/* For portability, include these lines at the beginning of each of your files. */ /* windows.h needed for Windows 2000/Visual Studio */ #ifdef WIN32 #include #endif /* MacOS uses frameworks/different paths */ #ifdef __APPLE__ #include #include #else #include #include #endif #include "math.h" #include "stdio.h" #include "stdlib.h" #define WINDOWSIZE 400 #define INITCAMX -20.0 #define INITCAMY 30.0 #define INITCAMZ 250.0 #define PITCHINC 1.0 #define ROLLINC 1.0 #define HEADINGINC 1.0 #define SPEEDINC .05 #define DELTAT .1 #define MAXPOLYGONS 100 int numpolygons = 0; #define COLORTABLESIZE 5 GLfloat colorTable[COLORTABLESIZE][3]; typedef struct { int numvertices; GLfloat vertices[16][5]; GLfloat* color; } PolygonStruct; PolygonStruct polygons[MAXPOLYGONS]; GLfloat camx, camy, camz, dirx, diry, dirz, speed, deltaposition, deltaspeed; GLfloat orientation[16]; int mousecontrol = 0; int mousex, mousey; int usedepthbuffer = 0; FILE* InFile; void initGLstuff(void) { glClearColor(1.0, 1.0, 1.0, 0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-.1,.1,-.1,.1,.2,1000); glMatrixMode(GL_MODELVIEW); glClear(GL_COLOR_BUFFER_BIT); colorTable[0][0] = 1.0; colorTable[0][1] = 0.0; colorTable[0][2] = 0.0; colorTable[1][0] = 0.0; colorTable[1][1] = 1.0; colorTable[1][2] = 0.0; colorTable[2][0] = 0.0; colorTable[2][1] = 0.0; colorTable[2][2] = 1.0; colorTable[3][0] = 1.0; colorTable[3][1] = 1.0; colorTable[3][2] = 0.0; colorTable[4][0] = 0.0; colorTable[4][1] = 1.0; colorTable[4][2] = 1.0; } void initcamerastate() { camx = INITCAMX; camy = INITCAMY; camz = INITCAMZ; speed = 0.0; glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glGetFloatv(GL_MODELVIEW_MATRIX,orientation); } /* perhaps useful for debugging, if you want to look at the orientation matrix */ void printmatrix(float* matrix) { int i,j; for (i = 0; i< 4; i++){ for (j=0;j<4;j++) fprintf(stderr, "%f ", matrix[4*j+i]); fprintf(stderr, "\n"); } } void updatepitch(float change) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glRotatef(-change, 1.0, 0.0, 0.0); glMultMatrixf(orientation); glGetFloatv(GL_MODELVIEW_MATRIX,orientation); glPopMatrix(); } void updateroll(float change) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glRotatef(-change, 0.0, 0.0, 1.0); glMultMatrixf(orientation); glGetFloatv(GL_MODELVIEW_MATRIX,orientation); glPopMatrix(); } void updateheading(float change) { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glRotatef(-change, 0.0, 1.0, 0.0); glMultMatrixf(orientation); glGetFloatv(GL_MODELVIEW_MATRIX,orientation); glPopMatrix(); } void display(void) { int i, j; if (usedepthbuffer) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); else glClear(GL_COLOR_BUFFER_BIT); /* set the view */ glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadMatrixf(orientation); glTranslatef(-camx, -camy, -camz); /* now do your drawing */ for (i = 0; i < numpolygons; i++) { glColor3fv(polygons[i].color); glBegin(GL_POLYGON); for (j = 0; j < polygons[i].numvertices; j++) { glVertex3f( polygons[i].vertices[j][0], polygons[i].vertices[j][1], polygons[i].vertices[j][2]); } glEnd(); } /* clean up */ glPopMatrix(); glutSwapBuffers(); /* seems needed in Windows 2000/Visual Studio */ glFlush(); } void idle(void) { if (mousecontrol) { if (mousex < (WINDOWSIZE/2 - 25)) updateheading(HEADINGINC/100); if (mousex > (WINDOWSIZE/2 + 25)) updateheading(-HEADINGINC/100); if (mousey < (WINDOWSIZE/2 - 25)) updatepitch(-PITCHINC/100); if (mousey > (WINDOWSIZE/2 + 25)) updatepitch(PITCHINC/100); } deltaposition = speed * DELTAT; dirx = orientation[2]; diry = orientation[6]; dirz = orientation[10]; camx = camx - dirx*deltaposition; camy = camy - diry*deltaposition; camz = camz - dirz*deltaposition; glutPostRedisplay(); } void motion(int x, int y) { y = WINDOWSIZE - y; mousex = x; mousey = y; } void mouse(int btn, int state, int x, int y) { y = WINDOWSIZE - y; if (state == GLUT_DOWN) { mousecontrol = 1; mousex = x; mousey = y; } else if (state == GLUT_UP) { mousecontrol = 0; } } void keybd(unsigned char key, int x, int y) { switch (key) { case '+': case'.': speed += SPEEDINC; break; case '-': case',': speed -= SPEEDINC; break; case '0': speed = 0.0; break; case 'r': initcamerastate(); break; case 'w': updatepitch(-PITCHINC); break; case 'z': updatepitch(PITCHINC); break; case 'a': updateheading(HEADINGINC); break; case 's': updateheading(-HEADINGINC); break; case 'e': updateroll(-ROLLINC); break; case 'q': updateroll(ROLLINC); break; case 'p': fprintf(stderr, "position %f %f %f direction %f %f %f\n", camx, camy, camz, dirx, diry, dirz); break; case 'h': if (usedepthbuffer == 1) { glDisable(GL_DEPTH_TEST); usedepthbuffer = 0; } else { usedepthbuffer = 1; glEnable(GL_DEPTH_TEST); } break; } } void reshape(int width, int height) { glViewport(0,0,width, height); } void PrintUsage () { fprintf(stderr, "USAGE: hw8viewing.exe scenefilename\n"); } void ReadScene(char* scenefile) { int i,j, numvertices; GLfloat x, y, z; fprintf(stderr, "reading scene file %s\n", scenefile); InFile = fopen(scenefile, "r"); if (InFile == NULL) { fprintf(stderr,"File not found: %s\n", scenefile); PrintUsage(); exit(-1); } fscanf(InFile, "%d", &numpolygons); for (i = 0; i