多窗口使用OpenGL——wglShareLists使用简介

本文介绍了OpenGL在Windows环境下多线程渲染时如何利用wglShareLists实现资源共享的方法,并提供了注意事项及示例代码。

在使用多窗口使用OpenGL的时候,发现只能运行一个,另外一个就暂停了...搜索有一下文章,且拿来参考:、

摘自:http://blog.youkuaiyun.com/webscaler/article/details/5873179

OpenGL 中用到多线程和多 render context 渲染的时候会用到 wglsharelist 进行资源共享,本文将对我本人在 wglsharelist 使用过程中的经验做个小总结:

         首先翻译下 msdn 上对 wglsharelist 的说明:

wglShareLists

         wglShareLists 函数使多个 OpenGL render contexts 可以共享一个显示列表空间。     

  1. BOOL wglShareLists(  
  2.    HGLR C   hglrc1 ,  // 提供共享资源的render context  
  3.    HGLRC   hglrc2    // 共享别人资源的render context  
  4. );   

参数

hglrc1

         指定共享显示列表的 OpenGL 渲染上下文。

hglrc2

指定共享 hglrc1 显示列表的 OpenGL 渲染上下文。当 wglShareLists 被调用时, hglrc2 不能包含任何显示列表。

返回值

         当函数成功时,返回值为 TRUE.

当函数失败时,返回值为 FALSE 并且显示列表也不会被共享。调用 GetLastError 可以得到更多错误信息。

下面是我对 ShareList 的理解:

         使用 OpenGL 在 windows 窗口上绘制图像需要一个 render context , 就像 GDI 需要 device context 一样,当然 render context 最终也是通过 device context 绘制到最终的显示设备上的,这里 render context 我们可以形象地看成一个管道,用来存储 OpenGL 用户的命令和数据,为了节省管道的容量和带宽,我们希望管道间共享数据,所以 windows 引入了 wglShareLists 。下面是我在使用过程中得出的几个注意事项:

<1> wglShareLists 的两个参数可以属于同一个 device context ,也可以属于不同 device context 。

<2> 不同 render context 切换时,切记要记得保存旧的 render context 和 device context ,以便恢复,这样其他地方的绘制才不会受到影响,示例代码如下:


       

  1. HDC l_oldDC = wglGetCurrentDC();  
  2. HGLRC l_oldRC = wglGetCurrentContext();  
  3. wglMakeCurrent(l_newDC, l_newRC);  
  4. …………….  
  5. SwapBuffers(l_newDC);  
  6. wglMakeCurrent(l_oldDC, l_oldRC);  

<3> 在 <2> 的示例代码中红色标出的 swapbuffer 操作,这个要和你设置 device context 的 pixel format 要一致,在 PIXELFORMATDESCRIPTOR 结构中有个 dwFlags 字段,如果设置了 PFD_DOUBLEBUFFER ,那一定要记得 swapbuffer 操作。

<4> wglShareLists 的两个参数谁分享谁的资源一定要搞清楚,之前在网上找的文章说错了,搞的我弄了半天都不对,后来换了一下就对了,这里我只讲正确的方式,免得大家搞混,请记住: hglrc2 分享 hglrc1 的资源。

好了,再讲下创建 render context 的步骤:

(a). 获取一个 DC

(b). 选择并且设置 DC 的像素格式

(c). 通过 API : wglCreateContext(DC) 创建一个 RC

(d). 设置当前的 RC ,通过 API : wglMakeCurrent(RC, DC) 来

这个在网上和 msdn 都可以查到,想进一步了解,就动起手来吧。本人 OpenGL 菜鸟,如有不对还请大家提出,不胜感激 :)

本文参考文章如下:

http://blog.youkuaiyun.com/blucexi/archive/2006/09/21/1262117.aspx

http://hi.baidu.com/atyuwen/blog/item/420d16ea7fdd36d5d539c9b6.html


