I have a RenderWidget
class inherited from QOpenGLWidget
, which has the following two methods, among others:
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();
}
};
paintGL
is being called 100 times/second, while setSmthEnabled
is only called when a user toggles a checkbox in the UI, which happens occasionally. uniformUserInput
uniform does not need to be set every frame, so I try to set it only in user input slot, but it does not work. The uniform preserves it's value, which was set on initialization.
I guess this happens because rendering is asynchronous, and uniform cannot be updated while the pipeline is busy. That's why I tried to call glFinish()
before setting uniformUserInput
in setSmthEnabled
slot, but it didn't help. The only solution I found is to rewrite the class in the following manner:
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();
}
};
Real-world code contains much more user-input uniforms, so I wouldn't like to update all of them each frame and keep redundant member variables for that purpose. How do I update uniforms on user input only?
shader.setUniformValue
in the core above only calls QOpenGLShaderProgram::setUniformValue
on a relevant QOpenGLShaderProgram
object and returns.