void Init(HWND hWnd) { g_hWnd = hWnd; // Assign the window handle to a global window handle GetClientRect(g_hWnd, &g_rRect); // Assign the windows rectangle to a global RECT InitializeOpenGL(g_rRect.right, g_rRect.bottom); // Init OpenGL with the global rect // Position our camera g_Camera.PositionCamera(0, 30, 120, 0, 0, 0, 0, 1, 0); // This loads the vertices for the terrain LoadVertices(); // Calculate the bounding box of our scene. This will give us a width of // the cube that is needed to surround the whole world. We want to pass in // the vertices and the vertex count into this function to find the farthest point // from the center of the world. That will then be our width. Depending on the // world this doesn't always surround it perfectly. In the next tutorial we will fix that. g_Octree.GetSceneDimensions(g_pVertices, g_NumberOfVerts); // Here we pass in the information to create the root node. This will then // recursively subdivide the root node into the rest of the node. g_Octree.CreateNode(g_pVertices, g_NumberOfVerts, g_Octree.GetCenter(), g_Octree.GetWidth()); // Here, we turn on a light and enable lighting. We don't need to // set anything else for lighting because we will just take the defaults. // We also want color, so we turn that on too. We don't load any normals from // our .raw file so we will calculate some simple face normals to get a decent // perspective of the terrain. glEnable(GL_LIGHT0); // Turn on a light with defaults set glEnable(GL_LIGHTING); // Turn on lighting glEnable(GL_COLOR_MATERIAL); // Allow color }
void RecreateOctree() { // You will not need this function for the octree. It is just for the tutorial // every time we change our subdivision information. g_EndNodeCount = 0; // Reset the end node count g_Debug.Clear(); // Clear the list of debug lines g_Octree.DestroyOctree(); // Destroy the octree and start again // Get the new scene dimensions since we destroyed the previous octree g_Octree.GetSceneDimensions(g_pVertices, g_NumberOfVerts); // Create our new octree with the new subdivision information g_Octree.CreateNode(g_pVertices, g_NumberOfVerts, g_Octree.GetCenter(), g_Octree.GetWidth()); }
void Init(HWND hWnd) { g_hWnd = hWnd; // Assign the window handle to a global window handle GetClientRect(g_hWnd, &g_rRect); // Assign the windows rectangle to a global RECT InitializeOpenGL(g_rRect.right, g_rRect.bottom); // Init OpenGL with the global rect /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// * // Initialize the camera position g_Camera.PositionCamera(0, 3.5f, 30, 0, 0, 0, 0, 1, 0); // Here we load the world from a .3ds file g_Load3DS.Import3DS(&g_World, FILE_NAME); // Go through all the materials for(int i = 0; i < g_World.numOfMaterials; i++) { // Check to see if there is a file name to load in this material if(strlen(g_World.pMaterials[i].strFile) > 0) { // Use the name of the texture file to load the bitmap, with a texture ID (i). // We pass in our global texture array, the name of the texture, and an ID to reference it. CreateTexture(g_Texture[i], g_World.pMaterials[i].strFile); } // Set the texture ID for this material g_World.pMaterials[i].texureId = i; } // The first thing that needs to happen before creating our octree is to find // the total width of the initial root node. Now we pass in our t3DModel object // to GetSceneDimensions(), instead of vertices and a vertex count, as done // in the last octree tutorials. This will store the initial root node cube width. g_Octree.GetSceneDimensions(&g_World); // Since our model structures stores multiple objects, we can't easily access the // total triangle count in the scene with out manually going through and counting the total. // This is what we do below. With the result, we pass this into our CreateNode() function. int TotalTriangleCount = g_Octree.GetSceneTriangleCount(&g_World); // To create the first node we need the world data, the total triangle count in the scene, // along with the initial root node center and width. This function will then recursively // subdivide the rest of the world, according to the global restrictions. g_Octree.CreateNode(&g_World, TotalTriangleCount, g_Octree.GetCenter(), g_Octree.GetWidth()); // The octree should be created by now. To better increase our efficiency we use display // lists for every end node. This way, we just have to call a display list ID to draw // a node, verses the slow loops we normal had. Vertex arrays are also used to optimize // our rendering of the octree. // Below we get the display list base ID and store it in the root node. This should return 1 // since we don't use display lists anywhere before this. Notice that we use our global // variable that stores our end node count to pass in the total amount of list ID's needed. // If you are unfamiliar with displays, basically what you do is section off a certain // amount of ID's, and then you are returns a base pointer to the start of those ID's. // You can use the ID's from the base pointer to the base pointer ID + the number of // ID's that were saved off for that base pointer. Each of the ID's correspond to a // bunch of OpenGL commands. That means that each end node has it's own ID that // corresponds to a bunch of OpenGL commands. So, for instance, if pass in a bunch // of vertices to OpenGL, we can assign this action to a display list. That way we // just call a display list ID to perform that action. Think of it as a function. // You just need to call a function to do a bunch of tasks, which eliminates extra // code, and also is saved on the video card for faster processing. g_Octree.SetDisplayListID( glGenLists(g_EndNodeCount) ); // Now we go through every single end node and create a display list for them all. // That way, when we draw the end node, we just use it's display list ID to render // the node, instead of looping through all the objects and manually give the verts to opengl. // The parameters for this function is the node (starting with the root node), // the world data and current display list base ID. The base ID is stored in the root // node's ID, so we just pass that in. The reason we do this is because, if you create // other display lists before you create the octree, you don't want to assume the octree // ID's go from 1 to the end node count. By passing in the base ID, we then will add // this ID to other nodes. Right now, when they are created they are assigned the // end node count at the time upon creating them. This will make more sense when looking // at the octree code. g_Octree.CreateDisplayList(&g_Octree, &g_World, g_Octree.GetDisplayListID()); // Hide our cursor since we are using first person camera mode ShowCursor(FALSE); /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// * glEnable(GL_LIGHT0); // Turn on a light with defaults set glEnable(GL_LIGHTING); // Turn on lighting glEnable(GL_COLOR_MATERIAL); // Allow color }