2

私は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);
}
4

1 に答える 1

4

プレーンOpenGL(Qtなし)を使用する場合、への呼び出しglUniformは、対応するプログラムがアクティブである場合にのみ有効です(を使用glUseProgram)。また、QGLShaderProgram'setUniformと関数はそれぞれとのbind単純なラッパーである必要があるため、関数呼び出しの順序を次のように変更する必要があります。glUniformglUseProgram

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

したがって、プログラムがバインドされるときは、常にプログラムのユニフォームを設定してください。ただし、一方で、ユニフォームの値はプログラムのバインドとバインド解除に対して永続的であるため、変更されない限り、プログラムをバインドするたびにユニフォームを設定する必要はありません。

ドキュメントにこの問題について何も書かれていないのは悲しいことです。しかし、対応するQt関数によってラップされるGL関数に名前を付けているので、OpenGLをいじって、とにかくこれらの事実を知っている人を想定していると思います(実際、これらは単なる軽量ラッパーであり、それ自体に新しいインターフェイスはありません)。

于 2012-07-01T10:37:57.453 に答える