3

修正するのにかなりの時間がかかったバグがありました。次の行にコメントするまで、EXC_BAD_ACCESSとmemmoveエラーへの参照を、これ以上の説明なしで取得し続けました。

[自己loadShaders];

glGenVertexArraysOES(1, &_vao);
glBindVertexArrayOES(_vao);

// Vertex Buffer
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);

glEnableVertexAttribArray(ATTRIB_TEXTURE);
glVertexAttribPointer(ATTRIB_TEXTURE, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 7));

// Index Buffer
glGenBuffers(1, &_indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER,0);  

////////// COMMENTED THIS ONE //////////////
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);//
////////////////////////////////////////////

glBindVertexArrayOES(0);

バッファを0にバインドすることはバインドを解除することを意味すると思ったので、それがどのようにアプリをクラッシュさせるのか本当に理解できません。

情報のおかげで!私はこの懸念にとどまりません...

私の構造:

const Vertex Vertices[4] = {
    {{0.75, -1, 0}, {1, 0, 0, 1},     {0.125, 0.833496}},
    {{0.75, 1, 0}, {0, 1, 0, 1},      {0.125, 1}},
    {{-0.75, 1, 0}, {0, 0, 1, 1},     {0,     1}},
    {{-0.75, -1, 0}, {0, 0, 0, 1},    {0,     0.833496}},
};

const GLushort Indices[6] =
{
    0, 1, 2,
    2, 3, 0
};
4

1 に答える 1

10

コードからは、この関数が初期化ルーチンにあるように見えます。このルーチンでは、バインドされたVAOに格納される属性データを初期化するため、描画時にVAOをバインドするだけで済みます。

次に、VAOは、VBOの描画に必要なすべての状態をカプセル化します。これは、属性の有効なフラグ(で設定gl(En/Dis)ableVertexAttribArray)、属性のソースとプロパティ(で設定glVertexAttribPointer)、および現在バインドされているインデックスバッファー(で設定glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...))です。この情報は属性状態で保存されるため、現在バインドされている頂点バッファは保存されないことに注意してください。

つまり、VAOをアクティブにしたまま、インデックスバッファを作成してバインドし、そのデータを設定してから、バインドを解除します。したがって、VAO状態はのGL_ELEMENT_ARRAY_BUFFERバインディングを格納し0ます。あなたが今何かを描くとき

glBindVertexArrayOES(_vao);
glDrawElements(...);

glDrawElementsVAOはクライアント側のアレイでは機能しないため、バッファバウンドはなく、失敗します。インデックスデータにVBOを使用するか、インデックス付けされていないプリミティブを描画する必要があります(を使用glDrawArrays)。

どちらもしません

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
glBindVertexArrayOES(_vao);
glDrawElements(...);

バインドされたインデックスバッファは、バインドされたときにVAOによって上書きされるため(インデックスバッファは0)、機能します。最初にVAOをバインドし、次にインデックスバッファをバインドすると機能しますが、それは問題を回避するだけです。

概念的には、バインドGL_ELEMENT_ARRAY_BUFFERはVAO状態の一部であるため0、VAO初期化ルーチンでバインドしないでください(インデックスデータが必要ない場合のみ)。また、VAOを使用する場合、インデックスまたは頂点データにクライアント側の配列を使用することも許可されていません。ただし、インデックス付きのジオメトリを描画したくない場合は、glDrawArraysの代わりにを使用してください。ただしglDrawElements、とにかく、インデックスバッファは廃止されます。

于 2012-05-25T15:09:05.617 に答える