OpenGL多线程,可变处理

OpenGL multiple threads, variable handling

本文关键字:处理 多线程 OpenGL      更新时间:2023-10-16

我编写了一个OpenGL程序,它以以下方式运行:

Main:
- Initialize SDL
- Create thread which has the OpenGL context:
- Renderloop
- Set camera (view) matrix with glUniform.
- glDrawElements() .... etc.
- Swapbuffers();
- Main SDL loop handling input events and such.
- Update camera matrix of type glm::mat4. 

这就是我将相机对象传递给处理opengl的类的方法。

Camera *cam = new Camera();
gl.setCam(cam);

其中

void setCam(Camera *camera) {
this->camera = camera;
}

对于在opengl上下文线程中渲染,会发生以下情况:

glm::mat4 modelView = camera->view * model;
glUniformMatrix4fv(shader->bindUniform("modelView"), 1, GL_FALSE, glm::value_ptr(modelView));

在处理SDL和其他事情的主程序中,我重新计算视图矩阵。在我不使用任何互斥锁的情况下,他工作得很好。这是正确的吗?

另一方面,我通过"上传队列"将对象添加到场景中,在这种情况下,当向其中添加项目时,我必须互斥锁定上传队列向量(向量类类型),否则程序将崩溃。

总之:我在另一个线程中重新计算矩阵,然后在没有任何互斥锁的情况下在opengl线程中使用它。为什么这样有效?

编辑:我想我的问题与这里的问题类似:

1) 如果我只需要一个变量';s在其他线程中的值,以及如果我不这样做,为什么它能工作';t?,只是在我的情况下,它甚至更简单,只改变了一个矩阵。

2) 当只有一个线程写入共享变量时,我需要锁吗?

为什么这样做?

谁说是?

多线程代码的经验法则非常简单:如果你的多线程代码不是可证明的线程安全,那么默认情况下它是错误的。

互斥体和其他同步结构允许您证明您的代码是有效的。如果没有经过验证的功能,你只是在掷骰子。也许你在那台机器上很幸运。也许如果你重新启动电脑,它就会停止工作。也许你打喷嚏它就会碎。

仅仅因为发生的事情按您的意愿运行并不意味着它有效。只是你逃脱了惩罚,就像小偷没有被警察抓住一样,并不意味着如果他们再试一次,他们就抓不到他。

如果需要,可以选择依赖未经验证的线程代码。或者你可以把事情做好,而不必担心。


据我所知,它的行为与我在哪里进行相同

不,不会。

在第一种情况下,您正在传递一个指向堆栈对象的指针。当作用域结束时,该堆栈对象将被销毁。从那时起,任何试图使用该指针进行任何操作的行为都会造成不良后果。

在第二种情况下,您将向一个新分配的堆对象传递一个指针。当销毁该对象时,该对象将被销毁。必须有人负责删除该对象。假设当您将该指针传递给gl.setCam时,gl对象将承担在适当的时间销毁它的责任。

这是标准的C++;它与OpenGL、多线程、任何东西都无关。这一切都与所有权的概念有关;你将堆栈所拥有的内存传递给了一个函数,该函数希望声明对它的所有权。你做出了一个无法兑现的承诺。因此,繁荣。

为什么这样做?

我不知道,我的水晶球坏了,你没有给我们你的代码。由于OpenGL没有摄像头,而您使用的是camera类,我认为您可能有一些副本(可能会泄漏内存)。