我正在和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();
}
Fragment Shader:
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);
}
答案 0 :(得分:4)
当使用普通OpenGL(没有Qt)时,如果相应的程序处于活动状态(使用glUniform
),则对glUseProgram
的调用才有效。由于QGLShaderProgram
的{{1}}和setUniform
函数应该分别是bind
和glUniform
的简单包装,因此您应该将函数调用的顺序更改为:
glUseProgram
因此,在程序绑定时始终设置程序的制服。但另一方面,制服的值对程序的绑定和解除绑定是持久的,因此如果它们不更改,则每次绑定程序时都不必设置它们。
虽然文档没有说明这个问题,但很遗憾。但是因为它命名由相应的Qt函数包装的GL函数,我猜他们只是假设任何人都在乱解OpenGL以了解这些事实(事实上它们只是轻量级包装器而且本身没有新的接口)。