我有一个继承自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
并返回。
答案 0 :(得分:2)
因此我尝试仅在用户输入槽中设置它,但它不起作用
这是可以预料的。 OpenGL是一个有状态的API,状态封装在一个上下文中。在单个程序中可能存在任意数量的上下文,这些上下文必须绑定并且可以是未绑定的。为了清楚在Qt的编程模型中,OpenGL上下文仅在非常特定的情况下绑定,即在initializeGL
,paintGL
和resizeGL
内。您还可以使用QOpenGLContext::makeCurrent
创建上下文。
只有当OpenGL上下文绑定时,您才能使用它。就像设置统一值一样。
我想这是因为渲染是异步的,并且在管道繁忙时无法更新统一。
这不是原因。此外,OpenGL完全有能力,事实上它是指定的,你可以随时拨打任何电话,一切都排队等候。即使在GPU仍在使用纹理对象进行渲染时,您甚至可以替换纹理图像(甚至通过PBO)(驱动程序必须跟踪这些更改并推迟执行,直到所有受影响的资源都可以自由使用)。