/* CPSC 360 Programming Assignment 7 * 3-D Model of My Room * by Chris Bolduc * boldu101@chapman.edu */ #include #include #include "keypress.h" #include "loadtga.h" // Misc constants #define GRID_SIZE 10 #ifndef pi #define pi 3.1415926535897932384626433832795 #endif // Prototypes void init(); void display(); void drawAxis(); void drawStairs(int numStairs); void drawDesk(); void drawComputer(); void drawMonitor(); void drawMonitorImage(); void drawKeyboard(); void drawBed(); void drawDoor(); void drawQuilt(); void drawBookshelf(); void drawBookshelfTexture(); void drawWalls(); void drawWindow(); void drawFan(); void rotate_fan(); void reshape(int w, int h); // Globals float fan_angle = 0.0; // Initialize the drawing area void init(){ glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_SMOOTH); //Set up the lighting GLfloat mat_off[] = { 0.0, 0.0, 0.0, 0.0 }; GLfloat mat_dark[] = { 0.1, 0.1, 0.1, 1.0 }; GLfloat mat_bright[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess[] = { 5.0 }; // Note: this only affects specular lights GLfloat mat_spot_direction[] = { 6.5, 3.0, 8.5 }; // Shine on the desk GLfloat mat_spot_cutoff[] = { 10.0 }; // 20 degrees total GLfloat light0_position[] = { 6.5, 8.0, 5.0, 0.0 }; // Middle of room, ceiling GLfloat light1_position[] = { 6.5, 0.0, 8.0, 0.0 }; // Under the desk // 4th value // == 0.0 -> light at infinite distnace // != 0.0 -> light is in the scene glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_bright); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_bright); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, mat_shininess); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_dark); glMaterialfv(GL_FRONT_AND_BACK, GL_SPOT_DIRECTION, mat_spot_direction); glMaterialfv(GL_FRONT_AND_BACK, GL_SPOT_CUTOFF, mat_spot_cutoff); glLightfv(GL_LIGHT0, GL_POSITION, light0_position); glLightfv(GL_LIGHT1, GL_POSITION, light1_position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_DEPTH_TEST); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT, GL_DIFFUSE); // Load textures into memory load_gl_tga("./img/carpet.tga", 0); load_gl_tga("./img/b2_rock.tga", 1); load_gl_tga("./img/closet.tga", 2); load_gl_tga("./img/bookshelf.tga", 3); load_gl_tga("./img/quilt.tga", 4); load_gl_tga("./img/officebk.tga", 5); load_gl_tga("./img/officert.tga", 6); load_gl_tga("./img/greenup.tga", 7); load_gl_tga("./img/comp_desk.tga", 8); load_gl_tga("./img/door.tga", 9); } // Handles user menu calls. void menuFunction(int itemNum){ switch(itemNum){ case 1: camera_x = 0.0; camera_y = 0.0; camera_z = 5.0; camera_theta = 0.0; camera_pitch = 0.0; break; } glutPostRedisplay(); } // Display the scene void display(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glEnable(GL_LIGHTING); // Camera offsets will be subtracted from current position // Remember that y is vertical and z is depth gluLookAt(camera_x, camera_y, camera_z, camera_x - (5.0 * sin(camera_theta)), camera_y - camera_pitch, camera_z - (5.0 * cos(camera_theta)), 0.0, 1.0, 0.0); // First draw all primitives glPushMatrix(); glColor3f(1.0, 0.0, 0.0); glTranslatef(8.0, 0.0, 0.0); drawBookshelf(); glPopMatrix(); glPushMatrix(); glColor3f(1.0, 1.0, 1.0); glTranslatef(6.5, 8.0, 5.0); drawFan(); glPopMatrix(); glPushMatrix(); glColor3f(0.0, 0.0, 1.0); glTranslatef(3.0, 0.0, 7.0); drawDesk(); glPopMatrix(); glPushMatrix(); glColor3f(0.0, 0.0, 0.0); glTranslatef(6.9, 0.0, 7.0); glScalef(2.0, 2.0, 2.0); drawComputer(); glPopMatrix(); glPushMatrix(); glColor3f(0.2, 0.2, 0.2); glTranslatef(4.5, 3.5, 9.0); glScalef(2.0, 2.0, 2.0); drawMonitor(); glPopMatrix(); glPushMatrix(); glColor3f(1.0, 1.0, 1.0); glTranslatef(4.5, 3.01, 7.1); drawKeyboard(); glPopMatrix(); glPushMatrix(); glColor3f(0.5, 0.25, 0.0); glScalef(7.0, 4.0, 5.0); drawBed(); glPopMatrix(); // Now draw textures glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glPushMatrix(); glScalef(13.0, 8.0, 10.0); glColor3f(1.0, 1.0, 1.0); drawWalls(); glPopMatrix(); drawWindow(); drawDoor(); glPushMatrix(); glTranslatef(8.0, 0.0, 0.0); drawBookshelfTexture(); glPopMatrix(); glPushMatrix(); glColor3f(0.2, 0.2, 0.2); glTranslatef(4.5, 3.5, 9.0); glScalef(2.0, 2.0, 2.0); drawMonitorImage(); glPopMatrix(); glPushMatrix(); glColor3f(0.5, 0.25, 0.0); glScalef(7.0, 4.0, 5.0); drawQuilt(); glPopMatrix(); glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_SMOOTH); glDisable(GL_LIGHTING); glFlush(); glutSwapBuffers(); glutPostRedisplay(); } // Draws the XYZ axis. Used when debugging. void drawAxis(){ glBegin(GL_LINES); // x is red glColor3f(1, 0, 0); glVertex3f(-100, 0, 0); glVertex3f(100, 0, 0); // y is green glColor3f(0, 1, 0); glVertex3f(0, -100, 0); glVertex3f(0, 100, 0); // z is blue glColor3f(0, 0, 1); glVertex3f(0, 0, -100); glVertex3f(0, 0, 100); glEnd(); } // Draws a basic stairway void drawStairs(int numStairs){ int i; float height = 0.0; float angle = 0.0; for(i = 0; i != numStairs; ++i){ glPushMatrix(); glRotatef(angle, 0.0, 1.0, 0.0); glTranslatef(3.0, height, 0.0); glScalef(1.0, 0.2, 1.0); glutSolidCube(1.0); glPopMatrix(); angle += 20.0; if(angle >= 360){ angle = 0.0; } height +=1.0; } } void drawDesk(){ glPushMatrix(); glTranslatef(0.1, 1.5, 1.5); glScalef(0.2, 3.0, 3.0); glutSolidCube(1.0); glPopMatrix(); glPushMatrix(); glTranslatef(4.9, 1.5, 1.5); glScalef(0.2, 3.0, 3.0); glutSolidCube(1.0); glPopMatrix(); glPushMatrix(); glTranslatef(2.5, 3.0, 1.5); glScalef(5.0, 0.2, 3.0); glutSolidCube(1.0); glPopMatrix(); } void drawComputer(){ glPushMatrix(); glTranslatef(0.25, 0.4, 0.5); glScalef(0.5, 1.0, 1.0); glutSolidCube(1.0); glPopMatrix(); } void drawMonitor(){ glPushMatrix(); glTranslatef(0.5, 0.5, 0.125); glScalef(1.0, 0.75, 0.25); glutSolidCube(1.0); glPopMatrix(); glPushMatrix(); glTranslatef(0.5, 0.0, 0.375); glScalef(0.25, 1.5, 0.25); glutSolidCube(1.0); glPopMatrix(); } void drawMonitorImage(){ glPushMatrix(); glBindTexture(GL_TEXTURE_2D, 8); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(0.9, 0.2, -0.01); glTexCoord2f(0.0, 1.0); glVertex3f(0.9, 0.8, -0.01); glTexCoord2f(1.0, 1.0); glVertex3f(0.1, 0.8, -0.01); glTexCoord2f(1.0, 0.0); glVertex3f(0.1, 0.2, -0.01); glEnd(); glPopMatrix(); } void drawKeyboard(){ glPushMatrix(); glTranslatef(1.0, 0.1, 0.25); glScalef(2.0, 0.2, 0.5); glutSolidCube(1.0); glPopMatrix(); } void drawBed(){ glPushMatrix(); glTranslatef(0.95, 0.25, 0.5); glScalef(0.1, 0.5, 1.0); glutSolidCube(1.0); glPopMatrix(); glPushMatrix(); glTranslatef(0.05, 0.5, 0.5); glScalef(0.1, 1.0, 1.0); glutSolidCube(1.0); glPopMatrix(); glPushMatrix(); glTranslatef(0.5, 0.25, 0.05); glScalef(1.0, 0.5, 0.1); glutSolidCube(1.0); glPopMatrix(); glPushMatrix(); glTranslatef(0.5, 0.25, 0.95); glScalef(1.0, 0.5, 0.1); glutSolidCube(1.0); glPopMatrix(); } void drawQuilt(){ glBindTexture(GL_TEXTURE_2D, 4); glPushMatrix(); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.51, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 0.51, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(1.0, 0.51, 1.0); glTexCoord2f(1.0, 0.0); glVertex3f(0.0, 0.51, 1.0); glEnd(); glPopMatrix(); } void drawBookshelf(){ glPushMatrix(); glTranslatef(1.5, 1.5, 0.5); glScalef(3.0, 3.0, 1.0); glutSolidCube(1.0); glPopMatrix(); } void drawBookshelfTexture(){ glPushMatrix(); glBindTexture(GL_TEXTURE_2D, 3); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 1.01); glTexCoord2f(0.0, 1.0); glVertex3f(0.0, 3.0, 1.01); glTexCoord2f(1.0, 1.0); glVertex3f(3.0, 3.0, 1.01); glTexCoord2f(1.0, 0.0); glVertex3f(3.0, 0.0, 1.01); glEnd(); glPopMatrix(); } void drawWalls(){ glPushMatrix(); // Floor glBindTexture(GL_TEXTURE_2D, 0); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(0.0, 0.0, 1.0); glTexCoord2f(1.0, 1.0); glVertex3f(1.0, 0.0, 1.0); glTexCoord2f(1.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glEnd(); // Ceiling glBindTexture(GL_TEXTURE_2D, 7); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 1.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(0.0, 1.0, 1.0); glTexCoord2f(1.0, 1.0); glVertex3f(1.0, 1.0, 1.0); glTexCoord2f(1.0, 0.0); glVertex3f(1.0, 1.0, 0.0); glEnd(); // Front Wall glBindTexture(GL_TEXTURE_2D, 1); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(0.0, 1.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(1.0, 1.0, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glEnd(); // Back wall glBindTexture(GL_TEXTURE_2D, 1); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 1.0); glTexCoord2f(0.0, 1.0); glVertex3f(0.0, 1.0, 1.0); glTexCoord2f(1.0, 1.0); glVertex3f(1.0, 1.0, 1.0); glTexCoord2f(1.0, 0.0); glVertex3f(1.0, 0.0, 1.0); glEnd(); // Left wall glBindTexture(GL_TEXTURE_2D, 1); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(0.0, 0.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(0.0, 1.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 1.0); glTexCoord2f(1.0, 0.0); glVertex3f(0.0, 0.0, 1.0); glEnd(); // Right wall glBindTexture(GL_TEXTURE_2D, 2); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(1.0, 0.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(1.0, 1.0, 1.0); glTexCoord2f(1.0, 0.0); glVertex3f(1.0, 0.0, 1.0); glEnd(); glPopMatrix(); } void drawDoor(){ glBindTexture(GL_TEXTURE_2D, 9); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(9.0, 0.01, 9.99); glTexCoord2f(0.0, 1.0); glVertex3f(9.0, 7.0, 9.99); glTexCoord2f(1.0, 1.0); glVertex3f(12.0, 7.0, 9.99); glTexCoord2f(1.0, 0.0); glVertex3f(12.0, 0.01, 9.99); glEnd(); } void drawWindow(){ glBindTexture(GL_TEXTURE_2D, 5); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(8.0, 4.0, 0.01); glTexCoord2f(0.0, 1.0); glVertex3f(8.0, 7.0, 0.01); glTexCoord2f(1.0, 1.0); glVertex3f(11.0, 7.0, 0.01); glTexCoord2f(1.0, 0.0); glVertex3f(11.0, 4.0, 0.01); glEnd(); glBindTexture(GL_TEXTURE_2D, 6); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(0.01, 4.0, 4.0); glTexCoord2f(0.0, 1.0); glVertex3f(0.01, 7.0, 4.0); glTexCoord2f(1.0, 1.0); glVertex3f(0.01, 7.0, 1.0); glTexCoord2f(1.0, 0.0); glVertex3f(0.01, 4.0, 1.0); glEnd(); } void drawFan(){ glutSolidSphere(1.0, 20, 20); glPushMatrix(); glRotatef(fan_angle, 0.0, 1.0, 0.0); glTranslatef(0.5, 0.0, 0.0); glScalef(4.0, 0.4, 1.0); glutSolidCube(1.0); glPopMatrix(); glPushMatrix(); glRotatef(fan_angle + 90.0, 0.0, 1.0, 0.0); glTranslatef(0.5, 0.0, 0.0); glScalef(4.0, 0.4, 1.0); glutSolidCube(1.0); glPopMatrix(); glPushMatrix(); glRotatef(fan_angle + 180.0, 0.0, 1.0, 0.0); glTranslatef(0.5, 0.0, 0.0); glScalef(4.0, 0.4, 1.0); glutSolidCube(1.0); glPopMatrix(); glPushMatrix(); glRotatef(fan_angle + 270.0, 0.0, 1.0, 0.0); glTranslatef(0.5, 0.0, 0.0); glScalef(4.0, 0.4, 1.0); glutSolidCube(1.0); glPopMatrix(); } void rotate_fan(){ fan_angle += 1.0; } // Adjusts viewing window when it is resized void reshape(int w, int h){ glViewport(0, 0, (GLsizei)w, (GLsizei)h); glDepthRange(0.0, 100.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 80.0); glMatrixMode(GL_MODELVIEW); } int main(int argc, char* argv[]){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow("CPSC360 Final Project"); init(); glutCreateMenu(menuFunction); glutAddMenuEntry("Reset view", 1); glutAttachMenu(GLUT_RIGHT_BUTTON); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keypress); glutIdleFunc(rotate_fan); glutMainLoop(); return 0; }