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

📄 glexplorer.cpp

📁 c++程序
💻 CPP
字号:
// glExplorer.cpp : Definiert den Einsprungpunkt f黵 die Anwendung.
//

#include "stdafx.h"
#include "SkyBox.h"
#include "Motion.h"
#include "Landscape.h"
#include "TreeCollection.h"
#include "Model.h"
#include "Crosshair.h"
#include "Settings.h"
#include "FrameCounter.h"
#include "CGL.h"
#include "Input.h"
#include "Weapon.h"
#include "Flashlight.h"
#include "Sunlight.h"
#include "mmsystem.h"
#include "Dlg.h"

// Needed classes
CSkyBox				cSkyBox;
CMotion				cMotion;
CLandscape			cLandscape;
CTreeCollection		cTreeCollection;
CCrosshair			cCrosshair;
CSettings			cSettings;
CFrameCounter		cFrameCounter;
CGL					cGL;
CInput				cInput;
CWeapon				cWeapon;
CFlashlight			cFlashlight;
CSunlight			cSunlight;
CDlg				cDlg;

GLvoid InitEngine()
{
	// Init multimedia timer and set it to maximum precision
	TIMECAPS Caps;
	timeGetDevCaps(&Caps, sizeof(Caps));
	if (timeBeginPeriod(Caps.wPeriodMin) == TIMERR_NOCANDO)
		MessageBox(NULL, "Error during timer initialisation !", "Error", MB_ICONERROR);

	// Load skybox textures
	cSkyBox.m_SkyBoxTexture.LoadBMP(cSettings.m_SkyBoxTexture);

	// Register landscape textures
	cLandscape.RegisterTexture("gfx/Textures/Landscape5.bmp");
						
	// Register tree textures
	cTreeCollection.RegisterTexture("gfx/Trees/Tree1.bmp");
	cTreeCollection.RegisterTexture("gfx/Trees/Tree2.bmp");
	cTreeCollection.RegisterTexture("gfx/Trees/Tree3.bmp");
	cTreeCollection.RegisterTexture("gfx/Trees/Tree4.bmp");
	cTreeCollection.RegisterTexture("gfx/Trees/Tree5.bmp");

	// Load heightmap and generate a landscape with it
	cLandscape.SetHeightScaling(cSettings.m_LandscapeHeightScaling);
	cLandscape.SetStepSize(cSettings.m_LandscapeStepSize);
	cLandscape.GenerateLandscape(cSettings.m_HeightmapFilename, cSettings.m_WorldSizeX,
		cSettings.m_WorldSizeY);

	// Link landscape with the camera
	cMotion.SetLandscape(&cLandscape);

	// Load motion settings
	cMotion.SetGravity(cSettings.m_Gravity);
	cMotion.SetSpeed(cSettings.m_Speed);
	cMotion.SetSlowDown(cSettings.m_SlowDown);
	cMotion.SetMidAirSlowDown(cSettings.m_MidAirSlowDown);
	cMotion.SetSmallestForce(cSettings.m_SmallestForce);
	cMotion.SetAccelerationTime(cSettings.m_AccelerationTime);
	cMotion.SetMidAirAccelerationTime(cSettings.m_MidAirAccelerationTime);
	cMotion.SetJumpForce(cSettings.m_JumpForce);
	cMotion.SetGravityAcceleration(cSettings.m_GravityAcceleration);
	cMotion.SetMaxAccelerationFactor(cSettings.m_MaxAccelerationFactor);
	cMotion.SetMinimumHeight(cSettings.m_MinimumHeight);
 
	// Update camera position
	// Make sure that no start positions are chosen that lie on a vertex, cause
	// GetSurfaceHeight() has problems with those points
	cMotion.SetXPos((cSettings.m_WorldSizeY / 2) * cLandscape.GetStepSize() + 
		(cLandscape.GetStepSize() / 2.0f));	
	cMotion.SetZPos((cSettings.m_WorldSizeX / 2) * cLandscape.GetStepSize() + 
		(cLandscape.GetStepSize() / 2.0f));
	cMotion.SetYPos(cMotion.GetSurfaceHeight());
	cMotion.SetSizeOfViewer(cSettings.m_SizeOfViewer);

	// Load font
	fontLoad(cSettings.m_FontFilename);

	// Load crosshair
	cCrosshair.LoadBMPTexture(cSettings.m_CrosshairTexture);
	cCrosshair.SetCrosshairSize(cSettings.m_CrosshairSize);
	cCrosshair.SetCrosshairTransparency(cSettings.m_CrosshairTransparency);

	// Link landscape with the tree collection
	cTreeCollection.SetLandscape(&cLandscape);

	// Generate trees
	cTreeCollection.SetMaxTerrainRoughness(cSettings.m_MaxTerrainRoughness);
	if (!cTreeCollection.GenerateTrees(cSettings.m_TreeCount, cSettings.m_TreeSize))
	{
		MessageBox(GetActiveWindow(), "Can't find enough valid places to place all trees", "Error", MB_ICONERROR);
		PostQuitMessage(0);
	}

	// Init input class
	cInput.SetMotionClassPointer(&cMotion);
	cInput.SetInvertMouse(cSettings.m_MouseInvert == 1);
	cInput.SetMouseSpeed(cSettings.m_MouseSpeed);
	
	// Load weapon
	if (cSettings.m_WeaponEnabled == 1)
		cWeapon.LoadModel(cSettings.m_WeaponModel, cSettings.m_WeaponSkin);
	
	// Setup flashlight
	if (cSettings.m_FlashlightEnabled == 1)
	{
		cFlashlight.SetupLight(GL_LIGHT1);
		// Update flashlight's position before the camera transformation
		cFlashlight.UpdatePosition();
	}

	// Setup sunlight
	cSunlight.SetupLight(GL_LIGHT0, cSettings.m_SunAmbient, cSettings.m_SunDiffuse,
		cSettings.m_WorldSizeX / 2 * cLandscape.GetStepSize(),
		cSettings.m_WorldSizeY / 2 * cLandscape.GetStepSize());
}

