📄 main.cpp
字号:
return(msg.wParam); // Return from the program
}
///////////////////////////////// RENDER SCENE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function renders the entire scene.
/////
///////////////////////////////// RENDER SCENE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void RenderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The matrix
// Give OpenGL our camera position
g_Camera.Look();
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// Each frame we calculate the new frustum. In reality you only need to
// calculate the frustum when we move the camera.
g_Frustum.CalculateFrustum();
// Initialize the total node count that is being draw per frame
g_TotalNodesDrawn = 0;
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// Here we draw the octree, starting with the root node and recursing down each node.
// When we get to each of the end nodes we will draw the vertices assigned to them.
g_Octree.DrawOctree(&g_Octree);
// Render the cube'd nodes to visualize the octree (in wire frame mode)
g_Debug.RenderDebugLines();
SwapBuffers(g_hDC); // Swap the backbuffers to the foreground
char strBuffer[255] = {0}; // Create a character buffer
// To view our octree information I set the window's title bar to the some basic
// information such as the max triangles per node, the max subdivisions,
// total end nodes and the total drawn end nodes that are currently in the frustum.
// Display in window mode the current subdivision information
sprintf(strBuffer, "MaxTriangles: %d MaxSubdivisions: %d TotalEndNodes: %d TotalNodesDraw: %d",
g_MaxTriangles, g_MaxSubdivisions, g_EndNodeCount, g_TotalNodesDrawn);
// Set our window title bar to the subdivision data
SetWindowText(g_hWnd, strBuffer);
}
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
///////////////////////////////// RECREATE OCTREE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function destroys the octree and debug lines then creates a new one
/////
///////////////////////////////// RECREATE OCTREE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
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());
}
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
///////////////////////////////// WIN PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function handles the window messages.
/////
///////////////////////////////// WIN PROC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LONG lRet = 0;
PAINTSTRUCT ps;
switch (uMsg)
{
case WM_SIZE: // If the window is resized
if(!g_bFullScreen) // Do this only if we are NOT in full screen
{
SizeOpenGLScreen(LOWORD(lParam),HIWORD(lParam));// LoWord=Width, HiWord=Height
GetClientRect(hWnd, &g_rRect); // Get the window rectangle
}
break;
case WM_PAINT: // If we need to repaint the scene
BeginPaint(hWnd, &ps); // Init the paint struct
EndPaint(hWnd, &ps); // EndPaint, Clean up
break;
case WM_LBUTTONDOWN: // If we hit the left mouse button
// Change the rendering mode to lines or triangles depending on it's current status
g_bRenderMode = !g_bRenderMode;
// Change the rendering mode to and from lines or triangles
if(g_bRenderMode)
{
// Render the triangles in fill mode
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
else
{
// Render the triangles in wire frame mode
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
break;
case WM_RBUTTONDOWN: // If the right mouse button was clicked.
g_bLighting = !g_bLighting; // Turn lighting ON/OFF
if(g_bLighting) { // If lighting is ON
glEnable(GL_LIGHTING); // Enable OpenGL lighting
} else {
glDisable(GL_LIGHTING); // Disable OpenGL lighting
}
break;
case WM_KEYDOWN: // If we hit a key
switch (wParam) // Check which key we hit
{
case VK_ESCAPE: // If we hit ESCAPE
PostQuitMessage(0); // Tell windows we want to quit
break;
case VK_ADD: // If we hit '+'
g_MaxSubdivisions += 1; // Increase the current max subdivisions
// Make sure we don't go over 10 subdivisions, otherwise it will get crazy
if(g_MaxSubdivisions > 10) g_MaxSubdivisions = 10;
// Destroy the octree and debug lines and create a new one with the new info
RecreateOctree();
break;
case VK_SUBTRACT: // If we hit '-'
g_MaxSubdivisions -= 1; // Decrease the current max subdivisions
// Make sure we don't go below zero subdivisions
if(g_MaxSubdivisions < 0) g_MaxSubdivisions = 0;
// Destroy the octree and debug lines and create a new one with the new info
RecreateOctree();
break;
case VK_F5: // If we hit F5
g_MaxTriangles += 20; // Increase the max triangle count by 20
// Make sure we don't go above 2000
if(g_MaxTriangles > 2000) g_MaxTriangles = 2000;
// Destroy the octree and debug lines and create a new one with the new info
RecreateOctree();
break;
case VK_F6: // If we hit F6
g_MaxTriangles -= 20; // Decrease the max triangle count by 20
// Make sure we don't go below 0 (0 would produce as many nodes as triangles)
if(g_MaxTriangles < 0) g_MaxTriangles = 0;
// Destroy the octree and debug lines and create a new one with the new info
RecreateOctree();
break;
}
break;
case WM_CLOSE: // If the window is closed
PostQuitMessage(0); // Tell windows we want to quit
break;
default: // Return by default
lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
break;
}
return lRet; // Return by default
}
/////////////////////////////////////////////////////////////////////////////////
//
// * QUICK NOTES *
//
// This tutorial was an add on to the last octree tutorial which just showed us
// how to create an octree. There wasn't a lot added, but the power that is provides
// is incredible. We now have a functional octree that only draws the vertices in
// our view. There are 2 things we added to this tutorial since the last:
//
// 1) We added the frustum code (frustum.cpp and frustum.h). This is all explained
// in our frustum tutorial on our site if you don't understand the code. Once we
// create our global CFrustum object: g_Frustum, we just need to call this every frame:
//
// g_Frustum.CalculateFrustum();
//
// We only really need to call it when the camera moves but you can do those checks
// yourself. Then, once the frustum planes are calculated we can use this function to
// check if the end nodes are in our frustum:
//
// g_Frustum.CubeInFrustum(center.x, center.y, center.z, cubeWidth / 2);
//
// That's it for the frustum! Simple, yet wonderfully usefull. We left in the sphere
// and point code in frustum.cpp from the frustum tutorial just so if you wanted to
// include the frustum.cpp file in your application/game you didn't have to copy and
// paste them back in. Just ingore those for this tutorial though.
//
// 2) Finally we added a counter (g_TotalNodesDrawn) to tell us how many of the end
// nodes are being drawn. This let's us know how well the octree is working. You
// can view this information in the window's title bar, along with the other subdivision
// information.
//
// Also notice that we took our the rotating. This is so all the cubes stay axis aligned.
//
// Hopefully by breaking the octree tutorial up into multiple parts it isn't so hard
// to digest. The next tutorial will focus on reading in a real world with texture
// information, normals, etc... Then you can actually use this code in a project.
// I also included the HTML octree tutorial with this tutorial as well just in case
// some people didn't want to download the first octree tutorial but wanted to get right
// to the good stuff. This HTML file will explain in more detail the octree theory, etc...
//
// Good luck!
//
//
// Ben Humphrey
// Game Programmer
// DigiBen@GameTutorials.com
// www.GameTutorials.com
//
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -