//Perform per-frame updates void UpdateFrame() { //set currentTime and timePassed static double lastTime=timer.GetTime(); double currentTime=timer.GetTime(); double timePassed=currentTime-lastTime; lastTime=currentTime; //Update window WINDOW::Instance()->Update(); //Update the lights for(int i=0; i<numLights; ++i) { lights[i].position+=lights[i].velocity*float(timePassed)/1000; //bounce off the borders if(lights[i].position.x>1.0f && lights[i].velocity.x>0.0f) lights[i].velocity.x=-lights[i].velocity.x; if(lights[i].position.x<-1.0f && lights[i].velocity.x<0.0f) lights[i].velocity.x=-lights[i].velocity.x; if(lights[i].position.z>1.0f && lights[i].velocity.z>0.0f) lights[i].velocity.z=-lights[i].velocity.z; if(lights[i].position.z<-1.0f && lights[i].velocity.z<0.0f) lights[i].velocity.z=-lights[i].velocity.z; } //Toggle vertex program/fixed function if(WINDOW::Instance()->IsKeyPressed('1') && GLEE_NV_vertex_program) { useVP1=true; useVP2=false; useFixedFunction=false; } if(WINDOW::Instance()->IsKeyPressed('2') && GLEE_NV_vertex_program2) { useVP1=false; useVP2=true; useFixedFunction=false; } if(WINDOW::Instance()->IsKeyPressed('3')) { useVP1=false; useVP2=false; useFixedFunction=true; } //Render frame RenderFrame(currentTime, timePassed); }
//Perform per-frame updates void UpdateFrame() { //set currentTime and timePassed static double lastTime=timer.GetTime(); double currentTime=timer.GetTime(); double timePassed=currentTime-lastTime; lastTime=currentTime; //Update window WINDOW::Instance()->Update(); //Render frame RenderFrame(currentTime, timePassed); }
//draw a frame void RenderFrame() { //Clear buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); //reset modelview matrix glEnable(GL_LIGHTING); glTranslatef(0.0f, 0.0f, -30.0f); glRotatef((float)timer.GetTime()/30, 1.0f, 0.0f, 1.0f); cubeGrid.DrawSurface(threshold); glDisable(GL_LIGHTING); fpsCounter.Update(); //update frames per second counter glColor4f(0.0f, 0.0f, 1.0f, 1.0f); window.StartTextMode(); window.Print(0, 28, "FPS: %.2f", fpsCounter.GetFps()); //print the fps glColor4f(1.0f, 1.0f, 0.0f, 1.0f); window.Print(0, 48, "Grid Size: %d", gridSize); window.Print(0, 68, "%d triangles drawn", cubeGrid.numFacesDrawn); window.EndTextMode(); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); if(window.isKeyPressed(VK_F1)) { window.SaveScreenshot(); window.SetKeyReleased(VK_F1); } window.SwapBuffers(); //swap buffers //check for any opengl errors window.CheckGLError(); //quit if necessary if(window.isKeyPressed(VK_ESCAPE)) PostQuitMessage(0); }
//Perform per frame updates void UpdateFrame(unsigned char key, int x, int y) { angle=(float)timer.GetTime()/25; objectLightDirection=worldLightDirection.GetRotatedY(-angle); objectViewDirection=worldViewDirection.GetRotatedY(-angle); //update vertex program registers //Light direction in c[4] glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 4, VECTOR4D(objectLightDirection.GetNormalized())); //view direction in c[5] glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 5, VECTOR4D(objectViewDirection.GetNormalized())); // //pause & unpause // if(window.isKeyPressed('P')) // timer.Pause(); // // if(window.isKeyPressed('U')) // timer.Unpause(); // // //change technique // if(window.isKeyPressed('1') && paths1And2Supported) // currentTechnique=SINGLE_PASS; // // if(window.isKeyPressed('2') && paths1And2Supported) // currentTechnique=TEXTURE_LOOKUP; // // if(window.isKeyPressed('3')) // currentTechnique=FALLBACK; // // //toggle bumpy // if(window.isKeyPressed('B')) // showBumps=true; // // if(window.isKeyPressed('F')) // showBumps=false; }
//draw a frame void RenderFrame() { //Draw to pbuffer pbuffer.MakeCurrent(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); //reset modelview matrix gluLookAt( 0.0f, 0.0f, 4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); //Draw scene if(drawTextured) { glBindTexture(GL_TEXTURE_2D, decalTexture); glEnable(GL_TEXTURE_2D); glPushMatrix(); glRotatef(timer.GetTime()/20, 0.0f, 1.0f, 0.0f); glutSolidTeapot(0.8f); glPopMatrix(); glDisable(GL_TEXTURE_2D); } else { glPushMatrix(); glRotatef(timer.GetTime()/20, 0.0f, 1.0f, 0.0f); glRotatef(55.0f, 1.0f, 0.0f, 0.0f); glutWireTorus(0.3f, 1.0f, 12, 24); glPopMatrix(); glPushMatrix(); glRotatef(timer.GetTime()/20, 0.0f, 1.0f, 0.0f); glRotatef(-55.0f, 1.0f, 0.0f, 0.0f); glutWireTorus(0.3f, 1.0f, 12, 24); glPopMatrix(); } //Draw to window window.MakeCurrent(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); camera.SetupViewMatrix(); glLoadMatrixf(camera.viewMatrix); glBindTexture(GL_TEXTURE_2D, pbufferTexture); //use the pbuffer as the texture wglBindTexImageARB(pbuffer.hBuffer, WGL_FRONT_LEFT_ARB); //Draw simple rectangle glBegin(GL_TRIANGLE_STRIP); { glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); } glEnd(); //release the pbuffer for further rendering wglReleaseTexImageARB(pbuffer.hBuffer, WGL_FRONT_LEFT_ARB); fpsCounter.Update(); //update frames per second counter glColor4f(1.0f, 1.0f, 0.0f, 1.0f); window.StartTextMode(); window.Print(0, 28, "FPS: %.2f", fpsCounter.GetFps()); //print the fps glColor4f(1.0f, 0.0f, 0.0f, 1.0f); window.Print(0, 48, "%dx Anisotropy", currentAnisotropy); glColor4f(0.0f, 1.0f, 0.0f, 1.0f); window.Print(0, 68, "%s", useMipmapFilter ? "LINEAR_MIPMAP_LINEAR filtering" : "LINEAR filtering"); window.EndTextMode(); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); if(window.isKeyPressed(VK_F1)) { window.SaveScreenshot(); window.SetKeyReleased(VK_F1); } window.SwapBuffers(); //swap buffers //check for any opengl errors window.CheckGLError(); //quit if necessary if(window.isKeyPressed(VK_ESCAPE)) PostQuitMessage(0); }
//Called to draw scene void Display(void) { //angle of spheres in scene. Calculate from time float angle=timer.GetTime()/10; //First pass - from light's point of view glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadMatrixf(lightProjectionMatrix); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(lightViewMatrix); //Use viewport the same size as the shadow map glViewport(0, 0, shadowMapSize, shadowMapSize); //Draw back faces into the shadow map glCullFace(GL_FRONT); //Disable color writes, and use flat shading for speed glShadeModel(GL_FLAT); glColorMask(0, 0, 0, 0); //Draw the scene DrawScene(angle); //Read the depth buffer into the shadow map texture glBindTexture(GL_TEXTURE_2D, shadowMapTexture); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, shadowMapSize, shadowMapSize); //restore states glCullFace(GL_BACK); glShadeModel(GL_SMOOTH); glColorMask(1, 1, 1, 1); //2nd pass - Draw from camera's point of view glClear(GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadMatrixf(cameraProjectionMatrix); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(cameraViewMatrix); glViewport(0, 0, windowWidth, windowHeight); //Use dim light to represent shadowed areas glLightfv(GL_LIGHT1, GL_POSITION, VECTOR4D(lightPosition)); glLightfv(GL_LIGHT1, GL_AMBIENT, white*0.2f); glLightfv(GL_LIGHT1, GL_DIFFUSE, white*0.2f); glLightfv(GL_LIGHT1, GL_SPECULAR, black); glEnable(GL_LIGHT1); glEnable(GL_LIGHTING); DrawScene(angle); //3rd pass //Draw with bright light glLightfv(GL_LIGHT1, GL_DIFFUSE, white); glLightfv(GL_LIGHT1, GL_SPECULAR, white); //Calculate texture matrix for projection //This matrix takes us from eye space to the light's clip space //It is postmultiplied by the inverse of the current view matrix when specifying texgen static MATRIX4X4 biasMatrix(0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f); //bias from [-1, 1] to [0, 1] MATRIX4X4 textureMatrix=biasMatrix*lightProjectionMatrix*lightViewMatrix; //MATRIX4X4 textureMatrix=lightProjectionMatrix*lightViewMatrix; //Set up texture coordinate generation. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGenfv(GL_S, GL_EYE_PLANE, textureMatrix.GetRow(0)); glEnable(GL_TEXTURE_GEN_S); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGenfv(GL_T, GL_EYE_PLANE, textureMatrix.GetRow(1)); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGenfv(GL_R, GL_EYE_PLANE, textureMatrix.GetRow(2)); glEnable(GL_TEXTURE_GEN_R); glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGenfv(GL_Q, GL_EYE_PLANE, textureMatrix.GetRow(3)); glEnable(GL_TEXTURE_GEN_Q); //Bind & enable shadow map texture glBindTexture(GL_TEXTURE_2D, shadowMapTexture); glEnable(GL_TEXTURE_2D); //Enable shadow comparison glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE); //Shadow comparison should be true (ie not in shadow) if r<=texture glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); //Shadow comparison should generate an INTENSITY result glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY); //Set alpha test to discard false comparisons glAlphaFunc(GL_GEQUAL, 0.99f); glEnable(GL_ALPHA_TEST); DrawScene(angle); //Disable textures and texgen glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); glDisable(GL_TEXTURE_GEN_Q); //Restore other states glDisable(GL_LIGHTING); glDisable(GL_ALPHA_TEST); //Update frames per second counter fpsCounter.Update(); //Print fps static char fpsString[32]; sprintf(fpsString, "%.2f", fpsCounter.GetFps()); //Set matrices for ortho glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluOrtho2D(-1.0f, 1.0f, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); //Print text glRasterPos2f(-1.0f, 0.9f); for(unsigned int i=0; i<strlen(fpsString); ++i) glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, fpsString[i]); //reset matrices glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glFinish(); glutSwapBuffers(); glutPostRedisplay(); }
//Perform per frame updates void UpdateFrame() { window.Update(); //update balls' position float c = 2.0f*(float)cos(timer.GetTime()/600); metaballs[0].position.x=-4.0f*(float)cos(timer.GetTime()/700) - c; metaballs[0].position.y=4.0f*(float)sin(timer.GetTime()/600) - c; metaballs[1].position.x=5.0f*(float)sin(timer.GetTime()/400) + c; metaballs[1].position.y=5.0f*(float)cos(timer.GetTime()/400) - c; metaballs[2].position.x=-5.0f*(float)cos(timer.GetTime()/400) - 0.2f*(float)sin(timer.GetTime()/600); metaballs[2].position.y=5.0f*(float)sin(timer.GetTime()/500) - 0.2f*(float)sin(timer.GetTime()/400); //increase or decrease density if(window.isKeyPressed(VK_UP) && gridSize<maxGridSize) { gridSize++; cubeGrid.Init(gridSize); } if(window.isKeyPressed(VK_DOWN) && gridSize>minGridSize) { gridSize--; cubeGrid.Init(gridSize); } //pause & unpause if(window.isKeyPressed('P')) { timer.Pause(); } if(window.isKeyPressed('U')) { timer.Unpause(); } //clear the field for(int i=0; i<cubeGrid.numVertices; i++) { cubeGrid.vertices[i].value=0.0f; cubeGrid.vertices[i].normal.LoadZero(); } //evaluate the scalar field at each point VECTOR3D ballToPoint; float squaredRadius; VECTOR3D ballPosition; float normalScale; for(int i=0; i<numMetaballs; i++) { squaredRadius=metaballs[i].squaredRadius; ballPosition=metaballs[i].position; //VC++6 standard does not inline functions //by inlining these maually, in this performance-critical area, //almost a 100% increase in speed is found for(int j=0; j<cubeGrid.numVertices; j++) { //ballToPoint=cubeGrid.vertices[j].position-ballPosition; ballToPoint.x=cubeGrid.vertices[j].position.x-ballPosition.x; ballToPoint.y=cubeGrid.vertices[j].position.y-ballPosition.y; ballToPoint.z=cubeGrid.vertices[j].position.z-ballPosition.z; //get squared distance from ball to point //float squaredDistance=ballToPoint.GetSquaredLength(); float squaredDistance= ballToPoint.x*ballToPoint.x + ballToPoint.y*ballToPoint.y + ballToPoint.z*ballToPoint.z; if(squaredDistance==0.0f) squaredDistance=0.0001f; //value = r^2/d^2 cubeGrid.vertices[j].value+=squaredRadius/squaredDistance; //normal = (r^2 * v)/d^4 normalScale=squaredRadius/(squaredDistance*squaredDistance); //cubeGrid.vertices[j].normal+=ballToPoint*normalScale; cubeGrid.vertices[j].normal.x+=ballToPoint.x*normalScale; cubeGrid.vertices[j].normal.y+=ballToPoint.y*normalScale; cubeGrid.vertices[j].normal.z+=ballToPoint.z*normalScale; } } //toggle wireframe if(window.isKeyPressed('W')) { glPolygonMode(GL_FRONT, GL_LINE); } if(window.isKeyPressed('F')) { glPolygonMode(GL_FRONT, GL_FILL); } //Change color if(window.isKeyPressed(VK_SPACE)) { currentDiffuseColor++; if(currentDiffuseColor==numDiffuseColors) currentDiffuseColor=0; glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuseColors[currentDiffuseColor]); window.SetKeyReleased(VK_SPACE); } }