GLvoid DrawGLScene()
{
	// Draw the full scene

	// Draw skybox (Draw without Z-buffer, so everything that 
	// comes after it will overdraw)
	cSkyBox.DrawSkyBox(cMotion.GetUpDownRotation(), cMotion.GetYRotation(),
		cSettings.m_FOV, cSettings.m_SunAmbient + cSettings.m_SunDiffuse, cGL.GetAspect());

	// Save matrix
	glPushMatrix();
		// Transform the viewport
		cMotion.TransformWorld();
		// Set sunlight position relative to transform
		cSunlight.UpdatePosition();
		// Draw landscape
		cLandscape.DrawLandscape(cMotion.GetYRotation(), cMotion.GetXPos(),
			cMotion.GetYPos(), cMotion.GetZPos());
		// Draw trees (trees are not affected by the sunlight)
		cSunlight.DisableLight();
		cTreeCollection.DrawAllTrees(cMotion.GetYRotation(), cMotion.GetXPos(),
			cMotion.GetYPos(), cMotion.GetZPos(), cSettings.m_TreeBrightness);
		cSunlight.EnableLight();
	// Reset matrix
	glPopMatrix();

	// Clear depth buffer
	glClear(GL_DEPTH_BUFFER_BIT);

	// Everything that comes now isn't clipped with the previous objects

	// Draw Weapon
	if (cSettings.m_WeaponEnabled == 1)
		cWeapon.DrawModel();

	// Draw FPS
	if (cSettings.m_DrawFPSCounter)
	{
		RECT rcScreen;
		unsigned int iFrameCount = cFrameCounter.GetFrameCount();
		unsigned int iXOffset = 0;
		GetClientRect(GetActiveWindow(), &rcScreen);
		if (iFrameCount > 99)
			iXOffset = 73;
		else if (iFrameCount > 9)
			iXOffset = 61;
		else
			iXOffset = 49;
		fontDrawString(rcScreen.right - iXOffset, rcScreen.bottom - 13, "%iFPS", iFrameCount);
	}	

	// Draw crosshair
	if (cSettings.m_DrawCrosshair)
		cCrosshair.DrawCrosshair(cSettings.m_FOV, cGL.GetAspect());
}

