?? base.cpp
字號:
/*
* 這些代碼是由Jeff Molofee 與2000年寫的,再次我必須感謝Fredric Echols,因為他使這些代碼看起來更簡潔和高效,并使他易于使用。
* 如果你發(fā)現(xiàn)這些代碼對你有所幫助,請訪問我的站點 http://nehe.gamedev.net/default.asp ,并讓我知道。
*********************************************************************************************************************************
* 這份文檔是由DancingWind翻譯的,如果有什么錯誤請e-mail:zhouwei02@mails.tsinghua.edu.cn
*/
/*********************包含鏈接的庫文件*******************************************************************************************/
#pragma comment( lib, "opengl32.lib" )
#pragma comment( lib, "glu32.lib" )
#pragma comment( lib, "glut32.lib")
#pragma comment( lib, "glew32.lib")
#pragma comment( lib, "glaux.lib")
#pragma comment( lib, "vfw32.lib" )
/********************************************************************************************************************************/
#include <windows.h> // Windows的頭文件
//#include "glew.h" // 包含最新的gl.h,glu.h庫
#include "glut.h" // 包含OpenGL實用庫
HDC hDC=NULL; // 窗口著色描述表句柄
HGLRC hRC=NULL; // OpenGL渲染描述表句柄
HWND hWnd=NULL; // 保存我們的窗口句柄
HINSTANCE hInstance; // 保存程序的實例
bool keys[256]; // 保存鍵盤按鍵的數(shù)組
bool active=TRUE; // 窗口的活動標志,缺省為TRUE
bool fullscreen=TRUE; // 全屏標志缺省,缺省設(shè)定成全屏模式
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // WndProc的定義
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // 重置OpenGL窗口大小
{
if (height==0) // 防止被零除
{
height=1; // 將Height設(shè)為1
}
glViewport(0,0,width,height); // 重置當前的視口
glMatrixMode(GL_PROJECTION); // 選擇投影矩陣
glLoadIdentity(); // 重置投影矩陣
// 設(shè)置視口的大小
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // 選擇模型觀察矩陣
glLoadIdentity(); // 重置模型觀察矩陣
}
int InitGL(GLvoid) // 此處開始對OpenGL進行所有設(shè)置
{
glShadeModel(GL_SMOOTH); // 啟用陰影平滑
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // 黑色背景
glClearDepth(1.0f); // 設(shè)置深度緩存
glEnable(GL_DEPTH_TEST); // 啟用深度測試
glDepthFunc(GL_LEQUAL); // 所作深度測試的類型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 告訴系統(tǒng)對透視進行修正
return TRUE; // 初始化 OK
}
int DrawGLScene(GLvoid) // 從這里開始進行所有的繪制
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度緩存
glLoadIdentity(); // 重置當前的模型觀察矩陣
return TRUE; // 一切 OK
}
GLvoid KillGLWindow(GLvoid) // 正常銷毀窗口
{
if (fullscreen) // 我們處于全屏模式嗎?
{
ChangeDisplaySettings(NULL,0); // 是的話,切換回桌面
ShowCursor(TRUE); // 顯示鼠標指針
}
if (hRC) //我們擁有OpenGL描述表嗎?
{
if (!wglMakeCurrent(NULL,NULL)) // 我們能否釋放DC和RC描述表?
{
MessageBox(NULL,"釋放DC或RC失敗。","關(guān)閉錯誤",MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // 我們能否刪除RC?
{
MessageBox(NULL,"釋放RC失敗。","關(guān)閉錯誤",MB_OK | MB_ICONINFORMATION);
}
hRC=NULL; // 將RC設(shè)為 NULL
}
if (hDC && !ReleaseDC(hWnd,hDC)) // 我們能否釋放 DC?
{
MessageBox(NULL,"釋放DC失敗。","關(guān)閉錯誤",MB_OK | MB_ICONINFORMATION);
hDC=NULL; // 將 DC 設(shè)為 NULL
}
if (hWnd && !DestroyWindow(hWnd)) // 能否銷毀窗口?
{
MessageBox(NULL,"釋放窗口句柄失敗。","關(guān)閉錯誤",MB_OK | MB_ICONINFORMATION);
hWnd=NULL; // 將 hWnd 設(shè)為 NULL
}
if (!UnregisterClass("OpenG",hInstance)) // 能否注銷類?
{
MessageBox(NULL,"不能注銷窗口類。","關(guān)閉錯誤",MB_OK | MB_ICONINFORMATION);
hInstance=NULL; // 將 hInstance 設(shè)為 NULL
}
}
/* 這個函數(shù)創(chuàng)建我們OpenGL窗口,參數(shù)為: *
* title - 窗口標題 *
* width - 窗口寬度 *
* height - 窗口高度 *
* bits - 顏色的位深(8/16/32) *
* fullscreenflag - 是否使用全屏模式,全屏模式(TRUE),窗口模式(FALSE) */
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat; // 保存查找匹配的結(jié)果
WNDCLASS wc; // 窗口類結(jié)構(gòu)
DWORD dwExStyle; // 擴展窗口風格
DWORD dwStyle; // 窗口風格
RECT WindowRect; // 取得矩形的左上角和右下角的坐標值
WindowRect.left=(long)0; // 將Left 設(shè)為 0
WindowRect.right=(long)width; // 將Right 設(shè)為要求的寬度
WindowRect.top=(long)0; // 將Top 設(shè)為 0
WindowRect.bottom=(long)height; // 將Bottom 設(shè)為要求的高度
fullscreen=fullscreenflag; // 設(shè)置全局全屏標志
hInstance = GetModuleHandle(NULL); // 取得我們窗口的實例
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // 移動時重畫,并為窗口取得DC
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc處理消息
wc.cbClsExtra = 0; // 無額外窗口數(shù)據(jù)
wc.cbWndExtra = 0; // 無額外窗口數(shù)據(jù)
wc.hInstance = hInstance; // 設(shè)置實例
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // 裝入缺省圖標
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 裝入鼠標指針
wc.hbrBackground = NULL; // GL不需要背景
wc.lpszMenuName = NULL; // 不需要菜單
wc.lpszClassName = "OpenG"; // 設(shè)定類名字
if (!RegisterClass(&wc)) // 嘗試注冊窗口類
{
MessageBox(NULL,"注冊窗口失敗","錯誤",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // 退出并返回FALSE
}
if (fullscreen) // 要嘗試全屏模式嗎?
{
DEVMODE dmScreenSettings; // 設(shè)備模式
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // 確保內(nèi)存清空為零
dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Devmode 結(jié)構(gòu)的大小
dmScreenSettings.dmPelsWidth = width; // 所選屏幕寬度
dmScreenSettings.dmPelsHeight = height; // 所選屏幕高度
dmScreenSettings.dmBitsPerPel = bits; // 每象素所選的色彩深度
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
// 嘗試設(shè)置顯示模式并返回結(jié)果。注: CDS_FULLSCREEN 移去了狀態(tài)條
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
// 若模式失敗,提供兩個選項:退出或在窗口內(nèi)運行。
if (MessageBox(NULL,"全屏模式在當前顯卡上設(shè)置失敗!\n使用窗口模式?","NeHe G",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
//如果用戶選擇窗口模式,變量fullscreen 的值變?yōu)镕ALSE,程序繼續(xù)運行
fullscreen=FALSE; // 選擇窗口模式(Fullscreen=FALSE)
}
else
{
//如果用戶選擇退出,彈出消息窗口告知用戶程序?qū)⒔Y(jié)束。并返回FALSE告訴程序窗口未能成功創(chuàng)建。程序退出。
MessageBox(NULL,"程序?qū)⒈魂P(guān)閉","錯誤",MB_OK|MB_ICONSTOP);
return FALSE; // 退出并返回 FALSE
}
}
}
if (fullscreen) // 仍處于全屏模式嗎?
{
dwExStyle=WS_EX_APPWINDOW; // 擴展窗體風格
dwStyle=WS_POPUP; // 窗體風格
ShowCursor(FALSE); // 隱藏鼠標指針
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // 擴展窗體風格
dwStyle=WS_OVERLAPPEDWINDOW; // 窗體風格
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // 調(diào)整窗口達到真正要求的大小
// 創(chuàng)建窗口
if (!(hWnd=CreateWindowEx( dwExStyle, // 擴展窗體風格
"OpenG", // 類名字
title, // 窗口標題
dwStyle | // 必須的窗體風格屬性
WS_CLIPSIBLINGS | // 必須的窗體風格屬性
WS_CLIPCHILDREN, // 必須的窗體風格屬性
0, 0, // 窗口位置
WindowRect.right-WindowRect.left, // 計算調(diào)整好的窗口寬度
WindowRect.bottom-WindowRect.top, // 計算調(diào)整好的窗口高度
NULL, // 無父窗口
NULL, // 無菜單
hInstance, // 實例
NULL))) // 不向WM_CREATE傳遞任何東東
{
KillGLWindow(); // 重置顯示區(qū)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -