如何仅在用户输入时设置统一变量?
How to set a uniform variable on user input only?
我有一个RenderWidget
class继承自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();
}
};
paintGL
被称为 100 times/second,而 setSmthEnabled
仅在用户切换 UI 中的复选框时才被调用,这偶尔会发生。 uniformUserInput
uniform 不需要每一帧都设置,所以我尝试只在用户输入槽中设置它,但它不起作用。制服保留其在初始化时设置的值。
我猜这是因为渲染是异步的,并且在管道繁忙时无法更新 uniform。这就是为什么我试图在 setSmthEnabled
槽中设置 uniformUserInput
之前调用 glFinish()
,但它没有帮助。我找到的唯一解决方案是以下列方式重写 class:
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
相关的 QOpenGLShaderProgram
对象和 returns.
so I try to set it only in user input slot, but it does not work
这是意料之中的事情。 OpenGL 是有状态的 API 并且状态被封装在上下文中。一个程序中可能会使用任意数量的上下文,这些上下文必须是绑定的,也可以是非绑定的。为了清楚 Qt 的编程模型,OpenGL 上下文仅在非常特定的情况下绑定,即在 initializeGL
、paintGL
和 resizeGL
内。您还可以使用 QOpenGLContext::makeCurrent
.
使上下文成为当前上下文
只有当 OpenGL 上下文绑定为当前上下文时,您才能使用它执行操作。喜欢设置统一值。
I guess this happens because rendering is asynchronous, and uniform cannot be updated while the pipeline is busy.
不是这个原因。 OpenGL 也非常有能力,事实上它是指定的,你可以随时拨打任何电话,一切都会排队。您甚至可以替换纹理图像(甚至通过 PBO),即使 GPU 仍在使用纹理对象进行渲染(驱动程序必须跟踪这些更改并推迟执行,直到所有受影响的资源都可以免费使用)。
我有一个RenderWidget
class继承自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();
}
};
paintGL
被称为 100 times/second,而 setSmthEnabled
仅在用户切换 UI 中的复选框时才被调用,这偶尔会发生。 uniformUserInput
uniform 不需要每一帧都设置,所以我尝试只在用户输入槽中设置它,但它不起作用。制服保留其在初始化时设置的值。
我猜这是因为渲染是异步的,并且在管道繁忙时无法更新 uniform。这就是为什么我试图在 setSmthEnabled
槽中设置 uniformUserInput
之前调用 glFinish()
,但它没有帮助。我找到的唯一解决方案是以下列方式重写 class:
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
相关的 QOpenGLShaderProgram
对象和 returns.
so I try to set it only in user input slot, but it does not work
这是意料之中的事情。 OpenGL 是有状态的 API 并且状态被封装在上下文中。一个程序中可能会使用任意数量的上下文,这些上下文必须是绑定的,也可以是非绑定的。为了清楚 Qt 的编程模型,OpenGL 上下文仅在非常特定的情况下绑定,即在 initializeGL
、paintGL
和 resizeGL
内。您还可以使用 QOpenGLContext::makeCurrent
.
只有当 OpenGL 上下文绑定为当前上下文时,您才能使用它执行操作。喜欢设置统一值。
I guess this happens because rendering is asynchronous, and uniform cannot be updated while the pipeline is busy.
不是这个原因。 OpenGL 也非常有能力,事实上它是指定的,你可以随时拨打任何电话,一切都会排队。您甚至可以替换纹理图像(甚至通过 PBO),即使 GPU 仍在使用纹理对象进行渲染(驱动程序必须跟踪这些更改并推迟执行,直到所有受影响的资源都可以免费使用)。