/* * scene.c * * This program demonstrates the use of the GL lighting model. * Objects are drawn using a grey material characteristic. * A single light source illuminates the objects. The program * is used to demonstrate the difference between single and * double buffering. * */ /* Z increases eyeZ, z decreases eyeZ * Y increases eyeY, y decreases eyeY * If the z coordinate becomes negative, the "near" and "far" are * changed to negative */ #include #include /* Initialize material property and light source. */ float spin = 0.0; double near = 0.1; double far = 120.0; double fovy = 40.0; double eyeX = 0.0; double eyeY= 0.0; double eyeZ = 5.0; void myinit(void) { // Light Properties GLfloat light_ambient[] = {0.0, 0.0, 0.0, 1.0}; GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0}; GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0}; GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; GLfloat mat_specular[] = {0.5, 0.5, 0.5, 1.0}; GLfloat mat_shininess[]= {30.0}; glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT0, GL_POSITION, light_position); // Material Properties glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); // Enable Various Components glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glColorMaterial(GL_FRONT,GL_DIFFUSE); } void spinDisplay() { spin += 2.0; if (spin > 360.0) spin -= 360.0; glutPostRedisplay(); } /* Draw various things using predefined GLUT objects */ void display(void) { glLoadIdentity(); gluPerspective( fovy, 1.0 , near, far); glMatrixMode(GL_MODELVIEW); // spin += 5.0; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(eyeX, eyeY, eyeZ, 0.0, 0.0, 0.0, 0.0, 1.0, 0.); printf("X=%f, Y=%f, Z=%f near=%f far=%f\n", eyeX, eyeY, eyeZ, near, far); glPushMatrix(); glRotatef(20.0, 1.0,0.0, 0.0); glRotatef(spin, 0.0, 1.0, 0.0); glPushMatrix(); // Green Torus glTranslatef(-0.6, 0.0, 0.0); glRotatef(90.0, 1.0, 0.0, 0.0); glColor3f(0.0, 0.5, 0.0); glutSolidTorus(0.275, 0.85, 10, 15); glPopMatrix(); glPushMatrix(); // Tall Yellow Box glTranslatef( 0.0, -0.5, -1.5); glRotatef(45.0, 0.0, 1.0, 0.0); glScalef(1.0, 6.0, 1.0); glColor3f(1.0, 1.0, 0.0); glutSolidCube(0.5); glPopMatrix(); glPushMatrix(); // Flat Blue Box glTranslatef( 0.0, -2.0, -1.5); glRotatef(45.0, 0.0, 1.0, 0.0); glScalef(1.0, 0.2, 1.0); glColor3f(0.4, 0.5, 1.0); glutSolidCube(2.0); glPopMatrix(); glPushMatrix(); // Red Ball glTranslatef(0.75, 0.0, -1.0); glColor3f(1.0, 0.0, 0.0); glutSolidSphere(0.8, 20, 10); glPopMatrix(); glPopMatrix(); glFlush(); glutSwapBuffers(); // glutPostRedisplay(); } void myReshape(int w, int h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective( fovy, (GLfloat) h / (GLfloat) w , near, far ); glMatrixMode(GL_MODELVIEW); } void mouse(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(spinDisplay); break; case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN) glutIdleFunc(NULL); break; default: break; } } void keyboard(unsigned char key, int x, int y) { switch (key) { case 'F': if (fovy < 85.0) fovy += 5.0; break; case 'f': if (fovy > 5.0) fovy -= 5.0; break; case 'N': if (near < (far-10.0)) near += 5.0; break; case 'n': if (near >= 10.1) near -= 5.0; break; case 'Z': eyeZ += 1.0; if (eyeZ > 0.0 && near < 0 && far < 0) { near *= -1.0; far *= -1.0; } break; case 'z': eyeZ -= 1.0; if (eyeZ < 0.0 && near > 0 && far >0) { near *= -1.0; far *= -1.0; } break; case 'Y': eyeY += 1.0; break; case 'y': eyeY-= 1.0; break; } glutPostRedisplay(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); glutInitWindowPosition(50, 50); glutInitWindowSize(500, 500); glutCreateWindow("3D Scene"); myinit(); glutKeyboardFunc(keyboard); glutMouseFunc(mouse); glutReshapeFunc(myReshape); glutDisplayFunc(display); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }