Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
C++ 基于OpenGL的多线程绘制_C++_Multithreading_Opengl_Rendering - Fatal编程技术网

C++ 基于OpenGL的多线程绘制

C++ 基于OpenGL的多线程绘制,c++,multithreading,opengl,rendering,C++,Multithreading,Opengl,Rendering,我有一个多线程应用程序,在其中我尝试使用不同的线程进行渲染。首先,我尝试在所有线程之间使用相同的呈现上下文,但其他线程的当前上下文为空。我在互联网上读到,一个上下文一次只能在一个线程中是最新的 所以我决定做些不同的事情。我创建一个窗口,从中获取HDC并创建第一个RC。之后,我在线程之间共享这个HDC,在我创建的每个新线程中,我从同一个HDC获得一个新的RC,并使它成为该线程的当前值。每次我这样做时,返回的RC总是不同的(通常是前一个值+1)。我做了一个断言来检查wglGetCurrentCont

我有一个多线程应用程序,在其中我尝试使用不同的线程进行渲染。首先,我尝试在所有线程之间使用相同的呈现上下文,但其他线程的当前上下文为空。我在互联网上读到,一个上下文一次只能在一个线程中是最新的

所以我决定做些不同的事情。我创建一个窗口,从中获取HDC并创建第一个RC。之后,我在线程之间共享这个HDC,在我创建的每个新线程中,我从同一个HDC获得一个新的RC,并使它成为该线程的当前值。每次我这样做时,返回的RC总是不同的(通常是前一个值+1)。我做了一个断言来检查
wglGetCurrentContext()
是否返回了一个RC,它看起来像是返回了刚刚创建的RC。但是在进行渲染之后,我没有得到渲染,如果调用
GetLastError()
我会得到错误6(无效句柄??)

那么,这是否意味着,尽管每次调用
wglCreateContext()
都会给我一个新值,但不知何故,这意味着所有这些不同的值都是OpenGL调用的相同“连接通道”

这是否意味着我将始终必须在线程上使以前的渲染上下文无效,并在新线程上激活它?我真的必须一直保持同步,或者有其他方法解决这个问题吗

我有一个多线程应用程序,在其中我尝试使用不同的线程进行渲染

不要

尝试对渲染器进行多线程处理将一无所获。基本上,您正在运行一个大的竞争条件,而驱动程序将忙于同步线程,以便以某种方式理解它

要获得最佳渲染性能,请将所有OpenGL操作仅保留在一个线程中。所有并行化都是在GPU上免费进行的。

我建议阅读OpenGL联盟提供的

简单地说,这在很大程度上取决于您对OpenGl中多线程的含义,如果您有一个线程执行渲染部分,另一个(或多个)执行其他工作(即AI、物理、游戏逻辑等),这是完全正确的

如果你想让多个线程搞乱OpenGL,你不能,或者更好,你可以,但它会给你带来更多的麻烦,而不是好处

请阅读以下有关并行OpenGL使用的常见问题解答,以便更好地了解此概念:


在某些情况下,在不同线程中使用多个呈现上下文可能是有意义的。我使用这种设计从文件系统加载图像数据,并将这些数据推送到纹理中。

Mac OS X上的OpenGL是单线程安全的;要启用它,请执行以下操作:

#include <OpenGL/OpenGL.h>

CGLError err = 0;
CGLContextObj ctx = CGLGetCurrentContext();

// Enable the multi-threading
err =  CGLEnable( ctx, kCGLCEMPEngine);

if (err != kCGLNoError ) {
     // Multi-threaded execution is possibly not available
     // Insert your code to take appropriate action
}
#包括
CGLError err=0;
CGLContextObj ctx=CGLGetCurrentContext();
//启用多线程
err=CGLEnable(ctx,kCGLCEMPEngine);
如果(错误!=kCGLNoError){
//多线程执行可能不可用
//插入代码以采取适当的操作
}
见:

以及:

谷歌搜索了2页,这可能会有所帮助:我做了一些非常类似的事情,但在wglShareLists调用后,我得到了错误6。我认为这个问题也应该理解为“既然多线程DirectX 11渲染比单线程快,那么驱动程序是否也能从OpenGL调用中带来同样的改进?”好吧,我没有正确地表达自己。但这并不意味着它们都将在屏幕上呈现。实际上他们不会。一个线程在backbuffer上绘制,并将其内容复制到纹理。另一个只是在屏幕上“闪烁”纹理。这意味着工作线程可以在backbuffer上渲染其他复杂的内容。”一个线程在backbuffer上绘制,并将其内容复制到纹理。另一个线程只是在屏幕上“Blits”纹理。“为什么?当你想展示时,你不应该只是交换前后缓冲区吗?@filipehd:即使这样,使用多个线程也没有意义。“blitter”线程必须等待“renderer”线程完成。多线程的全部要点是保持事物同时工作;你不知道。@datenwolf即使你们是对的,它也不能回答我的问题,为什么我在制作wglShareLists()后得到错误6。不过,这意味着为了做我想做的事情,我需要像FBO或PBuffer这样的辅助缓冲区?@filipehd:嗯,共享(即,让上下文同时在多个线程中处于活动状态)上下文是不可能的,但从一个线程到另一个线程传递它是可能的。但是:您应该避免总是重新创建线程和上下文。只创建一次线程池,并坚持它。上下文也是如此,不过我强烈建议不要在多个线程上使用多个上下文。如果有一个专用的OpenGL线程,事情会变得简单得多,而且性能也会更好。但这正是我的应用程序的想法——不同的线程处理不同的逻辑——我不明白的是,为什么调用WglShareList后会出现错误6。也许我说这件事太晚了?我将试着用你给我的第一个链接上写的想法来检查它是如何工作的。@filipehd:不同的逻辑意味着不同的子系统。一个线程用于联网,一个线程用于用户输入,一个线程用于OpenGL,等等。实际上,不要试图将图形输出分散到多个线程上。真是一团糟。还有“blitting”操作(绘制纹理四边形),即切换到另一个线程的整个开销将导致更多的时间消耗,即实际的“blitting”。此外,GPU是一种独占资源,您不能让多个线程同时使用GPU,因此blitter线程必须等待GPU上的任何其他操作完成。@filipehd:确实如此。为什么要尝试对渲染命令执行多线程处理?并行化发生在GPU上,它需要大量的几何原语,并行处理它们(顶点着色器),确定覆盖的片段和对象