📄 glexplorer.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 + -