统一值和 OpenGL 着色器

Posted

技术标签:

【中文标题】统一值和 OpenGL 着色器【英文标题】:uniform values and OpenGL shaders 【发布时间】:2015-05-04 03:53:16 【问题描述】:

所以我猜想在我用 QT 中的着色器编写的程序中的 openGL 中有一个小动画。

我的动画随着时间的变化而变化。为了计算时间,我在 Slot 中使用了一个 Timer,它会重复更新时间。

我有一个 Qwidget,我的顶点着色器非常简单,所以我不会包含代码。

现在我的片段着色器:

 QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
 const char *fsrc =
        "uniform float time;\n"
        "in vec4 coordinates;\n"
        "out vec4 outcolor;\n"
        "void main(void)\n"
        "\n"
        "   float l,z=time;"
        "   outcolor=vec4(coordinates * time);" //<- pretend i did something with time here
        "\n";
fshader->compileSourceCode(fsrc);

然后是我的时间更新方法:

void MyWidget::updateTime()

    float seconds;
    seconds = (float) ((double) clock() - startTime) / CLOCKS_PER_SEC;
    program->setUniformValue("time", (float) seconds / (float) CLOCKS_PER_SEC);


最后是我如何使用它:

 timeTimer=new QTimer();    
QObject::connect(timeTimer, SIGNAL(timeout()),this, SLOT(updateTime()));
timeTimer->start(20);

但是,当我运行我的程序时,它会编译并执行,但无论我等待多长时间,计时器都不会更新。我的直觉是我没有使用一种好的方法来更新我的着色器中的时间,我做错了什么?

【问题讨论】:

我不知道这个 Qt 信号是如何工作的,但您需要确保在您正在渲染的同一线程中调用 updateTime() 方法。否则,当您尝试设置统一值时,没有当前的 OpenGL 上下文。 我尝试使用 glGetUniformLocation() 但我不知道如何找到程序的句柄。我的代码乍一看是否有效?我担心仅仅调用 program->setUniformValue 是不够的,因为该程序同时具有顶点和片段着色器......@RetoKoradi 调用本身看起来不错。当您调用setUniformValue() 时,我怀疑您的信号处理程序要么在不同的线程中调用,要么您的程序不是活动程序。将更新的时间存储在类成员中似乎更安全,然后在重绘期间进行setUniformValue() 调用。不确定 Qt 是如何处理重绘的,但如果它自身不连续重绘,您可能还必须触发重绘。 在你的updateTime方法中setUniformValue之前需要绑定你的程序吗? 【参考方案1】:

我的猜测是您正在正确更新时间,但您没有重新绘制小部件。您应该在 updateTime 结束时调用重新绘制小部件的函数(我认为该函数的名称是 repaint())。

【讨论】:

谢谢,我尝试添加更新并重新绘制,但我认为这不是问题所在。我想一个更好的问题可能是我应该如何调试这个?我不知道有什么方法可以单步执行我提供的着色器代码

以上是关于统一值和 OpenGL 着色器的主要内容,如果未能解决你的问题,请参考以下文章

C ++ / OpenGL glm无法将矩阵插入着色器中的统一

此顶点着色器中的统一浮动不起作用

OpenGL:将随机位置传递给顶点着色器

对于 OpenGL 着色器,您将如何用 C++ 编写一个接受所有类型的统一函数?

如何将变量(不统一)浮点值从 C++ 传递到顶点着色器 OpenGL ES 2.0

opengl ---几何着色器