这个引擎是基于win32架构写的, Platform可以理解成是整个引擎的入口。控制着引擎的整个生命周期,内部主要完成了openGL、win32窗口句柄的初始化;键盘鼠标事件分发;主循环控制。关闭程序的处理。
1.首先是执行了Platform中的静态函数SetWindowSize,设置了Win32窗口的初始化xy位置,以及窗口大小。
void CPlateForm::setWindowSize(int x, int y, int wid, int hei)
{
window_x = x;
window_y = y;
windows_width = wid;
windows_height = hei;
}
2.接着是构造Platform的单例类(当时代码有些不规范,Platform已经是单例类了,直接在Init的时候传递x、y、w、h,然后在Init函数里执行原本构造函数里的这些代码就好了。没有必要再写一个静态类专门来Save一下x、y、w、h这四个参数了)
CPlateForm::CPlateForm()
{
hRC = NULL;
hDC = NULL;
hWnd = NULL;
hInst = NULL;
isPause = false;
gameMode = PLAYING;
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
MyRegisterClass();// 执行应用程序初始化:
if (!InitInstance())
{
MessageBox(NULL, L"不能成功初始化", L"错误", MB_OK | MB_ICONEXCLAMATION);
}
HACCEL hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(NULL));
memset(&msg, 0, sizeof(MSG));
m_Audio.Initialize(hWnd);
}
2.1.接着会调用MyRegisterClass对Win32窗口的大小、icon、光标、窗口风格进行设置,然后调用系统API把我们设置好的参数传递给操作系统。
ATOM CPlateForm::MyRegisterClass()
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInst;
wcex.hIcon = LoadIcon(hInst,NULL);//托盘上的ICO图标
wcex.hCursor = LoadCursorFromFileA("res/color/0081.ani");
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"myClass";
wcex.hIconSm = LoadIcon(wcex.hInstance,NULL);//窗口上的ICO图标
return RegisterClassExW(&wcex);
}
2.2 配置完成窗口配置后,会在这个函数里真正的创建一个Win32窗口,并返回一个窗口句柄(其实可以理解成系统给我们分配的一个窗口Id),接着初始化OpenGL。
BOOL CPlateForm::InitInstance()
{
//hInst = hInstance; // 将实例句柄存储在全局变量中
int nX = GetSystemMetrics(SM_CXFRAME) * 4;
int nY = GetSystemMetrics(SM_CYFRAME) * 4 + GetSystemMetrics(SM_CYCAPTION);//+ GetSystemMetrics(SM_CYMENU);
//创建Win32窗口,返回窗口句柄
hWnd = CreateWindowW(L"myClass", L"荒岛求生_V1.1", WS_OVERLAPPEDWINDOW,
window_x, window_y, windows_width + nX, windows_height + nY, nullptr, nullptr, NULL, nullptr);
if (!hWnd)
{
return FALSE;
}
//初始化OpenGL配置
InitGL();
//初始化硬件获取纹理通道
glewInit();
//操作系统API,显示这个窗口
ShowWindow(hWnd, true);
//立即刷新窗口
UpdateWindow(hWnd);
//顶点缓存上的,没有用到
//使用VBO查询字符串为
//#ifndef NO_VBOS
// g_fVBOSupported = IsExtensionSupported("GL_ARB_vertex_buffer_object");
// //返回1为支持.
// //下面声明VBO扩展函数
// // VBO Extension Function Pointers
// PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL; // VBO Name Generation Procedure
// PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL; // VBO Bind Procedure
// PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL; // VBO Data Loading Procedure
// PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL; // VBO Deletion Procedure
//
// if (g_fVBOSupported) //获取函数地址
// {
// // 获得函数的指针
// glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
// glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
// glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");
// glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)wglGetProcAddress("glDeleteBuffersARB");
// }
//#else
// g_fVBOSupported = false;
//#endif
return TRUE;
}
2.3 这个函数比较长,其实主要干的事儿就是给OpenGL传递参数开启或者关闭开关,对OpenGL进行初始化,因为OpenGL需要设置的参数实在是太多了,具体备注代码上都有,大家直接看代码吧!
// 此处开始对OpenGL进行所有设置
GLboolean CPlateForm::InitGL(GLvoid)
{
static PIXELFORMATDESCRIPTOR pfd = // /pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式
{
sizeof(PIXELFORMATDESCRIPTOR), // 上述格式描述符的大小
1, // 版本号
PFD_DRAW_TO_WINDOW | // 格式支持窗口
PFD_SUPPORT_OPENGL | // 格式必须支持OpenGL
PFD_DOUBLEBUFFER, // 必须支持双缓冲
PFD_TYPE_RGBA, // 申请 RGBA 格式
24, // 选定色彩深度
0, 0, 0, 0, 0, 0, // 忽略的色彩位
0, // 无Alpha缓存
0, // 忽略Shift Bit
0, // 无累加缓存
0, 0, 0, 0, // 忽略聚集位
16, // 16位 Z-缓存 (深度缓存)
1, // 无蒙板缓存
0, // 无辅助缓存
PFD_MAIN_PLANE, // 主绘图层
0, // Reserved
0, 0, 0 // 忽略层遮罩
};
if (!(hDC = GetDC(hWnd))) // 取得设备描述表了么?
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, L"不能创建一种相匹配的像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
// 返回 FALSE
}
GLuint PixelFormat = ChoosePixelFormat(hDC, &pfd); // Windows 找到相应的象素格式了吗?
if (!SetPixelFormat(hDC, PixelFormat, &pfd)) // 能够设置象素格式么?
return false;
// 能否取得着色描述表?
if (!(hRC = wglCreateContext(hDC)))
return false;
// 尝试激活着色描述表
if (!wglMakeCurrent(hDC, hRC))
return false;
// Windows 找到相应的象素格式了吗?
if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd)))
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, L"不能设置像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回 FALSE
}
if (!SetPixelFormat(hDC, PixelFormat, &pfd)) // 能够设置象素格式么?
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, L"不能设置像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回 FALSE
}
if (!(hRC = wglCreateContext(hDC))) // 能否取得着色描述表?
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, L"不能创建OpenGL渲染描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回 FALSE
}
if (!wglMakeCurrent(hDC, hRC)) // 尝试激活着色描述表
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, L"不能激活当前的OpenGL渲然描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回 FALSE
}
glStencilMask(0); //蒙版缓冲区置为0
glShadeModel(GL_SMOOTH); // 启用阴影平滑
glClearColor(0.0f,0.0f, 0.0f,1.0f); // 背景
glClearDepth(1.0f); // 设置深度缓存
glEnable(GL_DEPTH_TEST); // 启用深度测试
glDepthFunc(GL_LEQUAL); // 所作深度测试的类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 真正精细的透视修正,告诉系统对透视进行修正
glFrontFace(GL_CCW); //多边形逆时针方向为正面
glClearStencil(0);
glEnable(GL_CULL_FACE); //只显示正面
ReSizeGLScene(windows_width, windows_height); //设置openGL窗口大小
InitGeometry();
return TRUE; // 初始化 OK
}
2.4 InitGeometry 是初始化操作的最后一个函数,函数里面干的事儿主要就是设置光源位置,设置环境光、漫反射、高光的颜色。开启了范围雾、设置了雾的开始Z值 和 结束Z值,其实这些代码也能放到InitGL函数里面,但是考虑到InitGL函数太长了,这些代码干的事儿主要是初始化光源和雾气配置,所以细分了一下函数,就给拆出来了。
void CPlateForm::InitGeometry()
{
glEnable(GL_NORMALIZE);
GLfloat LightPos[] = { 0.0f,0.0f,5.0f,1.0f };
GLfloat LightAmb[] = { 0.5f,0.5f,0.5f,1.0f };
GLfloat LightDif[] = { 0.8f,0.8f,0.8f,1.0f };
GLfloat LightSpe[] = { 0.8f,0.8f,0.8f,1.0f };
glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif);
glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpe);
GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR }; // 雾气的模式
GLfloat fogColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; // 雾的颜色设为灰色
glFogi(GL_FOG_MODE, GL_LINEAR); // 设置雾气的模式
glFogfv(GL_FOG_COLOR, fogColor); // 设置雾的颜色
glFogf(GL_FOG_DENSITY,0.05f); // 设置雾的密度
glHint(GL_FOG_HINT, GL_DONT_CARE); // 设置系统如何计算雾气
glFogf(GL_FOG_START,2000.0f); // 雾气的开始位置
glFogf(GL_FOG_END,4000.0f); // 雾气的结束位置
}
3.Run起来!初始化都完成之后,程序当然就要Run起来了,这个引擎其实只能说是一个Demo引擎,逻辑线程和渲染线程当时给放到一块儿了,Render函数里其实不光是做了DrawElement这件事儿,而且还做了逻辑的update这件事儿,所以现在要我做的话肯定要分两个线程来做,而且Render里面的Update函数也得拆出来。每次循环都会Clear颜色缓冲区和深度缓冲区,清理了前台缓冲区后,立马使用SwapBuffers把后台的缓冲区交换到前台来,这样可以保证画面不会出现闪屏的现象。
void CPlateForm::run()
{
U3D::CEngineButton::getInstance()->InitAll();
U3D::CResouceManage::getInstance()->Init();
U3D::CResourceCompound::getInstance()->init();
CEffects::getInstance()->init();
label = new U3D::CUI_Label("A","宋体",24);
//1:m_pos 2:m_ssssslook 3:m_up 4:m_right
Vector3D pos[4] = {
{ Vector3D(0,500,0)},
{ Vector3D(0,0,1) },
{ Vector3D(0,1,0) },
{ Vector3D(1,0,0) } };
godCamera = new freeCamera(pos);
godCamera->rightRotate(90);
LARGE_INTEGER nFreq;
QueryPerformanceFrequency(&nFreq);
LARGE_INTEGER nAnimationInterval;
nAnimationInterval.QuadPart = (LONGLONG)(1.0 / FPS * nFreq.QuadPart);
LARGE_INTEGER nLast;
LARGE_INTEGER nNow;
QueryPerformanceCounter(&nLast);
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
if (!PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
QueryPerformanceCounter(&nNow);
if (nNow.QuadPart - nLast.QuadPart > nAnimationInterval.QuadPart)
{
nLast.QuadPart = nNow.QuadPart;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
Render();
SwapBuffers(hDC); // 交换缓存 (双缓存)
}
else { Sleep(0); }continue;
}
TranslateMessage(&msg); //翻译消息
DispatchMessage(&msg);
//分发消息
}
}
3.1 这个Render不一般,里面既实现了不同的模式下对透视矩阵和正交矩阵的切换,也实现了引擎的update,还实现了输入控制器的刷新。
GLvoid CPlateForm::Render()
{
if (Input::getKeyDown(VK_TAB))
gameMode = gameMode == EDITMODE ? PLAYING : EDITMODE;
if (currentEnvironment == NIGHT)
selectNight();
else if (currentEnvironment == DAYTIME)
selectDaytime();
switch (gameMode)
{
case TIELEMODE:
{
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else
U3D::CSceneManage::getInstance()->pause(updateTime());
select2DSpace();
U3D::CSceneManage::getInstance()->draw2D();
}break;
case EDITMODE:
{
glViewport(0, 0, 840, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluPerspective(80.0f, 840.0f / 760.0f, 0.1f, 15000.0f);//透视远近
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
godCamera->update();
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else
U3D::CSceneManage::getInstance()->pause(updateTime());
godCamera->drawFrustum();
if (Fog)
glEnable(GL_FOG);
else
glDisable(GL_FOG);
/
//右边2d
glViewport(840, 0, 440, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluOrtho2D(0, 440, windows_height, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
U3D::CSceneManage::getInstance()->drawDebug();
U3D::CEngineButton::getInstance()->_draw();
glPushMatrix();
glLoadIdentity();
label->setString("0l,2,3切换图片,右击存");
label->setPosition(850, 0, 1);
label->draw();
label->setString("鼠标X:%f鼠标Y:%f", mousePos.x, mousePos.y);
label->setPosition(850, 30, 0);
label->draw();
label->setString("小键盘0开关线段模式");
label->setPosition(850, 60, 0);
label->draw();
label->setString("当前渲染对象数量:%d", objNumber);
label->setPosition(850, 90, 0);
label->draw();
label->setString("TAB:开/关编辑模式");
label->setPosition(850, 120, 0);
label->draw();
label->setString("FPS:%f", getFPS());
label->setPosition(850, 150, 0);
label->draw();
glColor4f(1,1,1,1);
glPopMatrix();
if (Input::getKeyDown(VK_F2))
light = light == false ? 1 : 0;
if (Input::getKeyDown(VK_F3))
Fog = Fog == false ? 1 : 0;
if (Input::getKeyDown(VK_NUMPAD0))
lines = lines == false ? true : false;
if (light)
{
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);
}
else
{
glDisable(GL_LIGHTING); glDisable(GL_LIGHT0);
}
if (lines)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}break;
case IN_SPACE:
{
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 5000.0f);//透视远近
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Camera::getInstance()->update();
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else if (isPause)
U3D::CSceneManage::getInstance()->pause(updateTime());
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluOrtho2D(0, windows_width, windows_height, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
U3D::CSceneManage::getInstance()->draw2D();
}break;
case FALLING://陨落的场景
{
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 15000.0f);//透视远近
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Camera::getInstance()->update();
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else if (isPause)
U3D::CSceneManage::getInstance()->pause(updateTime());
}break;
case PLAYING:
{
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 5000.0f);//透视远近
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Camera::getInstance()->update();
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else if (isPause)
U3D::CSceneManage::getInstance()->pause(updateTime());
//partic->draw(0.2);
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluOrtho2D(0, windows_width, windows_height, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
U3D::CSceneManage::getInstance()->draw2D();
label->setString("-FPS:%f", getFPS());
label->setPosition(0, 920, 0);
label->draw();
}break;
case FLY://逃离这个星球
{
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 15000.0f);//透视远近
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Camera::getInstance()->update();
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else if (isPause)
U3D::CSceneManage::getInstance()->pause(updateTime());
label->setString("-FPS:%f", getFPS());
label->setPosition(0, 920, 0);
label->draw();
}break;
case END://结尾的场景
{
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else if (isPause)
U3D::CSceneManage::getInstance()->pause(updateTime());
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluOrtho2D(0, windows_width, windows_height, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
U3D::CSceneManage::getInstance()->draw2D();
}break;
}
Input::flush();
}
4.WndProc函数是注册进操作系统的回调,监听了用户的鼠标键盘响应事件,收到后丢给场景管理器去处理了系统传过来的事件。
LRESULT CALLBACK CPlateForm::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
U3D::CSceneManage::getInstance()->MsgProc(hWnd, message, wParam, lParam);
U3D::CSceneManage::getInstance()->my2DMsgProc(hWnd, message, wParam, lParam);
switch (message)
{
case WM_ACTIVATE:
case WM_SIZE:
switch (wParam)
{
case SIZE_MINIMIZED:
break;
}
break;
case WM_RBUTTONDOWN:
oldMousePos.x= LOWORD(lParam);
oldMousePos.y= HIWORD(lParam);
_mouseIsDown = true;
break;
case WM_MOUSEMOVE:
{
mousePos.x = LOWORD(lParam);
mousePos.y = HIWORD(lParam);
if (_mouseIsDown)
{
offset= oldMousePos - mousePos;
}
oldMousePos = mousePos;
}break;
case WM_RBUTTONUP:
_mouseIsDown = false;
break;
case WM_KEYDOWN:
{
switch (wParam)
{
break;
case VK_F1:
isDebug = true;
break;
case VK_F2:
break;
case VK_F3:break;
case VK_F11:break;
case VK_F12:break;
}
}break;
case WM_CLOSE:
{
getInstance()->KillGLWindow();
delete Instance;
PostQuitMessage(0);
}break;
return DefWindowProc(hWnd, message, wParam, lParam);
}
完整代码(Platform.h)
#pragma once
#define _WINDOW_WID_ 1280.0f
#define _WINDOW_HEI_ 960.0f
enum ENVIRONMENT //环境:白天和晚上
{
DAYTIME,
NIGHT
};
enum GameMode //游戏模式:
{
TIELEMODE,
IN_SPACE, //在宇宙里
FALLING, //落下
PLAYING, //在玩
EDITMODE, //编辑模式
FLY, //飞走(后面会是END)
DEAD, //死亡
END //结束(胜利以后的)
};
class CPlateForm
{
private:
U3D::CUI_Label *label;
GameMode gameMode;
ENVIRONMENT currentEnvironment=DAYTIME; //当前环境默认是白天
private:
int AxisMode = 1; //轴模式 拖动:1 缩放:3 旋转:3
int objNumber = 0;
private:
const int FPS =120; //FPS每一秒60帧
HINSTANCE hInst; // 当前实例
HGLRC hRC; // 窗口着色描述表句柄
HDC hDC; // OpenGL渲染描述表句柄
HWND hWnd; // 保存我们的窗口句柄
MSG msg; //消息
static wchar_t IcoName; //Icona名字
static bool isPause; //游戏暂停
static int windows_width;
static int windows_height;
static int window_x;
static int window_y;
bool isAutoSort = false;
static bool isDebug;
static bool _mouseIsDown;
bool g_fVBOSupported = false;//是否支持顶点缓存
static CPlateForm*Instance;
public:
CAudio4Bass m_Audio;
int m_MusicIndex;
static Vector2 mousePos;
static Vector2 oldMousePos;
static Vector2 offset;
freeCamera *godCamera;
///Other/
void run();
float updateTime(); //时间差:秒
void initObjNum() { objNumber = 0; }
void Resume() { isPause = false; } //恢复
void Pause() { isPause = true; } //暂停
void InitGeometry();
GLvoid ReSizeGLScene(GLsizei width, GLsizei height);
GLboolean InitGL(GLvoid);
GLvoid KillGLWindow(GLvoid);
GLvoid Render();
ATOM MyRegisterClass();
int getObjNumber() { return objNumber; }
BOOL InitInstance();
void OpenEditor();
Vector3D CPlateForm::MouseTransfrom(int mouse_x, int mouse_y);
bool IsExtensionSupported(char* szTargetExtension);
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
///Set/
static void setIco(wchar_t ico) { IcoName = ico; }
static void setWindowSize(int x, int y, int wid, int hei);
void setGameMode(GameMode mode);
void setObjNumber(int n) { this->objNumber = n; }
void setAutoSort(bool autoSort);
void setAxisMode(int Axis);
void setEnvironment(ENVIRONMENT V){this->currentEnvironment=V;}
///Get///
static CPlateForm *getInstance();
float getFPS();
HDC getHdc() { return hDC; }
HWND getHwnd() { return hWnd; }
UINT Get_win_width() { return windows_width; }
UINT Get_win_height() { return windows_height; }
bool getIsDebugMode();
bool getAutoSort();
CAudio4Bass getAudioBass() { return m_Audio; }
bool getMouseIsDown();
bool getfVBOSupported() { return g_fVBOSupported; }
int getAxisMode();
GameMode getGameMode();
ENVIRONMENT getEnvironment(){return currentEnvironment;}
void select2DSpace();
void select3DSpace();
sColor selectDaytime();
sColor selectNight();
CPlateForm();
~CPlateForm();
};
完整代码Platform.cpp
#include "Engine.h"
#include "resource.h"
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//
//
bool CPlateForm::isPause = false;
int CPlateForm::windows_width = 1080;
int CPlateForm::windows_height = 720;
int CPlateForm::window_x = 0;
int CPlateForm::window_y = 0;
wchar_t CPlateForm::IcoName=NULL;
CPlateForm*CPlateForm::Instance = NULL;
bool CPlateForm::isDebug = false;
bool CPlateForm::_mouseIsDown = false;
Vector2 CPlateForm::mousePos;
Vector2 CPlateForm::oldMousePos;
Vector2 CPlateForm::offset;
//
//-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
CPlateForm::CPlateForm()
{
hRC = NULL;
hDC = NULL;
hWnd = NULL;
hInst = NULL;
isPause = false;
gameMode = PLAYING;
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
MyRegisterClass();// 执行应用程序初始化:
if (!InitInstance())
{
MessageBox(NULL, L"不能成功初始化", L"错误", MB_OK | MB_ICONEXCLAMATION);
}
HACCEL hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(NULL));
memset(&msg, 0, sizeof(MSG));
/*char *MusicList[5] = { "res/小酒窝.mp3","res/爱.mp3","res/爱要怎么说出口.mp3"
,"res/江南.mp3","res/Where Them Girls At.mp3" };
m_Audio.Initialize(0);
for (int i = 0;i < 5;i++)
{
m_MusicIndex = m_Audio.LoadFile(MusicList[i], BASS_MUSIC_FLOAT);
}
MusicLen=m_Audio.ChannelBytes2Seconds(m_MusicIndex, m_Audio.GetChannelLength(m_MusicIndex, BASS_MUSIC_LOOP));
m_Audio.ChannelPlay(m_MusicIndex, true);*/
m_Audio.Initialize(hWnd);
//m_MusicIndex = m_Audio.LoadFile("res/音效/主场景主被攻击.mp3", BASS_MUSIC_LOOP/*BASS_MUSIC_FX*/);
//m_Audio.ChannelPlay(m_MusicIndex,false);
}
CPlateForm *CPlateForm::getInstance()
{
if (Instance == NULL)
{
Instance = new CPlateForm;
}
return Instance;
}
void CPlateForm::setWindowSize(int x, int y, int wid, int hei)
{
window_x = x;
window_y = y;
windows_width = wid;
windows_height = hei;
}
float CPlateForm::updateTime()
{
static float previousTime = GetTickCount() / 1000.0f;
float currentTime = GetTickCount() / 1000.0f;
float elapsedTime = currentTime - previousTime;
previousTime = currentTime;
return elapsedTime;
}
float CPlateForm::getFPS()
{
static float timeNow = GetTickCount() / 1000.0f;
static DWORD dwRenderedFrame = 0;
float tFrame = GetTickCount() / 1000.0f - timeNow;
timeNow += tFrame;
static float fps = 0;
if (fmodf(timeNow, 1) < tFrame)
{
fps = dwRenderedFrame + fmodf(timeNow, 1) / tFrame; //计算FPS
dwRenderedFrame = 0;
}
dwRenderedFrame++;
return fps;
}
GLboolean CPlateForm::InitGL(GLvoid) // 此处开始对OpenGL进行所有设置
{
static PIXELFORMATDESCRIPTOR pfd = // /pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式
{
sizeof(PIXELFORMATDESCRIPTOR), // 上述格式描述符的大小
1, // 版本号
PFD_DRAW_TO_WINDOW | // 格式支持窗口
PFD_SUPPORT_OPENGL | // 格式必须支持OpenGL
PFD_DOUBLEBUFFER, // 必须支持双缓冲
PFD_TYPE_RGBA, // 申请 RGBA 格式
24, // 选定色彩深度
0, 0, 0, 0, 0, 0, // 忽略的色彩位
0, // 无Alpha缓存
0, // 忽略Shift Bit
0, // 无累加缓存
0, 0, 0, 0, // 忽略聚集位
16, // 16位 Z-缓存 (深度缓存)
1, // 无蒙板缓存
0, // 无辅助缓存
PFD_MAIN_PLANE, // 主绘图层
0, // Reserved
0, 0, 0 // 忽略层遮罩
};
if (!(hDC = GetDC(hWnd))) // 取得设备描述表了么?
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, L"不能创建一种相匹配的像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
// 返回 FALSE
}
GLuint PixelFormat = ChoosePixelFormat(hDC, &pfd); // Windows 找到相应的象素格式了吗?
if (!SetPixelFormat(hDC, PixelFormat, &pfd)) // 能够设置象素格式么?
return false;
if (!(hRC = wglCreateContext(hDC))) // 能否取得着色描述表?
return false;
if (!wglMakeCurrent(hDC, hRC)) // 尝试激活着色描述表
return false;
//GLuint PixelFormat;
if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) // Windows 找到相应的象素格式了吗?
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, L"不能设置像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回 FALSE
}
if (!SetPixelFormat(hDC, PixelFormat, &pfd)) // 能够设置象素格式么?
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, L"不能设置像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回 FALSE
}
if (!(hRC = wglCreateContext(hDC))) // 能否取得着色描述表?
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, L"不能创建OpenGL渲染描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回 FALSE
}
if (!wglMakeCurrent(hDC, hRC)) // 尝试激活着色描述表
{
KillGLWindow(); // 重置显示区
MessageBox(NULL, L"不能激活当前的OpenGL渲然描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // 返回 FALSE
}
glStencilMask(0); //蒙版缓冲区置为0
glShadeModel(GL_SMOOTH); // 启用阴影平滑
glClearColor(0.0f,0.0f, 0.0f,1.0f); // 背景
glClearDepth(1.0f); // 设置深度缓存
glEnable(GL_DEPTH_TEST); // 启用深度测试
glDepthFunc(GL_LEQUAL); // 所作深度测试的类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 真正精细的透视修正,告诉系统对透视进行修正
glFrontFace(GL_CCW); //多边形逆时针方向为正面
glClearStencil(0);
glEnable(GL_CULL_FACE); //只显示正面
ReSizeGLScene(windows_width, windows_height); //设置openGL窗口大小
InitGeometry();
return TRUE; // 初始化 OK
}
void CPlateForm::InitGeometry()
{
//quadratic = gluNewQuadric();
//gluQuadricNormals(quadratic, GLU_SMOOTH); // 使用平滑法线
//gluQuadricTexture(quadratic, GL_TRUE); // 使用纹理
glEnable(GL_NORMALIZE);
GLfloat LightPos[] = { 0.0f,0.0f,5.0f,1.0f };
GLfloat LightAmb[] = { 0.5f,0.5f,0.5f,1.0f };
GLfloat LightDif[] = { 0.8f,0.8f,0.8f,1.0f };
GLfloat LightSpe[] = { 0.8f,0.8f,0.8f,1.0f };
glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif);
glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpe);
GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR }; // 雾气的模式
GLfloat fogColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; // 雾的颜色设为灰色
glFogi(GL_FOG_MODE, GL_LINEAR); // 设置雾气的模式
glFogfv(GL_FOG_COLOR, fogColor); // 设置雾的颜色
glFogf(GL_FOG_DENSITY,0.05f); // 设置雾的密度
glHint(GL_FOG_HINT, GL_DONT_CARE); // 设置系统如何计算雾气
glFogf(GL_FOG_START,2000.0f); // 雾气的开始位置
glFogf(GL_FOG_END,4000.0f); // 雾气的结束位置
}
GLvoid CPlateForm::ReSizeGLScene(GLsizei width, GLsizei height)
{
//glPushMatrix();
视口
glViewport(0, 0, width, height);
投影
//glMatrixMode(GL_PROJECTION);
glOrtho(0, windows_width, windows_height, 0, -1, 1); //2D
//glLoadIdentity();
//gluPerspective(45.0f,1.0, 0.1f, 100.0f); //3D
视图
//glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵
//glLoadIdentity(); // 重置模型观察矩阵
//glPopMatrix();
}
bool CPlateForm::IsExtensionSupported(char* szTargetExtension)
{
const unsigned char *pszExtensions = NULL;
const unsigned char *pszStart;
unsigned char *pszWhere, *pszTerminator;
pszWhere = (unsigned char *)strchr(szTargetExtension, ' ');
if (pszWhere || *szTargetExtension == '\0')
return false;
// 返回扩展字符串
pszExtensions = glGetString(GL_EXTENSIONS);
// 在扩展字符串中搜索
pszStart = pszExtensions;
for (;;)
{
pszWhere = (unsigned char *)strstr((const char *)pszStart, szTargetExtension);
if (!pszWhere)
break;
pszTerminator = pszWhere + strlen(szTargetExtension);
if (pszWhere == pszStart || *(pszWhere - 1) == ' ')
if (*pszTerminator == ' ' || *pszTerminator == '\0')
//如果存在返回True
return true;
pszStart = pszTerminator;
}
return false;
}
GLvoid CPlateForm::KillGLWindow(GLvoid)
{
if (hRC) // 我们拥有OpenGL渲染描述表吗?
{
if (!wglMakeCurrent(NULL, NULL))
{
MessageBox(NULL, L"释放DC或RC失败。", L"关闭错误", MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // 我们能否删除RC?
{
MessageBox(NULL, L"释放RC失败。", L"关闭错误", MB_OK | MB_ICONINFORMATION);
}
hRC = NULL;
}
if (hDC && !ReleaseDC(hWnd, hDC))
{
MessageBox(NULL, L"释放DC失败。", L"关闭错误", MB_OK | MB_ICONINFORMATION);
hDC = NULL;
}
}
ATOM CPlateForm::MyRegisterClass()
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInst;
wcex.hIcon = LoadIcon(hInst,NULL);//托盘上的ICO图标
//wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
//wcex.hCursor=gameMode ==PLAYING ? LoadCursorFromFileA("res/color/Prcs_IcP.ani"):LoadCursor(nullptr, IDC_ARROW);
wcex.hCursor = LoadCursorFromFileA("res/color/0081.ani");
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"myClass";
wcex.hIconSm = LoadIcon(wcex.hInstance,NULL);//窗口上的ICO图标
return RegisterClassExW(&wcex);
}
BOOL CPlateForm::InitInstance()
{
//hInst = hInstance; // 将实例句柄存储在全局变量中
int nX = GetSystemMetrics(SM_CXFRAME) * 4;
int nY = GetSystemMetrics(SM_CYFRAME) * 4 + GetSystemMetrics(SM_CYCAPTION);//+ GetSystemMetrics(SM_CYMENU);
hWnd = CreateWindowW(L"myClass", L"荒岛求生_V1.1", WS_OVERLAPPEDWINDOW,
window_x, window_y, windows_width + nX, windows_height + nY, nullptr, nullptr, NULL, nullptr);
if (!hWnd)
{
return FALSE;
}
InitGL();
glewInit();//初始化硬件获取纹理通道
ShowWindow(hWnd, true);
UpdateWindow(hWnd);
//顶点缓存上的,可是没有用到··
//使用VBO查询字符串为
//#ifndef NO_VBOS
// g_fVBOSupported = IsExtensionSupported("GL_ARB_vertex_buffer_object");
// //返回1为支持.
// //下面声明VBO扩展函数
// // VBO Extension Function Pointers
// PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL; // VBO Name Generation Procedure
// PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL; // VBO Bind Procedure
// PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL; // VBO Data Loading Procedure
// PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL; // VBO Deletion Procedure
//
// if (g_fVBOSupported) //获取函数地址
// {
// // 获得函数的指针
// glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
// glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
// glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");
// glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)wglGetProcAddress("glDeleteBuffersARB");
// }
//#else
// g_fVBOSupported = false;
//#endif
return TRUE;
}
LRESULT CALLBACK CPlateForm::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
U3D::CSceneManage::getInstance()->MsgProc(hWnd, message, wParam, lParam);
U3D::CSceneManage::getInstance()->my2DMsgProc(hWnd, message, wParam, lParam);
//CMouseTrack::getInstance()->MsgProc(hWnd, message, wParam, lParam);
switch (message)
{
case WM_ACTIVATE:
switch (wParam)
{
case WA_CLICKACTIVE:
case WA_ACTIVE:
//isPause = false;
break;
case WA_INACTIVE:
//isPause = true;
break;
}
break;
case WM_SIZE:
switch (wParam)
{
case SIZE_MINIMIZED:
break;
}
break;
case WM_RBUTTONDOWN:
oldMousePos.x= LOWORD(lParam);
oldMousePos.y= HIWORD(lParam);
_mouseIsDown = true;
break;
case WM_MOUSEMOVE:
{
mousePos.x = LOWORD(lParam);
mousePos.y = HIWORD(lParam);
if (_mouseIsDown)
{
offset= oldMousePos - mousePos;
}
oldMousePos = mousePos;
}break;
case WM_RBUTTONUP:
_mouseIsDown = false;
break;
case WM_KEYDOWN:
{
switch (wParam)
{
break;
case VK_F1:
isDebug = true;
break;
case VK_F2:
break;
case VK_F3:break;
case VK_F11:break;
case VK_F12:break;
}
}break;
case WM_CLOSE:
{
getInstance()->KillGLWindow();
delete Instance;
PostQuitMessage(0);
}break;
/*case WM_DESTROY:
{
if (MessageBox(hWnd, L"亲~要保存所有对象吗?", L"温馨提示", MB_OKCANCEL | MB_ICONQUESTION) == IDOK)
{
U3D::CSceneManage::getInstance()->getCurrentScene()->EngineSave();
U3D::CSceneManage::getInstance()->getCurrentScene()->UserSaveData();
}
getInstance()->KillGLWindow();
delete Instance;
PostQuitMessage(0);
}break;*/
//LOWORD:取出无符号长整形的低16位
//HIWORD:取出无符号长整形的高16位
//WPARAM:word类型, 最早是16位通常用来存储小段信息 现在类型:unsigned int
//LPARAM:long int类型 通常用于存储消息所需的对象 现在类型:long int
case WM_MOUSEWHEEL: {}break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
void CPlateForm::run()
{
U3D::CEngineButton::getInstance()->InitAll();
U3D::CResouceManage::getInstance()->Init();
U3D::CResourceCompound::getInstance()->init();
CEffects::getInstance()->init();
label = new U3D::CUI_Label("A","宋体",24);
//1:m_pos 2:m_ssssslook 3:m_up 4:m_right
Vector3D pos[4] = {
{ Vector3D(0,500,0)},
{ Vector3D(0,0,1) },
{ Vector3D(0,1,0) },
{ Vector3D(1,0,0) } };
godCamera = new freeCamera(pos);
godCamera->rightRotate(90);
LARGE_INTEGER nFreq;
QueryPerformanceFrequency(&nFreq);
LARGE_INTEGER nAnimationInterval;
nAnimationInterval.QuadPart = (LONGLONG)(1.0 / FPS * nFreq.QuadPart);
LARGE_INTEGER nLast;
LARGE_INTEGER nNow;
QueryPerformanceCounter(&nLast);
ZeroMemory(&msg, sizeof(msg));
while (msg.message != WM_QUIT)
{
if (!PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
QueryPerformanceCounter(&nNow);
if (nNow.QuadPart - nLast.QuadPart > nAnimationInterval.QuadPart)
{
nLast.QuadPart = nNow.QuadPart;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
Render();
SwapBuffers(hDC); // 交换缓存 (双缓存)
}
else { Sleep(0); }continue;
}
TranslateMessage(&msg); //翻译消息
DispatchMessage(&msg);
//分发消息
}
}
static bool lines = 0;
static bool Fog = 1;
static bool light = 1;
GLvoid CPlateForm::Render()
{
if (Input::getKeyDown(VK_TAB))
gameMode = gameMode == EDITMODE ? PLAYING : EDITMODE;
if (currentEnvironment == NIGHT)
selectNight();
else if (currentEnvironment == DAYTIME)
selectDaytime();
switch (gameMode)
{
case TIELEMODE:
{
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else
U3D::CSceneManage::getInstance()->pause(updateTime());
select2DSpace();
U3D::CSceneManage::getInstance()->draw2D();
}break;
case EDITMODE:
{
glViewport(0, 0, 840, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluPerspective(80.0f, 840.0f / 760.0f, 0.1f, 15000.0f);//透视远近
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
godCamera->update();
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else
U3D::CSceneManage::getInstance()->pause(updateTime());
godCamera->drawFrustum();
if (Fog)
glEnable(GL_FOG);
else
glDisable(GL_FOG);
/
//右边2d
glViewport(840, 0, 440, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluOrtho2D(0, 440, windows_height, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
U3D::CSceneManage::getInstance()->drawDebug();
U3D::CEngineButton::getInstance()->_draw();
glPushMatrix();
glLoadIdentity();
label->setString("0l,2,3切换图片,右击存");
label->setPosition(850, 0, 1);
label->draw();
label->setString("鼠标X:%f鼠标Y:%f", mousePos.x, mousePos.y);
label->setPosition(850, 30, 0);
label->draw();
label->setString("小键盘0开关线段模式");
label->setPosition(850, 60, 0);
label->draw();
label->setString("当前渲染对象数量:%d", objNumber);
label->setPosition(850, 90, 0);
label->draw();
label->setString("TAB:开/关编辑模式");
label->setPosition(850, 120, 0);
label->draw();
label->setString("FPS:%f", getFPS());
label->setPosition(850, 150, 0);
label->draw();
glColor4f(1,1,1,1);
glPopMatrix();
if (Input::getKeyDown(VK_F2))
light = light == false ? 1 : 0;
if (Input::getKeyDown(VK_F3))
Fog = Fog == false ? 1 : 0;
if (Input::getKeyDown(VK_NUMPAD0))
lines = lines == false ? true : false;
if (light)
{
glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);
}
else
{
glDisable(GL_LIGHTING); glDisable(GL_LIGHT0);
}
if (lines)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}break;
case IN_SPACE:
{
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 5000.0f);//透视远近
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Camera::getInstance()->update();
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else if (isPause)
U3D::CSceneManage::getInstance()->pause(updateTime());
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluOrtho2D(0, windows_width, windows_height, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
U3D::CSceneManage::getInstance()->draw2D();
}break;
case FALLING://陨落的场景
{
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 15000.0f);//透视远近
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Camera::getInstance()->update();
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else if (isPause)
U3D::CSceneManage::getInstance()->pause(updateTime());
}break;
case PLAYING:
{
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 5000.0f);//透视远近
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Camera::getInstance()->update();
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else if (isPause)
U3D::CSceneManage::getInstance()->pause(updateTime());
//partic->draw(0.2);
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluOrtho2D(0, windows_width, windows_height, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
U3D::CSceneManage::getInstance()->draw2D();
label->setString("-FPS:%f", getFPS());
label->setPosition(0, 920, 0);
label->draw();
}break;
case FLY://逃离这个星球
{
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluPerspective(80.0f, 1280.0f / 960.0f, 0.1f, 15000.0f);//透视远近
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Camera::getInstance()->update();
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else if (isPause)
U3D::CSceneManage::getInstance()->pause(updateTime());
label->setString("-FPS:%f", getFPS());
label->setPosition(0, 920, 0);
label->draw();
}break;
case END://结尾的场景
{
if (!isPause)
U3D::CSceneManage::getInstance()->run(updateTime());
else if (isPause)
U3D::CSceneManage::getInstance()->pause(updateTime());
glViewport(0, 0, windows_width, windows_height);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluOrtho2D(0, windows_width, windows_height, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
U3D::CSceneManage::getInstance()->draw2D();
}break;
}
Input::flush();
}
Vector3D CPlateForm::MouseTransfrom(int mouse_x, int mouse_y)
{
Vector3D pos;
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble posX, posY, posZ;
glPushMatrix();
glGetIntegerv(GL_VIEWPORT, viewport); // 得到的是最后一个设置视口的参数
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glPopMatrix();
winX = (float)mouse_x;
winY = viewport[3] - (float)mouse_y;
glReadPixels((int)winX, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
//if (Input::getMouseWheel(&mouseNow))
//{
// pos3D.z += mouseNow.scroll;
//}
pos.x = posX;
pos.y = posY;
pos.z = posZ;
return pos;
}
void CPlateForm::OpenEditor() { gameMode = EDITMODE; }
bool CPlateForm::getMouseIsDown() { return _mouseIsDown; }
bool CPlateForm::getIsDebugMode() { return isDebug; }
void CPlateForm::setAutoSort(bool autoSort) { this->isAutoSort = autoSort; }
bool CPlateForm::getAutoSort() { return isAutoSort; }
int CPlateForm::getAxisMode() { return AxisMode; }
void CPlateForm::setAxisMode(int Axis) { this->AxisMode = Axis; }
void CPlateForm::setGameMode(GameMode mode) { this->gameMode = mode; }
GameMode CPlateForm::getGameMode() { return gameMode; }
void CPlateForm::select2DSpace()
{
glViewport(0, 0, _WINDOW_WID_, _WINDOW_HEI_);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluOrtho2D(0, _WINDOW_WID_, _WINDOW_HEI_, 0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void CPlateForm::select3DSpace()
{
glViewport(0, 0, _WINDOW_WID_, _WINDOW_HEI_);
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
glLoadIdentity();
gluPerspective(80.0f,1280.0f/960.0f, 0.1f, 5000.0f);//透视远近
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
sColor CPlateForm::selectDaytime()
{
glEnable(GL_NORMALIZE);
GLfloat LightPos[] = { 0.0f,0.0f,5.0f,1.0f };
GLfloat LightAmb[] = { 0.5f,0.5f,0.5f,1.0f };
GLfloat LightDif[] = { 0.8f,0.8f,0.8f,1.0f };
GLfloat LightSpe[] = { 0.8f,0.8f,0.8f,1.0f };
glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif);
glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpe);
GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR }; // 雾气的模式
GLfloat fogColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; // 雾的颜色设为灰色
glFogi(GL_FOG_MODE, GL_LINEAR); // 设置雾气的模式
glFogfv(GL_FOG_COLOR, fogColor); // 设置雾的颜色
glFogf(GL_FOG_DENSITY, 0.05f); // 设置雾的密度
glHint(GL_FOG_HINT, GL_DONT_CARE); // 设置系统如何计算雾气
glFogf(GL_FOG_START, 2000.0f); // 雾气的开始位置
glFogf(GL_FOG_END, 4000.0f); // 雾气的结束位置
currentEnvironment=DAYTIME;
return sColor (1.0f, 1.0f, 1.0f, 1.0f);
}
sColor CPlateForm::selectNight()
{
glEnable(GL_NORMALIZE);
GLfloat LightPos[] = { 0.0f,0.0f,5.0f,1.0f };
GLfloat LightAmb[] = { 0.1f,0.1f,0.1f,1.0f };
GLfloat LightDif[] = { 0.1f,0.1f,0.1f,1.0f };
GLfloat LightSpe[] = { 0.1f,0.1f,0.1f,1.0f };
glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDif);
glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpe);
GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR }; // 雾气的模式
GLfloat fogColor[4] = { 0.15f, 0.15f, 0.15f, 1.0f }; // 雾的颜色设为灰色
glFogi(GL_FOG_MODE, GL_LINEAR); // 设置雾气的模式
glFogfv(GL_FOG_COLOR, fogColor); // 设置雾的颜色
glFogf(GL_FOG_DENSITY, 0.05f); // 设置雾的密度
glHint(GL_FOG_HINT, GL_DONT_CARE); // 设置系统如何计算雾气
glFogf(GL_FOG_START,1600.0f); // 雾气的开始位置
glFogf(GL_FOG_END, 5000.0f); // 雾气的结束位置
currentEnvironment=NIGHT;
return sColor(0.1f, 0.1f, 0.1f, 1.0f);
}
CPlateForm::~CPlateForm()
{
if (hRC)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
}
if (hDC)
{
ReleaseDC(hWnd, hDC);
}
U3D::CResouceManage::getInstance()->~CResouceManage();//析构时有错
U3D::CEngineButton::getInstance()->~CEngineButton();
CEffects::getInstance()->~CEffects();
U3D::CSceneManage::getInstance()->~CSceneManage();
m_Audio.Release();
m_Audio.clear_allMusic();
}
ps:刚毕业的时候对工程的理解不深刻,代码里有很多不规范的地方,比如把游戏的具体逻辑给写道了引擎里去了,这些当时想拆出来的,但是后来工作一忙还没有拆干净也就不了了之了。
ps2:本来想从具体的引擎模块开始写起的,但是发现还是从主入口写会更好理解吧,所以就从平台类开始写了。准备文章写完后就把整个工程传到gitee上去,供大家学习。也可以一起修改,有任何问题都可以加q群716872510大家可以一起交流吹b!