5

私の頂点シェーダーは、

uniform Block1{    vec4 offset_x1;   vec4 offset_x2;}block1;

out float value;

in vec4 position;

void main()
{
    value = block1.offset_x1.x + block1.offset_x2.x;            

    gl_Position = position;
}

値を渡すために使用しているコードは次のとおりです。

GLfloat color_values[8];// contains valid values

glGenBuffers(1,&buffer_object);

glBindBuffer(GL_UNIFORM_BUFFER,buffer_object);

glBufferData(GL_UNIFORM_BUFFER,sizeof(color_values),color_values,GL_STATIC_DRAW);

glUniformBlockBinding(psId,blockIndex,0);

glBindBufferRange(GL_UNIFORM_BUFFER,0,buffer_object,0,16);                                              

glBindBufferRange(GL_UNIFORM_BUFFER,0,buffer_object,16,16);

ここで私が期待しているのは、vec4 ユニフォームごとに 16 バイトを渡すことです。offset=16 、size = 16 で GL_INVALID_VALUE エラーが発生しました。オフセット値と混同しています。仕様によると、「buffer_object」に対応しています。

4

1 に答える 1

8

バインド時の UBO にはアラインメントの制限があります。AnyglBindBufferRange/Baseのオフセットは の倍数でなければなりませんGL_UNIFORM_BUFFER_OFFSET_ALIGNMENT。このアラインメントは何でもかまいません。そのため、ユニフォーム バッファーの配列を作成する前にクエリを実行する必要があります。つまり、コンパイル時の C++ ロジックで直接行うことはできません。ランタイム ロジックである必要があります。

実行時のクエリについて言えば、コードは他の多くの点で恐ろしく壊れています。ユニフォーム ブロックのレイアウト修飾子を定義していません。したがって、デフォルトが使用されます: shared. また、OpenGL から各ブロックのメンバーのレイアウトを照会せずに「shared* レイアウト」を使用することはできません。今まで

クエリを実行した場合、uniform ブロックのサイズが 16 バイトではなく、少なくとも32 バイトであることがすぐにわかります。また、範囲内に 16 バイトしか指定していないため、未定義の動作 (プログラム終了の可能性を含む) が発生します。 .

均一なブロック定義に正確にマップする C/C++ オブジェクトを定義できるようにしたい場合は、std140レイアウトを使用し、C/C++ オブジェクトで のレイアウトの規則に従う必要がありstd140ます。

于 2012-10-23T18:19:48.210 に答える