/* * Lab exercise 1.0 * CSc 474, Computer Graphics * Copyright 2005 Chris Buckalew * * This lab implements simple linear translation for a sphere along the * x-axis. I want you to: * * 1) make the sphere rotate (instead of translate) about the y axis at a * radius of 10 units (the cone marks the y axis). * * 2) make the rotation fast. * * 3) now add a translation element to move the rotating sphere 20 units up as * as it rotates (you may need to increase the number of frames). * Now the sphere should describe a screw-thread motion as it goes from * bottom to top. * * 4) a damping element that decreases the radius as the sphere moves * upward. *Don't* use spiral motion for this; use the exp() * function. * * 5) change the damping motion so that it damps very quickly. * * * Here is the (cumbersome) procedure to compile and run this * program under Visual Studio: * * 1. Open VisStudio and create a new project. Make sure it's a * Win32 console project and that it's empty (one of the options) * * 2. You'll need to name it something, say Lab1. * * 3. Make a New Item, Source Code and copy into it the contents of * this file. * * 4. Under Tools, go to the Options, Projects and Solutions, * VC++ Directories and * select Include Files. Create a new listing and browse to * My Computer, glut-3.7\include and select it. * * 5. Now you should be able to compile without an include error. Try it. * * 6. But you did get a link error. To fix it, copy the file * C:\glut-3.7\bin\glut32.lib into the 2nd level lab1 directory (not * the parent lab1 directory). * * 7. Now you should be able to compile without errors. But it won't run! * To fix this, copy C:\glut-3.7\bin\glut32.dll into the highest level * lab1\Debug directory (there's also a Debug directory at * lab1\lab1\Debug - don't put it there). * * 8. Now you should be able to compile and run. Whew! * */ #include #include #include #include #include #include // some function prototypes void display(void); void normalize(float[3]); void normCrossProd(float[3], float[3], float[3]); // initial viewer position static GLdouble viewer[] = {0.0, 0.0, 5.0}; // initial viewer angle static GLfloat theta[] = {0.0, 0.0, 0.0}; // animation variables static int frame = 0; static int startFrame = 0; static int endFrame = 100; static int increment = 1; // animation transform variables static GLdouble translate[3] = {-10.0, 0.0, 0.0}; //--------------------------------------------------------- // Set up the view void setUpView() { // this code initializes the viewing transform glLoadIdentity(); // moves viewer along coordinate axes gluLookAt(viewer[0], viewer[1], viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); // move the view back some relative to viewer[] position glTranslatef(0.0f,0.0f, -8.0f); // rotates view glRotatef(theta[0], 1.0, 0.0, 0.0); glRotatef(theta[1], 0.0, 1.0, 0.0); glRotatef(theta[2], 0.0, 0.0, 1.0); return; } //---------------------------------------------------------- // Set up the light void setUpLight() { // set up the light sources for the scene // a directional light source from over the right shoulder GLfloat lightDir[] = {1.0, 1.0, 5.0, 0.0}; GLfloat diffuseComp[] = {1.0, 1.0, 1.0, 1.0}; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_POSITION, lightDir); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseComp); return; } //-------------------------------------------------------- // Set up the objects void drawSphere() { // draw an object // save the transformation state glPushMatrix(); // set the material GLfloat diffuseColor[] = {0.0, 1.0, 1.0, 1.0}; glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor); // locate it in the scene glMatrixMode(GL_MODELVIEW); // this translation will be used to animate the sphere glTranslatef(translate[0], translate[1], translate[2]); glRotatef(90, 1.0, 0.0, 0.0); // draw the sphere - the parameters are radius, number of // radial slices (longitude lines) and number of vertical // slices (latitude lines) glutSolidSphere(1.0, 7, 7); // recover the transform state glPopMatrix(); return; } void drawCone() { // save the transformation state glPushMatrix(); // set the material GLfloat diffuseColor[] = {0.8, 0.8, 0.8, 1.0}; glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor); // locate it in the scene glMatrixMode(GL_MODELVIEW); // this translation will be used to animate the sphere glTranslatef(0, 0, 0); glRotatef(-90, 1.0, 0.0, 0.0); // draw the cone - the parameters are radius, height, number of // radial slices and number of vertical slices glutSolidCone(0.2, 10.0, 7, 7); // recover the transform state glPopMatrix(); return; } //----------------------------------------------------------- // Callback functions void reshapeCallback(int w, int h) { // from Angel, p.562 glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w < h) { glFrustum(-2.0, 2.0, -2.0*(GLfloat) h / (GLfloat) w, 2.0*(GLfloat) h / (GLfloat) w, 0.2, 200.0); } else { glFrustum(-2.0, 2.0, -2.0*(GLfloat) w / (GLfloat) h, 2.0*(GLfloat) w / (GLfloat) h, 0.2, 200.0); } glMatrixMode(GL_MODELVIEW); } void timeStep(int step) { // animation code goes here // This function is called for each frame of animation double t = (double) (frame - startFrame) / (endFrame - startFrame); //this implements linear interpolation on the translation translate[0] = -10.0 + t * (10.0 - (-10.0)); translate[1] = 0.0f; translate[2] = 0.0f; if (frame == endFrame) increment = -1; else if (frame == startFrame) increment = 1; frame = frame + increment; display(); glutTimerFunc(50,timeStep, 0); } //--------------------------------------------------------- // Main routines void display (void) { // this code executes whenever the window is redrawn (when opened, // moved, resized, etc. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // set the viewing transform setUpView(); // set up light source setUpLight(); // start drawing objects drawSphere(); drawCone(); glutSwapBuffers(); } // create a double buffered 500x500 pixel color window int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(500, 500); glutInitWindowPosition(100, 100); glutCreateWindow("Procedural Animation: Lab 1"); glEnable(GL_DEPTH_TEST); glutDisplayFunc(display); glutReshapeFunc(reshapeCallback); glutTimerFunc(50,timeStep, 0); // 50 millisecond callback glutMainLoop(); return 0; } //--------------------------------------------------------- // Utility functions void normalize(float v[3]) { // normalize v[] and return the result in v[] // from OpenGL Programming Guide, p. 58 GLfloat d = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); if (d == 0.0) { printf("zero length vector"); return; } v[0] = v[0]/d; v[1] = v[1]/d; v[2] = v[2]/d; } void normCrossProd(float v1[3], float v2[3], float out[3]) { // cross v1[] and v2[] and return the result in out[] // from OpenGL Programming Guide, p. 58 out[0] = v1[1]*v2[2] - v1[2]*v2[1]; out[1] = v1[2]*v2[0] - v1[0]*v2[2]; out[2] = v1[0]*v2[1] - v1[1]*v2[0]; normalize(out); }