Windows下创建OpenGL窗口

本文详细介绍了在Windows操作系统中创建OpenGL窗口的步骤,包括设置像素格式、创建OpenGL渲染上下文、显示渲染内容以及销毁上下文。重点讲解了PIXELFORMATDESCRIPTOR结构体的使用,渲染上下文的创建和设置,以及窗口的创建和销毁过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、     设置像素格式

像素格式用于指定OpenGL绘画的一些属性,在windows中,使用PIXELFORMATDESCRIPTOR结构体来描述。一个设备可以支持许多像素格式,但只能拥有一种当前像素格式,需要从这一系列的像素格式中选择出一种合适的像素格式来,并设置它。主要属性有:

  •  像素缓冲是单缓冲还是双缓冲;
  •  像素数据时RGBA还是颜色索引;
  •  颜色数据的位数;
  •  深度缓冲的位数;
  •  模板缓冲的位数;
  •  层的数量;
  •  各种可视化掩膜;

 

代码片段如下:

1.1  填写PIXELFORMATDESCRIPTOR结构体

static PIXELFORMATDESCRIPTOR pfd=	{
	sizeof(PIXELFORMATDESCRIPTOR),	// Size Of This Pixel Format Descriptor
	1,								// Version Number
	PFD_DRAW_TO_WINDOW |			// Format Must Support Window
	PFD_SUPPORT_OPENGL |			// Format Must Support OpenGL
	PFD_DOUBLEBUFFER,				// Must Support Double Buffering
	PFD_TYPE_RGBA,					// Request An RGBA Format
	bits,							// Select Our Color Depth
	0, 0, 0, 0, 0, 0,				// Color Bits Ignored
	0,								// No Alpha Buffer
	0,								// Shift Bit Ignored
	0,								// No Accumulation Buffer
	0, 0, 0, 0,						// Accumulation Bits Ignored
	16,								// 16Bit Z-Buffer (Depth Buffer)  
	0,								// No Stencil Buffer
	0,								// No Auxiliary Buffer
	PFD_MAIN_PLANE,					// Main Drawing Layer
	0,								// Reserved
	0, 0, 0							// Layer Masks Ignored
};


 

1.2  选择合适的像素格式

// get the best available match of pixel format for the device context
int  iPixelFormat = ChoosePixelFormat(hdc, &pfd);

if(0 == iPixelFormat)
{
    cerr << "Choose pixel format failed." << endl;
    ...
}


 

1.3  设置像素格式

// make that the pixel format of the device context
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下的设备环境使用了双缓冲的机制,所以这里就需要交换这两个缓冲,即可将渲染的内容显示在窗口中了。具体代码如下:

SwapBuffers(hdc);   // hdc需和前面两个步骤中的hdc相同


 

四、     销毁OpenGL上下文

当我们不再进行OpenGL渲染的时候,就可以将OpenGL上下文销毁了。具体代码如下:

if (hglrc)     // Do We Have A Rendering Context?
{
    // Are We Able To Release The DC And RC Contexts?
	if (!wglMakeCurrent(NULL,NULL))	
{
	    cerr << “Release HGLRC failed.” << endl;
	}

	if (!wglDeleteContext(hglrc))  // Are We Able To Delete The HGLRC?
	{
		cerr << "Release Rendering Context Failed.” << endl;
	}
	hglrc =NULL;	 // Set RC To NULL
}


 

附录

I.        创建窗口

前面说到那么多,但都没有说到如何创建显示OpenGL渲染内容的窗口,下面接着说一下如何创建一个Windows窗口吧。具体代码如下:

    1)注册WNDCLASS类(结构体)

WNDCLASS	wc; // Windows Class Structure

hInstance = GetModuleHandle(NULL);  // Grab An Instance For Our Window
// Redraw On Size, And Own DC For Window.
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;  
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages
wc.cbClsExtra  = 0;	                   // No Extra Window Data
wc.cbWndExtra  = 0;	                   // No Extra Window Data
wc.hInstance   = hInstance;	          // Set The Instance
wc.hIcon       = LoadIcon(NULL, IDI_WINLOGO);	 // Load The Default Icon
wc.hCursor    = LoadCursor(NULL, IDC_ARROW);   // Load The Arrow Pointer
wc.hbrBackground	= NULL;						// No Background Required For GL
wc.lpszMenuName		= NULL;		     			// We Don't Want A Menu
wc.lpszClassName	= "OpenGL";		     		// Set The Class Name

if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
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)) // Are We Able To Release The DC
{
	cerr << "Release Device Context Failed." << endl;
	hdc = NULL; // Set DC To NULL
}

if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window?
{
	cerr << "Could Not Release hWnd." << endl;
	hWnd=NULL; // Set hWnd To NULL
}

if (!UnregisterClass("OpenGL",hInstance))	// Are We Able To Unregister Class
{
	cerr << "Could Not Unregister Class." << endl;
	hInstance=NULL;	// Set hInstance To NULL
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值