如何使用OpenGL在Windows上的同一应用程序中的两个单独的3D窗口中进行绘制
How can I draw inside two separate 3D windows within the same application on Windows using OpenGL?
我正在Windows上的C++第三方程序中实现一个插件。
第三方程序有一个窗口,使用 OpenGL 显示 3D 图形。但是,我需要该插件来创建另一个窗口,该窗口也使用 OpenGL 显示 3D 图形。
我是否需要为我的窗口创建新的 OpenGL 渲染上下文,或者是否有某种方法可以"重用"第三方程序使用的 OpenGL 渲染上下文?
我假设我必须创建一个新的 OpenGL 渲染上下文并尝试以下操作:
// create a rendering context
hglrc = wglCreateContext (hdc);
// make it the calling thread's current rendering context
wglMakeCurrent (hdc, hglrc);
但是,最后一个函数失败了。阅读wglMakeCurrent的文档,我注意到
一个线程可以有一个当前呈现上下文。通过多线程处理,一个进程可以具有多个呈现上下文。
这是否意味着我的窗口需要在与第三方程序不同的线程中运行?
你没有发布由wglMakeCurrent((生成的错误代码,所以我不会猜测原因。但是,这不是绑定本身。句子"一个线程可以有一个当前渲染上下文"意味着,新上下文将"替换"旧上下文并成为当前上下文。我不知道您为什么要尝试将两个上下文设置为当前(或运行另一个线程(,但这不是要走的路。除非绝对必要,否则避免在渲染中使用多线程。所以,回答你的问题:
是的,您可以"重用"OpenGL渲染上下文。
你可能会问,为什么?渲染上下文是为特定设备上下文 (HDC( 创建的,这是每个窗口 (HWND( 的专有属性!这怎么可能?!
好吧,由于功能原型,这似乎是不可能的:
HWND my_window = CreateWindow(...(; HDC my_dc = GetDC(my_new_window(; 设置"my_dc"的像素格式... HGLRC my_rc = wglCreateContext(my_dc(; wglMakeCurrent(my_dc, my_rc(;
这确实让您认为呈现上下文绑定到此特定设备上下文,并且仅对其有效。但事实并非如此。关键部分是注释(设置像素格式(。呈现上下文是为特定的 DC 类创建的,更准确地说:为具有相同像素格式的 DC。所以下面的代码是完全有效的:
window_1 = 主窗口,window_2 = 您的窗口 HDC dc_1 = GetDC(window_1(; Set_pixel_format_for_dc_1((;平常的东西 HGLRC rc = wglCreateContext(dc_1(; wglMakeCurrent(dc_1, rc(; ultra_super_draw((; //..... HDC dc_2 = GetDC(window_2(; 获取dc_1的 PF 以确保它与 rc 兼容。 int pf_index = GetPixelFormat(dc_1(; PIXELFORMATDESCRIPTOR pfd; ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR((; DescribePixelFormat(dc_1, pf_index, sizeof(PIXELFORMATDESCRIPTOR(, &pfd(; SetPixelFormat(dc_2, pf_index, &pfd(; wglMakeCurrent(dc_2, rc(; another_awesome_render((; wglMakeCurrent(NULL, NULL(;
如果您仍然不相信,MSDN:
wglMakeCurrent(hdc, hglrc(:hdc 参数必须引用 OpenGL 支持的绘图图面。它不必与创建 hglrc 时传递给 wglCreateContext 的 hdc 相同,但它必须位于同一设备上并具有相同的像素格式。
我想你已经熟悉这些电话了。现在,我不知道您的渲染必须满足哪些条件,但是如果没有其他要求,我认为从这一点上看没有任何困难:
HDC my_dc = Create_my_DC((; //... 无效my_new_render { 可能您想保存当前绑定: HDC current_dc = wglGetCurrentDC((; HGLRC current_context = wglGetCurrentContext((; wglMakeCurrent(my_dc, current_context(; MyUltraSuperRender(...(; wglMakeCurrent(current_dc, current_context(; }
希望这对:)有所帮助
首先,您实际上应该为您的插件创建一个单独的OpenGL上下文,原因很简单,它为您提供了一个单独的状态空间,不会干扰主程序OpenGL上下文。
不过,您误解了有关多个渲染上下文的部分。一个进程完全可以拥有任意数量的 OpenGL 上下文。但是进程的每个线程一次只能绑定一个上下文。该绑定还包括上下文绑定到的窗口 DC。然而,随时更改上下文约束是完全合法的。您可以更改给定上下文绑定到的窗口,也可以切换上下文,或者同时执行这两项操作。
因此,在您的情况下,我建议您为插件创建一个自定义上下文,用于插件创建的所有窗口。
您的简单上下文"创建"代码失败的原因很简单:您的窗口很可能没有设置像素格式描述符。
我建议您使用以下方法来创建新窗口和上下文:
/* first get hold of the HDC/HRC of the parent */
HDC parentDC = wglGetCurrentDC();
HRC parentRC = wglGetCurrentContext();
int pixelformatID = GetPixelFormat(parentDC);
/* we use the same PFD as the parent */
PIXELFORMATDESCRIPTOR pixelformat;
memset(pixelformat, 0, sizeof(pixelformat);
DescribePixelFormat(parentDC, pixelformatID, sizeof(pixelformat), &pixelformat);
/* create a window and set it's pixelformat to the parent one's */
HWND myWND = create_my_window();
HDC myDC = GetDC(myWND);
SetPixelFormat(myDC, pixelformatID, &pixelformat);
/* finally we can create a rendering context
* it doesn't matter if we create it against
* the parent or our own DC.
*/
HRC myRC = wglCreateContext(myDC);
/* we're done here... */
现在,每当你的插件想要渲染一些东西时,它应该绑定自己的上下文,做它的事情并绑定之前绑定的上下文:
HDC prevDC = wglGetCurrentDC();
HRC prevRC = wglGetCurrentContext();
wglMakeCurrent(myDC, myRC);
/* do OpenGL stuff */
wglMakeCurrent(prevDC, prevRC);
- 如何在C++中从两个单独的for循环中添加两个数组
- 将字符串拆分为标记,并将标记拆分为两个单独的数组
- 如何将字符串和整数读取到两个单独的动态数组中的程序编写?
- 两个单独的类不共享相同的数据 C++
- SDL GPU 为什么将两个图像分成两个单独的循环更快?
- 如何将4位整数值转换为C 中两个单独的2位值
- 试图将两个类放在同一命名空间中的单独文件中,但只有#1个#Class类作品
- 在OpenGL中制作两个单独的茶壶
- 将INT和STR输入并将它们存储到两个单独的列表中
- 如何将一个类的两个单独实例设置为彼此相等的 c++
- GCC 6.3.0 中的 ODR 冲突,类型在两个单独的翻译单元中定义
- 尝试使用两个单独的 getline() 实例来填充两个单独的向量
- C++:两个单独的函数在嵌套时返回不同的结果?
- 模板和两个单独的类之间的区别
- 如何避免将两个单独的'>'格式化为一个班次?
- 输入坐标分为与文件故障的两个单独的数组
- 如何使用两个单独的语法实现计算机翻译器
- 相当棘手的代码气味要解决(由于两个单独的库)C
- 在单独列表中的两个精灵的碰撞
- 如何组合两个单独的生成文件来编译程序