⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 3D游戏场景的演示原码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//***********************************************************************//
//																		 //
//		- "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 + -