Qt 数组的 GLSL 统一始终为零

Posted

技术标签:

【中文标题】Qt 数组的 GLSL 统一始终为零【英文标题】:GLSL uniform always zero for Qt arrays 【发布时间】:2012-06-30 23:17:55 【问题描述】:

我正在使用 Qt。我有多个着色器在工作,但是传递统一数组似乎总是将全部设置为零。预期的结果是在纹理顶部绘制随机圆圈(或者由于圆圈太多而只是透明纹理)..我得到的是右下角的单个粒子圆圈。

if (program->isLinked()) 
    QVector3D hitPoints[40];

    for (int k = 0; k < 40; k++) 
        hitPoints[k] = QVector3D((float)rand()/(float)RAND_MAX, (float)rand()/(float)RAND_MAX, (float)rand()/(float)RAND_MAX);
    

    program->setUniformValueArray("hitPoints", hitPoints, 40);
    program->bind();

片段着色器:

uniform sampler2D color_texture;
uniform vec3 hitPoints[40];


void main()

    float dist = 0.3;
   vec2 texcoord = vec2(gl_TexCoord[0]);
   for (int i = 0; i < 40; i++) 
       float close = sqrt(pow(hitPoints[i].y - texcoord.y, 2) + pow(hitPoints[i].x - texcoord.x, 2));
       if (close < dist) 
            gl_FragColor = vec4(0,0,0,texture2D(color_texture, texcoord).a);
            return;
        
   
   gl_FragColor = texture2D(color_texture, texcoord);

【问题讨论】:

【参考方案1】:

当使用普通 OpenGL(没有 Qt)时,对 glUniform 的调用只有在相应的程序处于活动状态时才有效(使用 glUseProgram)。由于QGLShaderProgramsetUniformbind 函数应该分别是glUniformglUseProgram 的简单包装,因此您应该将函数调用的顺序更改为:

program->bind();
program->setUniformValueArray("hitPoints", hitPoints, 40);

因此在程序绑定时总是设置程序的制服。但另一方面,uniform 的值在程序的绑定和解除绑定上是持久的,因此如果它们不改变,则不必在每次绑定程序时都设置它们。

虽然文档没有说明这个问题,但很遗憾。但由于它命名了由相应 Qt 函数包装的 GL 函数,我猜他们只是假设任何使用 OpenGL 的人都知道这些事实(实际上它们只是轻量级包装器,本身没有新接口)。

【讨论】:

以上是关于Qt 数组的 GLSL 统一始终为零的主要内容,如果未能解决你的问题,请参考以下文章

iPhone GLSL 动态分支问题

NIB 中的导航项始终为零

Mac QT统一工具栏中选中的工具栏按钮与标题栏边框之间的间隙需要减少为零

创建一个 GLSL 制服数组?

GLSL 结构数组 - 内存分配/对齐

GLSL 每个顶点固定大小的数组