void PxIntroSceneRenderer::Enter() { glClearColor(0.0f ,0.0f ,0.0f ,0.0f); CreateBlurTexture(); CreateDisplayList(); screenWidth = float(PxWindow::Window()->ScreenWidth); screenHeight = float(PxWindow::Window()->ScreenHeight); glViewport(0, 0, PxWindow::Window()->ScreenWidth, PxWindow::Window()->ScreenHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0, screenWidth / screenHeight, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); PxAudioManager::Loop( "INTRO" ); }
void COctree::CreateDisplayList(COctree *pNode, t3DModel *pRootWorld, int displayListOffset) { // This function handles our rendering code in the beginning and assigns it all // to a display list. This increases our rendering speed, as long as we don't flood // the pipeline with a TON of data. Display lists can actually be to bloated or too small. // Like our DrawOctree() function, we need to find the end nodes by recursing down to them. // We only create a display list for the end nodes and ignore the rest. The // displayListOffset is used to add to the end nodes current display list ID, in case // we created some display lists before creating the octree. Usually it is just 1 otherwise. // Make sure a valid node was passed in, otherwise go back to the last node if(!pNode) return; // Check if this node is subdivided. If so, then we need to recurse down to it's nodes if(pNode->IsSubDivided()) { // Recurse down to each one of the children until we reach the end nodes CreateDisplayList(pNode->m_pOctreeNodes[TOP_LEFT_FRONT], pRootWorld, displayListOffset); CreateDisplayList(pNode->m_pOctreeNodes[TOP_LEFT_BACK], pRootWorld, displayListOffset); CreateDisplayList(pNode->m_pOctreeNodes[TOP_RIGHT_BACK], pRootWorld, displayListOffset); CreateDisplayList(pNode->m_pOctreeNodes[TOP_RIGHT_FRONT], pRootWorld, displayListOffset); CreateDisplayList(pNode->m_pOctreeNodes[BOTTOM_LEFT_FRONT], pRootWorld, displayListOffset); CreateDisplayList(pNode->m_pOctreeNodes[BOTTOM_LEFT_BACK], pRootWorld, displayListOffset); CreateDisplayList(pNode->m_pOctreeNodes[BOTTOM_RIGHT_BACK], pRootWorld, displayListOffset); CreateDisplayList(pNode->m_pOctreeNodes[BOTTOM_RIGHT_FRONT],pRootWorld, displayListOffset); } else { // Make sure we have valid data assigned to this node if(!pNode->m_pWorld) return; // Add our display list offset to our current display list ID pNode->m_DisplayListID += displayListOffset; // Start the display list and assign it to the end nodes ID glNewList(pNode->m_DisplayListID,GL_COMPILE); // Create a temp counter for our while loop below to store the objects drawn int counter = 0; // Store the object count and material count in some local variables for optimization int objectCount = pNode->m_pObjectList.size(); int materialCount = pRootWorld->pMaterials.size(); // Go through all of the objects that are in our end node while(counter < objectCount) { // Get the first object index into our root world int i = pNode->m_pObjectList[counter]; // Store pointers to the current face list and the root object // that holds all the data (verts, texture coordinates, normals, etc..) t3DObject *pObject = &pNode->m_pWorld->pObject[i]; t3DObject *pRootObject = &pRootWorld->pObject[i]; // Check to see if this object has a texture map, if so, bind the texture to it. if(pRootObject->bHasTexture) { // Turn on texture mapping and turn off color glEnable(GL_TEXTURE_2D); // Reset the color to normal again glColor3ub(255, 255, 255); // Bind the texture map to the object by it's materialID glBindTexture(GL_TEXTURE_2D, g_Texture[pRootObject->materialID]); } else { // Turn off texture mapping and turn on color glDisable(GL_TEXTURE_2D); // Reset the color to normal again glColor3ub(255, 255, 255); } // Check to see if there is a valid material assigned to this object if(materialCount && pRootObject->materialID >= 0) { // Get and set the color that the object is, since it must not have a texture BYTE *pColor = pRootWorld->pMaterials[pRootObject->materialID].color; // Assign the current color to this model glColor3ub(pColor[0], pColor[1], pColor[2]); } // Now we get to the more unknown stuff, vertex arrays. If you haven't // dealt with vertex arrays yet, let me give you a brief run down on them. // Instead of doing loops to go through and pass in each of the vertices // of a model, we can just pass in the array vertices, then an array of // indices that MUST be an unsigned int, which gives the indices into // the vertex array. That means that we can send the vertices to the video // card with one call to glDrawElements(). There are a bunch of other // functions for vertex arrays that do different things, but I am just going // to mention this one. Since texture coordinates, normals and colors are also // associated with vertices, we are able to point OpenGL to these arrays before // we draw the geometry. It uses the same indices that we pass to glDrawElements() // for each of these arrays. Below, we point OpenGL to our texture coordinates, // vertex and normal arrays. This is done with calls to glTexCoordPointer(), // glVertexPointer() and glNormalPointer(). // // Before using any of these functions, we need to enable their states. This is // done with glEnableClientState(). You just pass in the ID of the type of array // you are wanting OpenGL to look for. If you don't have data in those arrays, // the program will most likely crash. // // If you don't want to use vertex arrays, you can just render the world like normal. // That is why I saved the pFace information, as well as the pIndices info. This // way you can use what ever method you are comfortable with. I tried both, and // by FAR the vertex arrays are incredibly faster. You decide :) // Make sure we have texture coordinates to render if(pRootObject->pTexVerts) { // Turn on the texture coordinate state glEnableClientState(GL_TEXTURE_COORD_ARRAY); // Point OpenGL to our texture coordinate array. // We have them in a pair of 2, of type float and 0 bytes of stride between them. glTexCoordPointer(2, GL_FLOAT, 0, pRootObject->pTexVerts); } // Make sure we have vertices to render if(pRootObject->pVerts) { // Turn on the vertex array state glEnableClientState(GL_VERTEX_ARRAY); // Point OpenGL to our vertex array. We have our vertices stored in // 3 floats, with 0 stride between them in bytes. glVertexPointer(3, GL_FLOAT, 0, pRootObject->pVerts); } // Make sure we have normals to render if(pRootObject->pNormals) { // Turn on the normals state glEnableClientState(GL_NORMAL_ARRAY); // Point OpenGL to our normals array. We have our normals // stored as floats, with a stride of 0 between. glNormalPointer(GL_FLOAT, 0, pRootObject->pNormals); } // Here we pass in the indices that need to be rendered. We want to // render them in triangles, with numOfFaces * 3 for indice count, // and the indices are of type UINT (important). glDrawElements(GL_TRIANGLES, pObject->numOfFaces * 3, GL_UNSIGNED_INT, pObject->pIndices); // Increase the current object count rendered counter++; } // End the display list for this ID glEndList(); } }
CRenderFrm::CRenderFrm() { m_ToolBox = EngineGetToolBox(); CreateDisplayList(); }