LRESULT CALLBACK WndProc(	HWND	hWnd,
							UINT	message,
							WPARAM	wParam,
							LPARAM	lParam)
{
	// Used later on to get the size of the window
	RECT Screen;
	
	// Tells Windows we want to check the message
	switch (message)
	{
		case WM_CREATE:										// Window creation
			if (!cGL.InitGL(cSettings.m_ResWidth,			// Initialize OpenGL
				cSettings.m_ResHeight, 
				cSettings.m_Fullscreen == 1,hWnd))	
			{												// Init failed
				cGL.DestroyGL();							// Shutdown GL
				PostQuitMessage(0);							// Exit programm
			}
			InitEngine();									// Init engine
			POINT lCrosshair;								// Center mouse
			GetClientRect(hWnd, &Screen);
			lCrosshair.x = Screen.right / 2;
			lCrosshair.y = Screen.bottom / 2;
			ClientToScreen(hWnd, &lCrosshair);
			SetCursorPos(lCrosshair.x, lCrosshair.y); 
			ShowCursor(FALSE);								// Hide mouse
			break;

		case WM_DESTROY:									// Windows being destroyed
			break;

		case WM_CLOSE:										// Windows being closed
			cGL.DestroyGL();								// Shutown GL
			ShowCursor(TRUE);								// Show mouse
			TIMECAPS Caps;									// Shutdown the multimedia timer
			timeGetDevCaps(&Caps, sizeof(Caps));
			timeEndPeriod(Caps.wPeriodMin);
			PostQuitMessage(0);								// Quit the program
			break;

		case WM_KEYDOWN:									// Key being held down
			cInput.SetKeyState(wParam, TRUE);				// Make that keys cell true
			break;

		case WM_KEYUP:										// Key is released
			cInput.SetKeyState(wParam, FALSE);				// Make that keys cell false
			break;

		case WM_LBUTTONDOWN:								// Left mouse button is pressed
			cInput.SetMouseButtonState(0, TRUE);
			break;

		case WM_RBUTTONDOWN:								// Right mouse button is pressed
			cInput.SetMouseButtonState(1, TRUE);
			break;

		case WM_MBUTTONDOWN:								// Middle mouse button is pressed
			cInput.SetMouseButtonState(2, TRUE);
			break;

		case WM_SIZE:										// Resizing the screen
			cGL.Resize(LOWORD(lParam),HIWORD(lParam),		// Resize to the new window size
				cSettings.m_FOV, cSettings.m_ViewDepth);		
			break;

		case WM_MOUSEMOVE:
			cInput.SetMousePos(LOWORD(lParam),				// Position of the cursor 
				               HIWORD(lParam));
			break;
 
		default:
			// Pass windows messages
			return (DefWindowProc(hWnd, message, wParam, lParam));
	}

	return (0);
}

int WINAPI WinMain(	HINSTANCE	hInstance, 
					HINSTANCE	hPrevInstance, 
					LPSTR		lpCmdLine, 
					int			nCmdShow)
{
	// Read engine settings from the ini file before any other initialisation is performed
	cSettings.ReadSettings("glExplorer.ini");

	MSG			msg;		// Windows message structure
	WNDCLASS	wc;			// Windows class structure used to set up the type of window
	HWND		hWnd;		// Storage for window handle

	//cDlg.ShowDialog(hInstance, NULL);
	
	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	wc.lpfnWndProc		= (WNDPROC) WndProc;
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hInstance		= hInstance;
	wc.hIcon			= NULL;
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground	= NULL;
	wc.lpszMenuName		= NULL;
	wc.lpszClassName	= "OpenGL WinClass";

	if(!RegisterClass(&wc))
	{
		MessageBox(0, "Failed to register the window class", "Error", MB_OK | MB_ICONERROR);
		return FALSE;
	}

	hWnd = CreateWindow(
	"OpenGL WinClass",
	"glExplorer",				// Title appearing at the top of the window

	WS_POPUP |
	WS_CLIPCHILDREN |
	WS_CLIPSIBLINGS,
	
	0,							// The position of the window on the screen
	0,		
	cSettings.m_ResWidth,		// The width and height of the window
	cSettings.m_ResHeight,		

	NULL,
	NULL,
	hInstance,
	NULL);

	if (!hWnd)
	{
		MessageBox(0, "Window creation error", "Error", MB_OK | MB_ICONERROR);
		return FALSE;
	}

	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);
	SetFocus(hWnd);

	// Hold last tick
	DWORD dwLastTick = timeGetTime();
	cInput.SetLastTick(dwLastTick);

	while (1)
	{
		// Process All Messages
		while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
		{
			if (GetMessage(&msg, NULL, 0, 0))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
			else
			{
				return TRUE;
			}
		}

		// Handle mouse and keyboard input
		cInput.HandleKeyboardInput();
		cInput.HandleMouseInput();
		
		// Apply motion physics
		cMotion.ApplyMotionPhysics(timeGetTime() - dwLastTick);
		// Set new tick
		dwLastTick = timeGetTime();
				
		// Draw scene
		DrawGLScene();
		cGL.SwapBuffers();
		
		// One more frames has been drawn
		cFrameCounter.FrameFinished();

		// Check for exit
		if (cInput.GetKeyState(VK_ESCAPE)) SendMessage(hWnd, WM_CLOSE, 0, 0);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -