小菜學Chromium之OpenGL學習之二


在這個教程裏,我們一起來玩第一個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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章