#include #include #include #include "geometry.h" using namespace std; // function prototypes void display(void); void reshape(int width, int height); void keyboard(unsigned char key, int x, int y); void motion(int x, int y); void init(void); // viewpoint double theta=0.5, phi=0, d=150; // window int width = 400; int height = 400; int main(int argc, char **argv) { // set up window glutInitWindowSize(400, 400); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("Viewpoint Demo"); // register callback functions glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMotionFunc(motion); // initalize opengl parameters init(); // loop until something happens glutMainLoop(); return 0; } void init() { // initialize viewing system glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, 1.0, 1.0, 1000.0); glMatrixMode(GL_MODELVIEW); // shading model glEnable(GL_SMOOTH); // initialize background color to black glClearColor(0.0,0.0,0.0,0.0); // enable depth buffering glEnable(GL_DEPTH_TEST); } void reshape(int newWidth, int newHeight) { width = newWidth; height = newHeight; // preserve aspect ratio if (width < height) glViewport(0,0,width,width); else glViewport(0,0,height,height); } void display() { // compute eye position glLoadIdentity(); Tuple eye(0,0,0); eye[0] = (float) -d * cos(theta) * sin(phi); eye[1] = (float) 2*d * sin(theta); eye[2] = (float) d * cos(theta) * cos(phi); // compute up vector Tuple up = Tuple(0,1,0)-eye/eye.length(); up.normalize(); gluLookAt(eye[0],eye[1],eye[2], 0,0,0,up[0], up[1], up[2]); glTranslatef(-50,0,-50); // clear buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // draw axes glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(100.0f, 0.0f, 0.0f); glEnd(); glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 100.0f, 0.0f); glEnd(); glBegin(GL_LINES); glVertex3f(0.0f, 0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 100.0f); glEnd(); // draw to screen glutSwapBuffers(); } void keyboard(unsigned char key, int mouseX, int mouseY) { switch (key) { case 'h': cout << "Use '-' and '+' to zoom in and out." << endl; break; case '-': if (d>1) d--; break; case '+': d++; break; } glutPostRedisplay(); } /* * This routine reads mouse movement and adjusts * camera position/orientation. */ void motion(int x, int y) { static int currX=-1; static int currY=-1; // wait until a mouse position is recorded and // avoid really big jumps if (currX>0 && abs(x-currX) < width/6 && abs(y-currY) < height/6) { phi += (double) (x-currX)/ (double) width * 3.14159; theta += (double) (y-currY)/ (double) height * 3.14159; // limit theta to -4pi/9 and 4pi/9 // it is disorienting to lose "up" if (theta < -4*3.14159/9.0) theta = -4*3.14159/9.0; if (theta > 4*3.14159/9.0) theta = 4*3.14159/9.0; } currX = x; currY = y; glutPostRedisplay(); }