?? glframe.cpp
字號:
//======================================================================
/**
* @file GLFrame.cpp
*
* 項目描述: 3DS文件載入
* 文件描述: 鍵盤類和程序框架類
* 適用平臺: Windows98/2000/NT/XP
*
* 作者: WWBOSS
* 電子郵件: wwboss123@gmail.com
* 創建日期: 2006-09-13
* 修改日期: 2006-10-10
*
* 你必須在你的繼承類中完成以下函數的實現
*
* GLApplication * GLApplication::Create(const char * class_name)
* 創建你的子類的一個實例
*
* bool Init();
* 執行所有的初始化工作,如果成功函數返回true
*
* void Uninit();
* 執行所有的卸載工作
*
* void Update(DWORD milliseconds);
* 執行所有的更新操作,傳入的參數為兩次操作經過的時間,以毫秒為單位
*
* void Draw();
* 執行所有的繪制操作
*/
//======================================================================
#include "stdafx.h"
#include "GLFrame.h" /**< 包含GLFrame.h頭文件 */
/** 主程序入口 */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int ret = -1;
GLApplication * appl = GLApplication::Create("OpenGL"); /**< 創建程序類 */
if (appl != 0)
{
ret = appl->Main(hInstance, hPrevInstance, lpCmdLine, nCmdShow);/**< 執行程序主循環 */
delete appl; /**< 刪除程序類(在繼承類中,使用GL_Example * example = new GL_Example(class_name);分配了一塊內存)*/
}
else
{ /**< 創建程序出錯 */
MessageBox(HWND_DESKTOP, "創建程序出錯", "Error", MB_OK | MB_ICONEXCLAMATION);
}
return ret;
}
/** 處理窗口消息 */
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LONG user_data = GetWindowLong(hWnd, GWL_USERDATA); /**< 返回用戶自定義的32位的程序附加值 */
if (user_data == 0)
{
/// 如果程序第一次運行
if (uMsg == WM_CREATE) /**< 處理窗口創建消息 */
{
/// 返回窗口結構的指針,它保存剛創建的程序實例的類
CREATESTRUCT * creation = reinterpret_cast<CREATESTRUCT *>(lParam);
/// 獲得程序實例的指針
GLApplication * appl = reinterpret_cast<GLApplication *>(creation->lpCreateParams);
/// 保存程序實例的指針為用戶自定義的程序附加值
SetWindowLong(hWnd, GWL_USERDATA, reinterpret_cast<LONG>(appl));
appl->m_IsVisible = true; /**< 設置程序可見 */
return 0; /**< 返回 */
}
}
else
{
/// 如果不是第一次窗口,返回程序實例的指針
GLApplication * appl = reinterpret_cast<GLApplication *>(user_data);
return appl->Message(hWnd, uMsg, wParam, lParam); /**< 調用程序實例自己的消息處理函數 */
}
return DefWindowProc(hWnd, uMsg, wParam, lParam); /**< 調用默認的窗口消息處理函數 */
}
/** 構造函數 */
GLApplication::GLApplication(const char * class_name)
{
m_ClassName = class_name; /**< 保存類名 */
m_IsProgramLooping = true; /**< 設置程序循環為true */
m_CreateFullScreen = true; /**< 使用全屏模式 */
m_IsVisible = false; /**< 不可見 */
m_ResizeDraw = false; /**< 在窗口改變大小的時候,不可繪制 */
m_LastTickCount = 0;
}
void GLApplication::ToggleFullscreen() /**< 切換 全屏/窗口模式 */
{
PostMessage(m_Window, WM_TOGGLEFULLSCREEN, 0, 0); /**< 發送自定的切換消息 */
}
void GLApplication::TerminateApplication() /**< 結束程序 */
{
PostMessage(m_Window, WM_QUIT, 0, 0); /**< 發送退出消息 */
m_IsProgramLooping = false; /**< 停止程序循環 */
}
/** 消息循環 */
LRESULT GLApplication::Message(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) /**< 處理不同的Windows消息 */
{
case WM_SYSCOMMAND: /**< 截獲系統命令 */
switch (wParam)
{
case SC_SCREENSAVE: /**< 截獲屏幕保護啟動命令 */
case SC_MONITORPOWER: /**< 截獲顯示其省電模式啟動命令 */
return 0; /**< 不啟用這兩個命令 */
break;
}
break; /**< 退出 */
case WM_CLOSE: /**< 關閉窗口 */
TerminateApplication(); /**< 調用TerminateApplication函數 */
return 0;
break;
case WM_EXITMENULOOP:
case WM_EXITSIZEMOVE:
m_LastTickCount = GetTickCount(); /**< 更新計數器的值 */
return 0;
break;
case WM_MOVE:
m_Window.SetPosX(LOWORD(lParam)); /**< 更新鼠標的坐標 */
m_Window.SetPosY(HIWORD(lParam));
return 0;
break;
case WM_PAINT:
if (m_ResizeDraw == true) /**< 如果需要重繪 */
{
m_Window.ReshapeGL(); /**< 重新設置窗口的大小 */
Draw(); /**< 重新繪制 */
m_Window.SwapBuffers(); /**< 交換前后幀緩存 */
}
break;
case WM_SIZING: /**< 窗口正在改變大小 */
{
RECT * rect = (RECT *)lParam;
m_Window.SetWidth(rect->right - rect->left); /**< 設置窗口寬度 */
m_Window.SetHeight(rect->bottom - rect->top); /**< 設置窗口高度 */
return TRUE;
}
break;
case WM_SIZE: /**< 窗口改變大小后 */
switch (wParam) /**< 處理不同的窗口狀態 */
{
case SIZE_MINIMIZED: /**< 是否最小化? */
m_IsVisible = false; /**< 如果是,則設置不可見 */
return 0;
break;
case SIZE_MAXIMIZED: /**< 窗口是否最大化? */
case SIZE_RESTORED: /**< 窗口被還原? */
m_IsVisible = true; /**< 設置為可見 */
m_Window.SetWidth(LOWORD(lParam)); /**< 設置窗口寬度 */
m_Window.SetHeight(HIWORD(lParam)); /**< 設置窗口高度 */
m_Window.ReshapeGL(); /**< 改變窗口大小 */
m_LastTickCount = GetTickCount(); /**< 更新計數器的值 */
return 0;
break;
}
break;
case WM_KEYDOWN: /**< 更新按鍵信息 */
m_Keys.SetPressed(wParam);
return 0;
break;
case WM_KEYUP: /**< 更新釋放鍵信息 */
m_Keys.SetReleased(wParam);
return 0;
break;
case WM_TOGGLEFULLSCREEN: /**< 切換 全屏/窗口模式 */
m_CreateFullScreen = !m_CreateFullScreen;
PostMessage(hWnd, WM_QUIT, 0, 0);
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam); /**< 調用默認的窗口消息處理函數 */
}
/** 程序的主循環 */
int GLApplication::Main(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
/// 注冊一個窗口
WNDCLASSEX windowClass; /**< 窗口類 */
ZeroMemory(&windowClass, sizeof(WNDCLASSEX)); /**< 清空結構為0 */
windowClass.cbSize = sizeof(WNDCLASSEX); /**< 窗口結構的大小 */
windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; /**< 設置窗口類型為,移動時重畫,并為窗口取得DC */
windowClass.lpfnWndProc = (WNDPROC)(WindowProc); /**< WndProc處理消息 */
windowClass.hInstance = hInstance; /**< 設置實例 */
windowClass.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE); /**< 設置背景 */
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); /**< 載入光標 */
windowClass.lpszClassName = m_ClassName; /**< 設置類名 */
if (RegisterClassEx(&windowClass) == 0) /**< 嘗試注冊窗口類 */
{ /**< NOTE: Failure, Should Never Happen */
MessageBox(HWND_DESKTOP, "注冊窗口失敗!", "Error", MB_OK | MB_ICONEXCLAMATION);
return -1; /**< 退出并返回FALSE */
}
// 詢問是否在全屏狀態下運行?
if (MessageBox(HWND_DESKTOP, "你想在全屏狀態下運行么 ?", "設置運行模式", MB_YESNO | MB_ICONQUESTION) == IDNO)
{
m_CreateFullScreen = false; /**< m_CreateFullScreen記錄當前的顯示模式為窗口 */
}
while (m_IsProgramLooping) /**< 循環直到WM_QUIT退出程序 */
{
/// 創建一個窗口
if (m_Window.Create("OpenGL 3D游戲編程——3DS文件載入", m_ClassName,m_CreateFullScreen, hInstance, this) == true)
{
/// 如果初始化失敗,則退出
if (Init() == false) /**< 調用自定義的初始化函數 */
{ /**< 失敗 */
TerminateApplication(); /**< 關閉窗口退出程序 */
}
else /**< 成功開始消息循環 */
{
MSG msg; /**< Window消息結構 */
bool isMessagePumpActive = true; /**< 當消息不為空時,處理消息循環 */
m_LastTickCount = GetTickCount(); /**< 返回當前的計時器的值 */
m_Keys.Clear(); /**< 清空所有的按鍵信息 */
while (isMessagePumpActive == true) /**< 當消息不為空時,處理消息循環 */
{ /**< 成功創建窗口,檢測窗口消息 */
if (PeekMessage(&msg, m_Window, 0, 0, PM_REMOVE) != 0)
{
/// 檢測是否為WM_QUIT消息
if (msg.message != WM_QUIT)
{
DispatchMessage(&msg); /**< 如果不是發送消息到消息回調函數中處理 */
}
else
{
isMessagePumpActive = false; /**< 如果是,則退出 */
}
}
/// 如果沒有消息
else
{
if (m_IsVisible == false) /**< 如果窗口不可見 */
{
WaitMessage(); /**< 暫停程序,等待消息 */
}
else /**< 如果窗口可見 */
{ /**< 執行消息循環 */
DWORD tickCount = GetTickCount(); /**< 返回計時器的當前值 */
Update(tickCount - m_LastTickCount); /**< 調用用戶自定義的更新函數 */
m_LastTickCount = tickCount; /**< 重新設置上一次,計數器的值 */
Draw(); /**< 調用用戶自定義的繪制函數 */
m_Window.SwapBuffers(); /**< 交換前后幀緩存 */
}
}
} /**< 如果isMessagePumpActive == true,則循環 */
}
/**< 程序結束 */
Uninit(); /**< 用戶自定義的卸載函數 */
m_Window.Destroy(); /**< 刪除窗口 */
}
else /**< 如果創建窗口失敗 */
{
MessageBox(HWND_DESKTOP, "創建OpenGL窗口錯誤", "Error", MB_OK | MB_ICONEXCLAMATION);
m_IsProgramLooping = false; /**< 停止程序循環 */
}
}
UnregisterClass(m_ClassName, hInstance); /**< 取消注冊的窗口 */
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -