一、 设置像素格式
像素格式用于指定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;
- }