//Render a frame void RenderFrame(double currentTime, double timePassed) { //Clear buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); //reset modelview matrix glColor4f(1.0f, 1.0f, 1.0f, 1.0f); glTranslatef(0.0f, 0.0f,-5.0f); glRotatef((float)currentTime/10, 0.0f, 1.0f, 0.0f); //Create a simple rotating tetrahedron glBegin(GL_TRIANGLE_FAN); { glColor3f( 1.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 1.0f, 0.0f); glColor3f( 0.0f, 1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 1.0f); glColor3f( 0.0f, 0.0f, 1.0f); glVertex3f( 1.0f,-1.0f,-1.0f); glColor3f( 0.0f, 1.0f, 0.0f); glVertex3f( -1.0f,-1.0f,-1.0f); glColor3f( 0.0f, 0.0f, 1.0f); glVertex3f( -1.0f,-1.0f, 1.0f); glColor3f( 0.0f, 1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 1.0f); } glEnd(); fpsCounter.Update(); //Print text font.StartTextMode(); glColor4f(0.0f, 1.0f, 0.0f, 1.0f); font.Print(0, 28, "FPS: %.2f", fpsCounter.GetFps()); font.EndTextMode(); WINDOW::Instance()->SwapBuffers(); //Save a screenshot if(WINDOW::Instance()->IsKeyPressed(VK_F1)) { WINDOW::Instance()->SaveScreenshot(); WINDOW::Instance()->SetKeyReleased(VK_F1); } //Check for an openGL error WINDOW::Instance()->CheckGLError(); //quit if necessary if(WINDOW::Instance()->IsKeyPressed(VK_ESCAPE)) PostQuitMessage(0); }
//Render a frame void RenderFrame(double currentTime, double timePassed) { //Clear buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); //reset modelview matrix glColor4f(1.0f, 1.0f, 1.0f, 1.0f); gluLookAt( 0.0f, 1.8f, 1.8f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0); //Enable texture glBindTexture(GL_TEXTURE_2D, floorTexture); glEnable(GL_TEXTURE_2D); //Set up vertex arrays glVertexPointer(3, GL_FLOAT, sizeof(SIMPLE_VERTEX), &vertices[0].position); glEnableClientState(GL_VERTEX_ARRAY); glNormalPointer(GL_FLOAT, sizeof(SIMPLE_VERTEX), &vertices[0].normal); glEnableClientState(GL_NORMAL_ARRAY); glTexCoordPointer(2, GL_FLOAT, sizeof(SIMPLE_VERTEX), &vertices[0].texCoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); //Use Fixed Function Pipeline if(useFixedFunction) { //Set parameters for GL lighting glLightModelfv(GL_LIGHT_MODEL_AMBIENT, white*0.1f); //global ambient glMaterialfv(GL_FRONT, GL_AMBIENT, white); glMaterialfv(GL_FRONT, GL_DIFFUSE, white); glEnable(GL_LIGHTING); //8 passes, dealing with 8 lights at a time, except final pass where we do 4 for(int i=0; i<8; ++i) { int numLightsThisPass=8; if(i==7) numLightsThisPass=4; //Set up lights for(int j=0; j<numLightsThisPass; ++j) { glLightfv(GL_LIGHT0+j, GL_POSITION, VECTOR4D(lights[i*8+j].position)); glLightfv(GL_LIGHT0+j, GL_DIFFUSE, lights[i*8+j].color); glEnable(GL_LIGHT0+j); } //If this is the final pass, disable lights 4-7 if(i==7) for(int j=4; j<7; ++j) glDisable(GL_LIGHT0+j); //Enable additive blend for all passes except the first if(i!=0) { glBlendFunc(GL_ONE, GL_ONE); glEnable(GL_BLEND); //if this is not the first pass, no ambient glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black); } //Draw grid as triangle strips for(int j=0; j<gridDensity-1; ++j) glDrawElements( GL_TRIANGLE_STRIP, gridDensity*2, GL_UNSIGNED_INT, &indices[j*gridDensity*2]); } //Disable lights for(int j=0; j<7; ++j) glDisable(GL_LIGHT0+j); glDisable(GL_LIGHTING); glDisable(GL_BLEND); } //Use vp1 if(useVP1) { //Bind program glBindProgramNV(GL_VERTEX_PROGRAM_NV, vp1); glEnable(GL_VERTEX_PROGRAM_NV); //3 passes, dealing with 20 lights at a time for(int i=0; i<3; ++i) { //Send ambient brightness as c[4] //Only send this for the first pass if(i==0) glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 4, white*0.1f); else glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 4, black); //Update program parameters 5&6 for light0, 7&8 for light1, etc for(int j=0; j<20; ++j) { glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 2*j+5, VECTOR4D(lights[i*20+j].position)); glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 2*j+6, lights[i*20+j].color); } //Enable additive blend for passes except the first if(i>0) { glBlendFunc(GL_ONE, GL_ONE); glEnable(GL_BLEND); } //Draw grid as triangle strips for(int j=0; j<gridDensity-1; ++j) glDrawElements( GL_TRIANGLE_STRIP, gridDensity*2, GL_UNSIGNED_INT, &indices[j*gridDensity*2]); } glDisable(GL_VERTEX_PROGRAM_NV); glDisable(GL_BLEND); } //Use vp2 if(useVP2) { //Bind program glBindProgramNV(GL_VERTEX_PROGRAM_NV, vp2); glEnable(GL_VERTEX_PROGRAM_NV); //Send ambient brightness as c[4] glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 4, white*0.1f); //Update program parameters 5&6 for light0, 7&8 for light1, etc for(int j=0; j<60; ++j) { glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 2*j+5, VECTOR4D(lights[j].position)); glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 2*j+6, lights[j].color); } //Send loop parameters to c[125] glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 125, 60.0, //number of lights 5.0, //base offset of light data -1.0, 2.0);//num parameters between lights //Draw grid as triangle strips for(int j=0; j<gridDensity-1; ++j) glDrawElements( GL_TRIANGLE_STRIP, gridDensity*2, GL_UNSIGNED_INT, &indices[j*gridDensity*2]); glDisable(GL_VERTEX_PROGRAM_NV); } //reset states glDisable(GL_TEXTURE_2D); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); fpsCounter.Update(); //Print text font.StartTextMode(); glColor4f(0.0f, 1.0f, 0.0f, 1.0f); font.Print(0, 28, "FPS: %.2f", fpsCounter.GetFps()); glColor4f(1.0f, 0.0f, 0.0f, 0.0f); if(useVP1) font.Print(0, 48, "Using NV_vertex_program"); if(useVP2) font.Print(0, 48, "Using NV_vertex_program2"); if(useFixedFunction) font.Print(0, 48, "Using Fixed Function Pipeline"); font.EndTextMode(); WINDOW::Instance()->SwapBuffers(); //Save a screenshot if(WINDOW::Instance()->IsKeyPressed(VK_F1)) { WINDOW::Instance()->SaveScreenshot(); WINDOW::Instance()->SetKeyReleased(VK_F1); } //Check for an openGL error WINDOW::Instance()->CheckGLError(); //quit if necessary if(WINDOW::Instance()->IsKeyPressed(VK_ESCAPE)) PostQuitMessage(0); }