<think> 嗯,用户这次询问的是关于wglCreateContext的具体信息,包括使用方法、功能和示例。从对话历史来看,用户显然在深入研究Windows平台下的OpenGL开发,特别是上下文管理相关的API。之前提供的引用[1]和[2]已经给出了函数的基本说明和命名规则,这次需要更深入的技术细节。 用户能准确指出wglCreateContext这个函数,说明他应该正在处理OpenGL渲染上下文创建相关的开发任务,可能是遇到了初始化问题或者多上下文管理需求。考虑到wglCreateContext是Windows平台专有的API,需要特别强调其平台相关性,避免用户误用到其他系统。 关于功能部分,除了创建上下文的基本说明,应该补充这个函数与设备上下文(DC)的绑定关系,这是Windows GDI整合OpenGL的关键机制。用户可能没意识到的是,这个函数返回的上下文默认不包含扩展功能,需要额外处理扩展加载,这点在示例代码里需要体现。 示例代码的设计要突出几个关键点:设备上下文获取、像素格式设置(这是容易出错的地方)、上下文创建与绑定。考虑到用户可能是新手,在注释里特别说明错误检查的必要性,因为很多驱动兼容性问题会在这里暴露。最后用wglMakeCurrent(0,0)释放上下文的做法也要写清楚,避免资源泄漏。 突然想到用户可能还会关心线程安全问题——wglCreateContext创建的上下文只能在单个线程使用。不过当前问题没涉及这点,放在功能说明里提一句就够了,不必展开。另外现代OpenGL提倡使用wglCreateContextAttribsARB这个扩展函数,但既然用户明确问wglCreateContext,暂时不引入额外概念。 最后生成的两个相关问题是有意设计的:第一个针对上下文创建后的状态设置(比如版本号请求),第二个则是常见的多上下文共享需求。如果用户继续追问,就能自然引出更高级的扩展函数用法。 </think> 以下是关于 `wglCreateContext` 的详细说明,涵盖其功能、使用方法及示例: --- ### **功能说明** `wglCreateContext` 是 Windows 平台专属的 OpenGL 窗口库 (WGL) 函数[^1][^2],核心功能是**创建 OpenGL 渲染上下文**。该上下文关联当前窗口的设备上下文 (DC),使 OpenGL 指令能在指定窗口上执行渲染操作[^2]。 --- ### **函数原型** ```c HGLRC wglCreateContext(HDC hdc); ``` - **参数**: `hdc` → 窗口设备上下文的句柄(通过 `GetDC(hWnd)` 获取)。 - **返回值**: - 成功:返回新创建的 OpenGL 渲染上下文句柄 (`HGLRC`)。 - 失败:返回 `NULL`(需检查 `GetLastError()`)。 --- ### **使用方法** 1. **前置条件**: - 为窗口设置兼容的像素格式(使用 `ChoosePixelFormat` + `SetPixelFormat`)。 - 获取窗口设备上下文句柄:`hdc = GetDC(hWnd)`。 2. **创建上下文**: ```c HGLRC hglrc = wglCreateContext(hdc); ``` 3. **绑定上下文**(使 OpenGL 命令在当前线程生效): ```c BOOL success = wglMakeCurrent(hdc, hglrc); // 返回 TRUE 表示成功 ``` 4. **销毁资源**(程序退出时): ```c wglMakeCurrent(NULL, NULL); // 解绑上下文 wglDeleteContext(hglrc); // 删除上下文 ReleaseDC(hWnd, hdc); // 释放设备上下文 ``` --- ### **示例代码(Windows OpenGL 初始化)** ```c #include <Windows.h> #include <GL/gl.h> HDC hdc; HGLRC hglrc; // 1. 设置像素格式 PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32, // 颜色深度 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, // 深度缓冲区 8, // 模板缓冲区 0, 0, 0, 0, 0 }; int pixelFormat = ChoosePixelFormat(hdc, &pfd); SetPixelFormat(hdc, pixelFormat, &pfd); // 2. 创建并绑定上下文 hglrc = wglCreateContext(hdc); if (hglrc && wglMakeCurrent(hdc, hglrc)) { // OpenGL 初始化成功,可调用 glClearColor() 等函数 } // 3. 渲染循环中交换缓冲区 SwapBuffers(hdc); // 4. 程序退出时清理 wglMakeCurrent(NULL, NULL); wglDeleteContext(hglrc); ReleaseDC(hWnd, hdc); ``` --- ### **关键注意事项** 1. **线程绑定**: 创建的上下文仅对调用线程有效,多线程渲染需为每个线程创建独立上下文并通过 `wglShareLists` 共享资源[^2]。 2. **扩展功能启用**: 现代 OpenGL 功能(如核心配置文件)需使用扩展函数 `wglCreateContextAttribsARB`(需先加载 WGL 扩展)[^2]。 3. **错误处理**: 若返回 `NULL`,常见原因包括: - 未正确设置像素格式。 - 显卡驱动不支持 OpenGL。 - 多次创建上下文未释放。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值