0

これは、画面に描画する単純なコードです。

GLuint vbo;

glGenBuffers(1, &vbo);

glUseProgram(myProgram);

glBindBuffer(GL_ARRAY_BUFFER, vbo);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

//Fill up my VBO with vertex data
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), &vertexes, GL_STATIC_DRAW);

/*Draw to the screen*/

これはうまくいきます。ただし、いくつかの GL 呼び出しの順序を次のように変更してみました。

GLuint vbo;

glGenBuffers(1, &vbo);

glUseProgram(myProgram);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

//Now comes after the setting of the vertex attributes.
glBindBuffer(GL_ARRAY_BUFFER, vbo);

//Fill up my VBO with vertex data
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), &vertexes, GL_STATIC_DRAW);

/*Draw to the screen*/

これにより、プログラムがクラッシュします。GL_ARRAY_BUFFER頂点アトリビュートを設定するだけなのに、VBO をバインドする必要があるのはなぜですか? 私にとっては、glVertexAttribPointerOpenGL が最終的に描画に使用する頂点の形式を設定するだけです。これは VBO に固有のものではありません。したがって、複数の VBO が同じ頂点フォーマットを使用したい場合、VBO 内の頂点を再度フォーマットする必要はありません。

4

2 に答える 2

3

これは、最後の引数がglVertexAttribPointerVBOpointerへのオフセットであるためだと思いますglBindBuffer(nonzero)が、VBOがバインドされていない場合、実際のデータ配列へのポインターであるはずです。したがって、VBO をまったく使用していない場合、最後の引数は になり&vertexes、クラッシュしません。

于 2012-06-23T03:11:57.400 に答える
3

頂点属性を設定しているときに、GL_ARRAY_BUFFER にバインドされた VBO が必要なのはなぜですか?

いいえ、頂点属性を設定するだけではありません。実際には、現在バインドされているバッファー オブジェクトを使用して参照を作成しています。

バッファ オブジェクトがバインドされていない場合、gl…Pointer は、指定されたアドレスを指すプロセス アドレス空間への参照を作成します。あなたの場合、これは null ポインターであるため、頂点を逆参照しようとすると、セグメンテーション違反/アクセス違反が発生します。

私にとって、glVertexAttribPointer が行うことは、OpenGL が最終的に描画に使用する頂点の形式を設定することです。

いいえ。データの取得元への参照も作成します。

これは VBO に固有のものではありません。

はい、実際にはバインドされた VBO、または VBO がバインドされていない場合はプロセスのアドレス空間に固有です。また、バッファ バインディングを変更しても、gl…Pointer 参照に沿って更新されません。

于 2012-06-23T11:20:33.143 に答える