一、 設置像素格式
像素格式用於指定OpenGL繪畫的一些屬性,在windows中,使用PIXELFORMATDESCRIPTOR結構體來描述。一個設備可以支持許多像素格式,但只能擁有一種當前像素格式,需要從這一系列的像素格式中選擇出一種合適的像素格式來,並設置它。主要屬性有:
- 像素緩衝是單緩衝還是雙緩衝;
- 像素數據時RGBA還是顏色索引;
- 顏色數據的位數;
- 深度緩衝的位數;
- 模板緩衝的位數;
- 層的數量;
- 各種可視化掩膜;
代碼片段如下:
1.1 填寫PIXELFORMATDESCRIPTOR結構體
-
static PIXELFORMATDESCRIPTOR pfd= {
-
sizeof(PIXELFORMATDESCRIPTOR),
-
1,
-
PFD_DRAW_TO_WINDOW |
-
PFD_SUPPORT_OPENGL |
-
PFD_DOUBLEBUFFER,
-
PFD_TYPE_RGBA,
-
bits,
-
0, 0, 0, 0, 0, 0,
-
0,
-
0,
-
0,
-
0, 0, 0, 0,
-
16,
-
0,
-
0,
-
PFD_MAIN_PLANE,
-
0,
-
0, 0, 0
-
};
1.2 選擇合適的像素格式
-
-
int iPixelFormat = ChoosePixelFormat(hdc, &pfd);
-
-
if(0 == iPixelFormat)
-
{
-
cerr << "Choose pixel format failed." << endl;
-
...
-
}
1.3 設置像素格式
-
-
if(!SetPixelFormat(hdc, iPixelFormat, &pfd))
-
{
-
cerr << "Set pixel format failed." << endl;
-
...
-
}
注意:必須在創建渲染上下文前設置像素格式。
參考:http://msdn.microsoft.com/en-us/library/dd368832%28v=vs.85%29
二、 創建OpenGL渲染上下文(rendering
context)
每一個調用了OpenGL API的線程都必須要有一個OpenGL渲染上下文,這個渲染上下文用來將OpenGL鏈接到Windwos的窗口系統。
一個線程只能有一個當前渲染上下文,一個渲染上下文只能最爲一個線程的當前上下文。如果調用OpenGL API的線程缺少當前渲染上下文,則不會有任何結果產生。
2.1 創建OpenGL上下文
-
HGLRC hglrc = wglCreateContext(hdc);
-
-
if(!hglrc)
-
{
-
cerr << "Create render contex failed." << endl;
-
…
-
}
2.2 將OpenGL上下文設置爲當前線程的當前上下文
-
if(!wglMakeCurrent(hdc, hglrc))
-
{
-
cerr << "Make current rendering context failed." << endl;
-
…
-
}
如果要清除當前上下文,可以將wglMakeCurrent中的參數設置爲NULL即可。
注意:參數hdc必須和設置像素格式時使用的是同一個hdc。
參考:http://msdn.microsoft.com/en-us/library/dd369038%28v=vs.85%29
三、 顯示OpenGL渲染內容
當前面兩個步驟完成後,就可以使用OpenGL API進行渲染了。這時不再關注具體的渲染上下文,只需調用OpenGL的相應API即可。待渲染完畢,下一步要做的時就是要把它顯示在窗口環境中。因爲Windows下的設備環境使用了雙緩衝的機制,所以這裏就需要交換這兩個緩衝,即可將渲染的內容顯示在窗口中了。具體代碼如下:
四、 銷燬OpenGL上下文
當我們不再進行OpenGL渲染的時候,就可以將OpenGL上下文銷燬了。具體代碼如下:
-
if (hglrc)
-
{
-
-
if (!wglMakeCurrent(NULL,NULL))
-
{
-
cerr << “Release HGLRC failed.” << endl;
-
}
-
-
if (!wglDeleteContext(hglrc))
-
{
-
cerr << "Release Rendering Context Failed.” << endl;
-
}
-
hglrc =NULL;
-
}
附錄
I. 創建窗口
前面說到那麼多,但都沒有說到如何創建顯示OpenGL渲染內容的窗口,下面接着說一下如何創建一個Windows窗口吧。具體代碼如下:
1)註冊WNDCLASS類(結構體)
-
WNDCLASS wc;
-
-
hInstance = GetModuleHandle(NULL);
-
-
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
-
wc.lpfnWndProc = (WNDPROC) WndProc;
-
wc.cbClsExtra = 0;
-
wc.cbWndExtra = 0;
-
wc.hInstance = hInstance;
-
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
-
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
-
wc.hbrBackground = NULL;
-
wc.lpszMenuName = NULL;
-
wc.lpszClassName = "OpenGL";
-
-
if (!RegisterClass(&wc))
-
{
-
cerr << “Failed to register the window.” << endl;
-
…
-
}
2)創建窗口
-
HWND hWnd = CreateWindow("OpenGL", "Hello World.",
-
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW,
-
0, 0, 100, 100, NULL, NULL, GetModuleHandle(NULL), 0);
-
if(!hWnd)
-
{
-
cerr << “Create window failed.” << endl;
-
…
-
}
-
-
ShowWindow(hWnd, SW_SHOW);
Ⅱ. 銷燬窗口
當不再需要該窗口時,需要對其進行銷燬,步驟如下:
-
if (hdc && !ReleaseDC(hWnd,hdc))
-
{
-
cerr << "Release Device Context Failed." << endl;
-
hdc = NULL;
-
}
-
-
if (hWnd && !DestroyWindow(hWnd))
-
{
-
cerr << "Could Not Release hWnd." << endl;
-
hWnd=NULL;
-
}
-
-
if (!UnregisterClass("OpenGL",hInstance))
-
{
-
cerr << "Could Not Unregister Class." << endl;
-
hInstance=NULL;
-
}