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,还实现了输入控制器的刷新。
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(); }
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上去,供大家学习。