📄 main.cpp
字号:
//***********************************************************************//
// //
// - "Talk to me like I'm a 3 year old!" Programming Lessons - //
// //
// $Author: DigiBen digiben@gametutorials.com //
// //
// $Program: Octree2 //
// //
// $Description: Intergrates frustum culling with an octree //
// //
// $Date: 11/26/01 //
// //
//***********************************************************************//
// This is a compiler directive that includes libraries (For Visual Studio)
// You can manually include the libraries in the "Project->settings" menu under
// the "Link" tab.
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#include "main.h" // This includes our main header file
#include "camera.h" // This includes our camera header file
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
//
// By reading this tutorial we assume you have looked at the previous octree tutorial,
// as well as the frustum culling tutorial. If not we strongly recommend it.
//
// This is the second tutorial of the 3 part series on octrees. The last tutorial
// focused on creating the octree. This tutorial adds to the previous tutorial
// by adding the frustum culling.
//
// The controls are:
// Left Mouse Button - Changes the Render mode from normal to wire frame.
// Right Mouse Button - Turns lighting On/Off
// Left Arrow Key | A - Rotates the camera left
// Right Arrow Key | D - Rotates the camera right
// Up Arrow Key | W - Moves the camera along the view vector
// Down Arrow Key | S - Moves the camera opposite the view vector
// F5 - Increases the max triangle count by 20 for each node
// F6 - Decreases the max triangle count by 20 for each node
// + - Increases the max subdivision count
// - - Decreases the max subdivision count
// Escape - Quits
//
//
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
bool g_bFullScreen = TRUE; // Set full screen as default
HWND g_hWnd; // This is the handle for the window
RECT g_rRect; // This holds the window dimensions
HDC g_hDC; // General HDC - (handle to device context)
HGLRC g_hRC; // General OpenGL_DC - Our Rendering Context for OpenGL
HINSTANCE g_hInstance; // This holds the global hInstance for UnregisterClass() in DeInit()
// This is how fast our camera moves
#define SPEED 0.03f
// This is the file name that is to be loaded
#define FILE_NAME "Terrain.raw"
// Initialize a global camera object
CCamera g_Camera;
// Here we initialize our single Octree object. This will hold all of our vertices
COctree g_Octree;
// This will be our global frustum object that keeps track of our frustum
CFrustum g_Frustum;
// We created a debug class to show us the nodes visually in yellow cubes.
CDebug g_Debug;
// This will store an array of 3D points that we will read from a file.
CVector3 *g_pVertices = NULL;
// This will store the amount of vertices read in from the text file (.raw)
int g_NumberOfVerts = 0;
// The maximum amount of triangles per node. If a node has equal or less
// than this, stop subdividing and store the verts in that node
int g_MaxTriangles = 100;
// The maximum amount of subdivisions allowed (Levels of subdivision)
int g_MaxSubdivisions = 0;
// The current amount of end nodes in our tree (The nodes with vertices stored in them)
int g_EndNodeCount = 0;
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// This stores the amount of nodes that are in the frustum
int g_TotalNodesDrawn = 0;
/////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *
// Set the current render mode to triangles initially
bool g_bRenderMode = true;
// Turn lighting on initially
bool g_bLighting = true;
// This stores the variable that increases the rotation angle for our terrain (not important)
float g_RotateX = 0;
///////////////////////////////// LOAD VERTICES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function loads the vertices of our terrain from a text file (Terrain.raw)
/////
///////////////////////////////// LOAD VERTICES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
void LoadVertices()
{
// This function reads in the vertices from an ASCII text file (terrain.raw).
// First, we read in the vertices with a temp CVector3 to get the number of them.
// Next, we rewind the file pointer and then actually read in the vertices into
// our allocated CVector3 array g_pVertices[].
// Create a file pointer and load the model from a file of vertices
FILE *fp = fopen(FILE_NAME, "r");
// Make sure we opened the file correctly and it was found
if(!fp)
MessageBox(NULL, "Can't Open File", "Error", MB_OK);
// Create a temporary variable to hold what we read in from the file
CVector3 vTemp;
// Read in the number of vertices that are stored in the file
while(1)
{
// Read in a vertice and get the return value. If it's EOF we are done reading
int result = fscanf(fp, "%f %f %f\n", &vTemp.x, &vTemp.y, &vTemp.z);
// If we hit End Of File then we are done reading in the vertices, break
if(result == EOF)
break;
// Increase the vertice count
g_NumberOfVerts++;
}
// Allocate the needed memory to hold the vertices
g_pVertices = new CVector3 [ g_NumberOfVerts ];
// Go back to the beginning of the file so we can store the vertices now
rewind(fp);
// Create a counter for the index of the g_pVertices[] array
int index = 0;
// Read in the vertices that are stored in the file
for(int i = 0; i < g_NumberOfVerts; i++)
{
// Read in the current vertice and at the end add 1 to the index
fscanf(fp, "%f %f %f\n", &g_pVertices[ index ].x,
&g_pVertices[ index ].y,
&g_pVertices[ index ].z);
index++; // Increase our index for the vertex list
}
// Close our file because we are done
fclose(fp);
}
///////////////////////////////// INIT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function initializes the game window.
/////
///////////////////////////////// INIT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
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
}
///////////////////////////////// MAIN GAME LOOP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
///// This function Handles the main game loop
/////
///////////////////////////////// MAIN GAME LOOP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
WPARAM MainLoop()
{
MSG msg;
while(1) // Do our infinite loop
{ // Check if there was a message
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT) // If the message wasnt to quit
break;
TranslateMessage(&msg); // Find out what the message does
DispatchMessage(&msg); // Execute the message
}
else // if there wasn't a message
{
g_Camera.Update(); // Update the camera
RenderScene(); // Render the scene if every frame
}
}
// Here we free our vertice data that was loaded from our .raw file
delete [] g_pVertices;
DeInit(); // Clean up
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -