在這個教程裏,我們一起來玩第一個OpenGL程序.它將顯示一個空的OpenGL窗口,可以在窗口和全屏模式下切換,按ESC退出.它是我們以後應用程序的框架.
在CodeBlock裏創建一個新的GLUT
Win32程序(不是console控制檯程序)後,我們還需要鏈接OpenGL庫文件。
代碼的前4行包括了我們使用的每個庫文件的頭文件。如下所示:
#include
<windows.h> // Windows的頭文件
#include <glew.h> //
包含最新的gl.h,glu.h庫
#include <glut.h> //
包含OpenGL實用庫
接下來需要設置使用的所有變量。本節中的例程將創建一個空的OpenGL窗口,因此我們暫時還無需設置大堆的變量。餘下需要設置的變量不多,但十分重要。幾乎所寫的每一個OpenGL程序中都會用到它們。
第一行設置的變量是Rendering
Context(着色描述表)。每一個OpenGL都被連接到一個着色描述表上。着色描述表將所有的OpenGL調用命令連接到Device
Context(設備描述表)上。我將OpenGL的着色描述表定義爲 hRC
。要讓程序能夠繪製窗口的話,還需要創建一個設備描述表,也就是第二行的內容。Windows的設備描述表被定義爲 hDC 。DC將窗口連接到GDI(Graphics
Device Interface圖形設備接口)。而RC將OpenGL連接到DC。第三行的變量 hWnd
將保存由Windows給我們的窗口指派的句柄。最後,第四行爲我們的程序創建了一個Instance(實例)。
HGLRC
hRC=NULL;// 窗口着色描述表句柄
HDC hDC=NULL;//
OpenGL渲染描述表句柄
HWND hWnd=NULL;// 保存我們的窗口句柄
HINSTANCE
hInstance;// 保存程序的實例
bool keys[256];// 保存鍵盤按鍵的數組
bool active=TRUE;//
窗口的活動標誌,缺省爲TRUE
bool fullscreen=TRUE;//
全屏標誌缺省,缺省設定成全屏模式
下面的代碼的作用是重新設置OpenGL場景的大小,而不管窗口的大小是否已經改變(假定您沒有使用全屏模式)。OpenGL場景的尺寸將被設置成它顯示時所在窗口的大小。
GLvoid
ReSizeGLScene(GLsizei width, GLsizei height){
if (height==0) //
防止被零除
{
height=1;// 將Height設爲1
}
glViewport(0, 0, width, height);//
重置當前的視口
glMatrixMode(GL_PROJECTION);// 選擇投影矩陣
glLoadIdentity();//
重置投影矩陣
//
設置視口的大小
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);//
選擇模型觀察矩陣
glLoadIdentity();//
重置模型觀察矩陣}
接下的代碼段中,我們將對OpenGL進行所有的設置。我們將設置清除屏幕所用的顏色,打開深度緩存,啓用smooth
shading(陰影平滑),等等。
int InitGL(GLvoid)//
此處開始對OpenGL進行所有設置{
glShadeModel(GL_SMOOTH);// 啓用陰影平滑
glClearColor(0.0f,
0.0f, 0.0f, 0.0f); // 黑色背景
glClearDepth(1.0f); //
設置深度緩存
glEnable(GL_DEPTH_TEST); // 啓用深度測試
glDepthFunc(GL_LEQUAL); //
所作深度測試的類型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //
告訴系統對透視進行修正
return TRUE; // 初始化
OK
}
下一段包括了所有的繪圖代碼。任何所想在屏幕上顯示的東東都將在此段代碼中出現。
int DrawGLScene(GLvoid)//
從這裏開始進行所有的繪製
{ // 清除屏幕和深度緩存
glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT);
glLoadIdentity(); // 重置當前的模型觀察矩陣
return TRUE; // 一切
OK
}
下面是我們的Windows程序的入口。將會調用窗口創建例程,處理窗口消息,並監視人機交互。
int WINAPI
WinMain(HINSTANCE hInstance,// 當前窗口實例
HINSTANCE hPrevInstance,//
前一個窗口實例
LPSTR lpCmdLine,// 命令行參數
int nCmdShow) //
窗口顯示狀態
{
創建OpenGL窗口
if
(!CreateGLWindow("OpenGL程序框架",640,480,16,fullscreen))
{
return 0; //
失敗退出
}
下面是循環的開始。只要done保持FALSE,循環一直進行。
保持循環直到 done=TRUE
while(!done)
{
我們要做的第一件事是檢查是否有消息在等待。使用PeekMessage()可以在不鎖住我們的程序的前提下對消息進行檢查。許多程序使用GetMessage(),也可以很好的工作。但使用GetMessage(),程序在收到paint消息或其他別的什麼窗口消息之前不會做任何事。
//有消息在等待嗎?
if
(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
下面的代碼查看是否出現退出消息。如果當前的消息是由PostQuitMessage(0)引起的WM_QUIT,done變量被設爲TRUE,程序將退出。
// 收到退出消息?
if
(msg.message==WM_QUIT)
{
done=TRUE; // 是,則done=TRUE
}
else
{
// 不是,處理窗口消息
如果不是退出消息,我們翻譯消息,然後發送消息,使得WndProc() 或
Windows能夠處理他們。
TranslateMessage(&msg); //
翻譯消息
DispatchMessage(&msg); // 發送消息
}
}
else // 如果沒有消息
{
如果沒有消息,繪製我們的OpenGL場景。代碼的第一行查看窗口是否激活。如果按下ESC鍵,done變量被設爲TRUE,程序將會退出。
//
繪製場景。監視ESC鍵和來自DrawGLScene()的退出消息
if (active) // 程序激活的麼?
{
if
(keys[VK_ESCAPE]) // ESC 按下了麼?
{
done=TRUE; // ESC 發出退出信號
}
else //
不是退出的時候,刷新屏幕
{
如果程序是激活的且ESC沒有按下,我們繪製場景並交換緩存(使用雙緩存可以實現無閃爍的動畫)。我們實際上在另一個看不見的"屏幕"上繪圖。當我們交換緩存後,我們當前的屏幕被隱藏,現在看到的是剛纔看不到的屏幕。這也是我們看不到場景繪製過程的原因。場景只是即時顯示。
DrawGLScene(); //
繪製場景
SwapBuffers(hDC); // 交換緩存 (雙緩存)
}
}
}
如果done變量不再是FALSE,程序退出。正常銷燬OpenGL窗口,將所有的內存釋放,退出程序。
// 關閉程序
KillGLWindow(); //
銷燬窗口
return (msg.wParam); // 退出程序
}
在這一課中,詳細解釋了所有的基本步驟。每一步都與設置有關,並創建了一個全屏OpenGL程序。這是框架,幾乎每個OpenGL程序都會用到這些步驟。
歡迎大家繼續關注更多內容
身爲一名IT技術人員磨練自己的技術是必不可少的,關注微信號coder_online,程序員互動聯盟,可以與大牛在線隨時討論自己感興趣的話題,讓自己用最少的時間學到最多的東西,掃一掃下方二維碼或者搜索微信號coder_online即可關注。
摘自:http://my.oschina.net/coderonline/blog/403202