如何从不同的线程绘制opengl图形?

时间:2022-09-10 16:40:18

I want to make an opengl application that shows some 3d graphics and a command-line. I would like to make them separate threads, because they both are heavy processes. I thought that I could approach this with 2 different viewports, but I would like to know how to handle the threads in opengl.

我想制作一个显示一些3d图形和命令行的opengl应用程序。我想让它们成为单独的线程,因为它们都是繁重的进程。我认为我可以使用2个不同的视口来处理这个问题,但我想知道如何处理opengl中的线程。

According to what I've been reading, Opengl is asynchronous, and calling its functions from different threads can be very problematic. Is there a way that I could use to approach this problem? Ideally, I would like to draw the command line on top of the 3d graphics with some transparecy effect... (this is impossible with viewports I guess)

根据我一直在阅读的内容,Opengl是异步的,从不同的线程调用它的函数可能非常有问题。有没有办法可以用来解决这个问题?理想情况下,我想在3d图形的顶部绘制命令行,并具有一些透明效果......(我想这对于视口是不可能的)

Is important that the solution is portable.

重要的是解决方案是可移植的。

Thanks!

3 个解决方案

#1


Its possible you can achieve what you want to do using Overlays.
Overlays are a somewhat dated feature but it should still be supported in most setups. Basically an overlay is a separate GL Context which is rendered in the same window as another layer, drawing on top of whatever was drawn on the windows with its original context.
You can read about it here.

您可以使用Overlays实现您想要的功能。叠加是一种有点过时的功能,但在大多数设置中仍然应该支持它。基本上,叠加是一个单独的GL上下文,它在与另一个图层相同的窗口中呈现,绘制在窗口上绘制的任何内容及其原始上下文之上。你可以在这里读到它。

#2


I think, rather than trying to create two threads to draw to the screen, you need to use the MVC pattern and make your model thread-safe. Then you can have one thread that grabs the necessary info from the model each frame and throws it on screen, and then two other threads, one for the graphics and one for the command-line, which manage only the model.

我认为,您需要使用MVC模式并使模型具有线程安全性,而不是尝试创建两个线程来绘制到屏幕上。然后你可以有一个线程从每个帧的模型中获取必要的信息并将其抛出到屏幕上,然后是另外两个线程,一个用于图形,一个用于命令行,只管理模型。

So for instance, you have a Simulation class that has your 3D graphics stuff, and then a CommandLine class that has your command line. Each of these classes does not use OpenGL at all; only manages the data, such as where things are in 3d-space, and in the case of the command-line a queue of the lines on-screen. Then the opengl thread can query thread-safe functions of these classes each frame, to get the necessary info. So for example, it grabs the positions of the 3d things, draws them on-screen, then grabs the lines to display on the command line and draws them.

例如,你有一个拥有3D图形内容的Simulation类,然后是一个拥有命令行的CommandLine类。这些类中的每一个都根本不使用OpenGL;仅管理数据,例如3d空间中的内容,以及命令行中屏幕上的行队列。然后opengl线程可以每帧查询这些类的线程安全函数,以获得必要的信息。因此,例如,它抓取3d事物的位置,在屏幕上绘制它们,然后抓取线条以在命令行上显示并绘制它们。

#3


You can't do it with 2 viewports.

你不能用2个视口做到这一点。

Each OpenGL context must be used from the same thread in which it was created.

每个OpenGL上下文必须在创建它的同一个线程中使用。

Two separate window handles, each with their own context, can be setup and used from two separate threads safely, but not 2 viewports in one window.

两个单独的窗口句柄,每个窗口句柄都有自己的上下文,可以安全地从两个单独的线程设置和使用,但在一个窗口中不能设置2个视口。


A good place to look at ideas for this is OpenSceneGraph. It does a lot of work with threading to help try to speed up handling and maintain a constant, high framerate with very large scenes.

OpenSceneGraph是一个了解这个想法的好地方。它通过线程进行了大量工作,以帮助尝试加速处理并保持具有非常大的场景的恒定,高帧率。

I've successfully embedded it and used it from 2 separate threads, but OSG has many checks in place to help with this sort of scenario.

我已成功嵌入它并从2个独立的线程中使用它,但OSG有许多检查来帮助处理这种情况。

#1


Its possible you can achieve what you want to do using Overlays.
Overlays are a somewhat dated feature but it should still be supported in most setups. Basically an overlay is a separate GL Context which is rendered in the same window as another layer, drawing on top of whatever was drawn on the windows with its original context.
You can read about it here.

您可以使用Overlays实现您想要的功能。叠加是一种有点过时的功能,但在大多数设置中仍然应该支持它。基本上,叠加是一个单独的GL上下文,它在与另一个图层相同的窗口中呈现,绘制在窗口上绘制的任何内容及其原始上下文之上。你可以在这里读到它。

#2


I think, rather than trying to create two threads to draw to the screen, you need to use the MVC pattern and make your model thread-safe. Then you can have one thread that grabs the necessary info from the model each frame and throws it on screen, and then two other threads, one for the graphics and one for the command-line, which manage only the model.

我认为,您需要使用MVC模式并使模型具有线程安全性,而不是尝试创建两个线程来绘制到屏幕上。然后你可以有一个线程从每个帧的模型中获取必要的信息并将其抛出到屏幕上,然后是另外两个线程,一个用于图形,一个用于命令行,只管理模型。

So for instance, you have a Simulation class that has your 3D graphics stuff, and then a CommandLine class that has your command line. Each of these classes does not use OpenGL at all; only manages the data, such as where things are in 3d-space, and in the case of the command-line a queue of the lines on-screen. Then the opengl thread can query thread-safe functions of these classes each frame, to get the necessary info. So for example, it grabs the positions of the 3d things, draws them on-screen, then grabs the lines to display on the command line and draws them.

例如,你有一个拥有3D图形内容的Simulation类,然后是一个拥有命令行的CommandLine类。这些类中的每一个都根本不使用OpenGL;仅管理数据,例如3d空间中的内容,以及命令行中屏幕上的行队列。然后opengl线程可以每帧查询这些类的线程安全函数,以获得必要的信息。因此,例如,它抓取3d事物的位置,在屏幕上绘制它们,然后抓取线条以在命令行上显示并绘制它们。

#3


You can't do it with 2 viewports.

你不能用2个视口做到这一点。

Each OpenGL context must be used from the same thread in which it was created.

每个OpenGL上下文必须在创建它的同一个线程中使用。

Two separate window handles, each with their own context, can be setup and used from two separate threads safely, but not 2 viewports in one window.

两个单独的窗口句柄,每个窗口句柄都有自己的上下文,可以安全地从两个单独的线程设置和使用,但在一个窗口中不能设置2个视口。


A good place to look at ideas for this is OpenSceneGraph. It does a lot of work with threading to help try to speed up handling and maintain a constant, high framerate with very large scenes.

OpenSceneGraph是一个了解这个想法的好地方。它通过线程进行了大量工作,以帮助尝试加速处理并保持具有非常大的场景的恒定,高帧率。

I've successfully embedded it and used it from 2 separate threads, but OSG has many checks in place to help with this sort of scenario.

我已成功嵌入它并从2个独立的线程中使用它,但OSG有许多检查来帮助处理这种情况。