Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用OpenGL在windows上的同一应用程序中在两个单独的3D窗口内绘制? 我在Windows上的C++中实现了一个第三方程序的插件。_C++_Windows_Multithreading_Winapi_Opengl - Fatal编程技术网

如何使用OpenGL在windows上的同一应用程序中在两个单独的3D窗口内绘制? 我在Windows上的C++中实现了一个第三方程序的插件。

如何使用OpenGL在windows上的同一应用程序中在两个单独的3D窗口内绘制? 我在Windows上的C++中实现了一个第三方程序的插件。,c++,windows,multithreading,winapi,opengl,C++,Windows,Multithreading,Winapi,Opengl,第三方程序有一个使用OpenGL显示3D图形的窗口。 但是,我需要该插件来创建另一个窗口,该窗口也使用OpenGL显示3D图形 我是否需要为我的窗口创建新的OpenGL渲染上下文,或者是否有某种方法可以“重用”第三方程序使用的OpenGL渲染上下文? 我假设我必须创建一个新的OpenGL渲染上下文,并尝试了以下操作: // create a rendering context hglrc = wglCreateContext (hdc); // make it the calling t

第三方程序有一个使用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()生成的错误代码,因此我不会猜测原因。然而,这不是绑定本身。句子“一个线程可以有一个当前呈现上下文”意味着新上下文将“替换”旧上下文并成为当前上下文。我不知道为什么要将两个上下文设置为当前上下文(或运行另一个线程),但这不是解决方法。除非绝对必要,否则在渲染时避免使用多线程。 那么,回答你的问题:

是的,您可以“重用”OpenGL渲染上下文

你可能会问,为什么?渲染上下文是为特定设备上下文(HDC)创建的,它是每个窗口(HWND)的专有属性!那这怎么可能呢

由于功能原型的原因,这似乎是不可能的:

HWND my_window = CreateWindow(...); HDC my_dc = GetDC(my_new_window); //Setup pixel format for 'my_dc'... HGLRC my_rc = wglCreateContext(my_dc); wglMakeCurrent(my_dc, my_rc); HWND my_window=CreateWindow(…); HDC my_dc=GetDC(my_new_窗口); //设置“my_dc”的像素格式。。。 HGLRC my_rc=wglCreateContext(my_dc); wglMakeCurrent(my_dc,my_rc); 这确实让您认为呈现上下文绑定到此特定设备上下文,并且仅对其有效。但事实并非如此。 关键部分是注释(设置像素格式)。渲染上下文是为特定的DC类创建的,更精确地说,是为具有相同像素格式的DC创建的。因此,下面的代码完全有效:

//window_1 = main window, window_2 = your window HDC dc_1 = GetDC(window_1); Set_pixel_format_for_dc_1(); //Usual stuff HGLRC rc = wglCreateContext(dc_1); wglMakeCurrent(dc_1, rc); ultra_super_draw(); //..... HDC dc_2 = GetDC(window_2); //Get dc_1's PF to make sure it's compatible with 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); //窗口1=主窗口,窗口2=您的窗口 HDC dc_1=GetDC(窗口_1); 为_dc_1()设置_像素_格式_//平常的东西 HGLRC=wglCreateContext(dc_1); wglMakeCurrent(dc_1,rc); ultra_super_draw(); //..... HDC dc_2=GetDC(窗口_2); //获取dc_1的PF,确保其与rc兼容。 int pf_index=GetPixelFormat(dc_1); 像素描述符pfd; 零内存(&pfd,sizeof(像素格式描述符)); 描述像素格式(dc_1、pf_索引、sizeof(像素格式描述符)和pfd); SetPixelFormat(dc_2、pf_索引和pfd); wglMakeCurrent(dc_2,rc); 另一个精彩的呈现(); wglMakeCurrent(NULL,NULL); 如果你仍然不相信,那么:

wglMakeCurrent(hdc,hglrc):hdc参数必须引用OpenGL支持的图形表面。它不需要与创建hglrc时传递给wglCreateContext的hdc相同,但必须位于同一设备上,并且具有相同的像素格式

我想你已经熟悉这些电话了。现在,我不知道渲染必须满足哪些条件,但如果没有其他要求,我看不出这一点有任何困难:

HDC my_dc = Create_my_DC(); //... void my_new_render { //Probably you want to save current binding: HDC current_dc = wglGetCurrentDC(); HGLRC current_context = wglGetCurrentContext(); wglMakeCurrent(my_dc, current_context); MyUltraSuperRender(...); wglMakeCurrent(current_dc, current_context); } HDC my_dc=创建我的dc(); //... 使我的新渲染无效 { //可能要保存当前绑定: HDC current_dc=wglGetCurrentDC(); HGLRC current_context=wglGetCurrentContext(); wglMakeCurrent(我的dc,当前上下文); MyUltraSuperRender(…); wglMakeCurrent(当前\u dc,当前\u上下文); }
希望这有帮助:)

首先,您实际上应该为插件创建一个单独的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);

如果您的窗口与第三方应用程序的窗口具有相同的像素格式,则不需要单独的线程。告诉我们wglMakeCurrent()失败的确切程度可能会有所帮助。