如何仅在用户输入上设置统一变量?

时间:2016-09-16 10:21:04

标签: c++ qt opengl qtopengl

我有一个继承自RenderWidget的{​​{1}}类,其中包含以下两种方法:

QOpenGLWidget

RenderWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_3_Core { // ... public slots: void setSmthEnabled(bool enabled) { float val = (enabled == true) ? 1.0f : 0.0f; shader.setUniformValue("uniformUserInput", val); } public: void paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // ... shader.setUniformValue("uniform1", value1); shader.setUniformValue("uniform2", value2); // ... mesh->draw(); } }; 被调用100次/秒,而paintGL仅在用户切换UI中的复选框时调用,偶尔会发生这种情况。 setSmthEnabled统一不需要每帧设置,所以我尝试仅在用户输入槽中设置它,但它不起作用。制服保留了它在初始化时设置的值。

我想这是因为渲染是异步的,并且在管道繁忙时无法更新统一。这就是我在uniformUserInput位置设置glFinish()之前尝试拨打uniformUserInput的原因,但这并没有帮助。我找到的唯一解决方案是以下列方式重写该类:

setSmthEnabled

真实世界的代码包含更多用户输入的制服,所以我不想每帧更新所有这些,并为此目的保留冗余成员变量。如何仅更新用户输入的制服?

上面核心中的

RenderWidget : public QOpenGLWidget, protected QOpenGLFunctions_4_3_Core { // ... private: float val = 1.0f; public slots: void setSmthEnabled(bool enabled) { val = (enabled == true) ? 1.0f : 0.0f; } public: void paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // ... shader.setUniformValue("uniform1", value1); shader.setUniformValue("uniform2", value2); // ... shader.setUniformValue("uniformUserInput", val); mesh->draw(); } }; 仅在相关的shader.setUniformValue对象上调用QOpenGLShaderProgram::setUniformValue并返回。

1 个答案:

答案 0 :(得分:2)

  

因此我尝试仅在用户输入槽中设置它,但它不起作用

这是可以预料的。 OpenGL是一个有状态的API,状态封装在一个上下文中。在单个程序中可能存在任意数量的上下文,这些上下文必须绑定并且可以是未绑定的。为了清楚在Qt的编程模型中,OpenGL上下文仅在非常特定的情况下绑定,即在initializeGLpaintGLresizeGL内。您还可以使用QOpenGLContext::makeCurrent创建上下文。

只有当OpenGL上下文绑定时,您才能使用它。就像设置统一值一样。

  

我想这是因为渲染是异步的,并且在管道繁忙时无法更新统一。

这不是原因。此外,OpenGL完全有能力,事实上它是指定的,你可以随时拨打任何电话,一切都排队等候。即使在GPU仍在使用纹理对象进行渲染时,您甚至可以替换纹理图像(甚至通过PBO)(驱动程序必须跟踪这些更改并推迟执行,直到所有受影响的资源都可以自由使用)。