这个引擎是基于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;
//#endifreturn 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 |           // 格式必须支持OpenGLPFD_DOUBLEBUFFER,                // 必须支持双缓冲PFD_TYPE_RGBA,                    // 申请 RGBA 格式24,                                // 选定色彩深度0, 0, 0, 0, 0, 0,              // 忽略的色彩位0,                             // 无Alpha缓存0,                               // 忽略Shift Bit0,                                // 无累加缓存0, 0, 0, 0,                     // 忽略聚集位16,                             // 16位 Z-缓存 (深度缓存)1,                                // 无蒙板缓存0,                              // 无辅助缓存PFD_MAIN_PLANE,                 // 主绘图层0,                               // Reserved0, 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);                                       //蒙版缓冲区置为0glShadeModel(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_rightVector3D 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());elseU3D::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());elseU3D::CSceneManage::getInstance()->pause(updateTime());godCamera->drawFrustum();if (Fog)glEnable(GL_FOG);elseglDisable(GL_FOG);///右边2dglViewport(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);elseglPolygonMode(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.0fenum 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 旋转:3int 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; //计算FPSdwRenderedFrame = 0;}dwRenderedFrame++;return fps;
}GLboolean CPlateForm::InitGL(GLvoid)                       // 此处开始对OpenGL进行所有设置
{static PIXELFORMATDESCRIPTOR pfd =        // /pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式{sizeof(PIXELFORMATDESCRIPTOR),       // 上述格式描述符的大小1,                             // 版本号PFD_DRAW_TO_WINDOW |          // 格式支持窗口PFD_SUPPORT_OPENGL |           // 格式必须支持OpenGLPFD_DOUBLEBUFFER,                // 必须支持双缓冲PFD_TYPE_RGBA,                    // 申请 RGBA 格式24,                                // 选定色彩深度0, 0, 0, 0, 0, 0,              // 忽略的色彩位0,                             // 无Alpha缓存0,                               // 忽略Shift Bit0,                                // 无累加缓存0, 0, 0, 0,                     // 忽略聚集位16,                             // 16位 Z-缓存 (深度缓存)1,                                // 无蒙板缓存0,                              // 无辅助缓存PFD_MAIN_PLANE,                 // 主绘图层0,                               // Reserved0, 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);                                   //蒙版缓冲区置为0glShadeModel(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')//如果存在返回Truereturn 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;
//#endifreturn 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 intcase 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_rightVector3D 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());elseU3D::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());elseU3D::CSceneManage::getInstance()->pause(updateTime());godCamera->drawFrustum();if (Fog)glEnable(GL_FOG);elseglDisable(GL_FOG);///右边2dglViewport(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);elseglPolygonMode(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!

从0开发游戏引擎之引擎Win32平台的Platform类实现相关推荐

  1. Windows Embedded CE 6.0开发初体验(六)平台定制

    Windows CE是一个组件化的操作系统,我们可以根据不同的环境设置不同的组件来组合成有针对性的平台,而一个功能往往需要多个组件才能够实现.Catalog就是实现某个功能的组件集合,每个Catalo ...

  2. 从0开发游戏引擎之引擎基础组件-Node类实现

    基类是设计模式中的模板方法模式,主要存放了一些通用的代码. 当时使用了U2D和U3D把2D UI和3D UI给区分开了,基类里面存放的主要的是本地矩阵和世界矩阵,角度.锚点.缩放.z顺序等. Node ...

  3. 从0开发游戏引擎之游戏引擎中2D序列帧动画控制器的实现

    这种序列帧动画要求每一帧的宽高必须一一致,否则动画播起来会出问题. 需要的图片类似图1.1 会把所有的动作拼接到一张图上,这样做也是为了节省内存和减少DrawCall,切换动作的时候只需要重新计算图片 ...

  4. cocos2d-x3.0开发游戏部分机型(显卡类型)闪退问题

    拓展cocos2d-x3.0底层支持etc图片格式,把游戏中的模型使用etc格式的图片替换. 原先可以运行在联想(lenovo S880,显卡类型是PowerVP SGX 531)的机器上,但是换成e ...

  5. 使用Visual Studio开发游戏——微软宣布与Unity、Unreal Engine和Cocos展开全新合作

    从Xbox.Windows,到iOS.安卓,再到浏览器平台,每天都有数以亿计的用户在这些设备上运行由游戏开发者设计和开发的游戏.多年以来,我们很荣幸的看到,Visual Studio一直是游戏行业最流 ...

  6. 十五开源的Andr​​oid(2D或3D)Android开发游戏引擎

    Android游戏开发Android游戏引擎是非常有用的,这里是10个开源的Andr​​oid(2D或3D)Android开发的游戏引擎. 1.  Rokon:Android的开源2D游戏引擎 Rok ...

  7. 元宇宙开发:你在虚幻引擎中的第一个虚拟现实游戏

    了解如何开发零编程背景的Oculus Quest游戏 你会学到什么 为Oculus Quest构建应用程序 设计和开发虚拟现实游戏 在虚幻引擎中工作 使用材料和纹理 优化内容,实现移动和虚拟现实游戏的 ...

  8. 用函数式编程,从0开发3D引擎和编辑器(三):初步需求分析

    大家好,本文介绍了Wonder的高层需求和本系列对应的具体功能点. 确定Wonder高层需求 业务目标 Wonder是web端3D开发的解决方案,包括引擎.编辑器,致力于打造开放.分享.互助的生态. ...

  9. GJM : 各大开发游戏引擎

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

最新文章

  1. 浅析Spring——控制反转IoC
  2. 在有序但含有空的数组中查找字符串
  3. 用 Hadoop 进行分布式并行编程, 第 1 部分 基本概念与安装部署
  4. JavaScript或jQuery中使用键盘控制对象运动
  5. 用xshell传输jdk_在JDK 9中将InputStream传输到OutputStream
  6. java获取系统当前时间格式化_java 获取系统当前时间并格式化
  7. 什么是 Python?我介绍我几年前学习Python的方法和经验
  8. pyqt stop停止线程_面试阿里,字节跳动,腾讯90%都会被问到如何终止线程?有几种方式?你都知道吗?...
  9. 图像处理-RGB彩色图像均衡化处理
  10. Vue脚手架组件开发常见问题
  11. 【精讲】软件工程用图的各个阶段及其应用(详细)系统流程图、数据流图、数据字典、ER图、状态转换图、层次方框图、Warnier图、IPO图、层次图、HIPO图、结构图、程序流程图、盒图等
  12. 伺服驱动系统的电磁干扰问题
  13. 刀塔霸业怎么在电脑上玩 刀塔霸业电脑版玩法教程
  14. linux 命令:du 详解
  15. 一位高人隐士传授的炼精化气秘法 透彻之极!
  16. 如何生成带标高的西安80坐标系等高线
  17. 设计一款主动降噪(ANC)耳机
  18. content provider nullpoint
  19. Studio3T 无限破解 (2019.3.0.0)
  20. 手机6120C 玩仙剑dos版

热门文章

  1. 该怎么回答面试官问“你有什么优缺点?”
  2. Kali Linux 详细安装步骤
  3. vue 页面跳转路由 不显示内容Component inside <Transition> renders non-element root node that cannot be animated.
  4. Windows 10 “无法打开这个应用” 应用出现问题,应该怎么解决?
  5. 常用网络测试软件,常用的网络故障检测工具有哪些
  6. JSP+Servlet实现BMI计算器
  7. 盐于律己,甜以待人(*╹▽╹*)
  8. 一文掌握常见常用Java集合框架
  9. 规范化:范式(主属性,非主属性,1NF,2NF,3NF,BCNF:定义,例子等)
  10. NandFlash驱动移植基础知识