4

今日の午後、VBO の使用から VAO / VBO の使用に移行したときに openGLES2.0 コードが正しく動作するように、壁に頭をぶつけてきました。基本的に、私は openGLES に関する Apple の「専門家」のアドバイスに従って作業を進めており、Vertex Array Objects の使用に移行することがリストのトップでした ...

ここで同様の質問と回答を確認しましたが、他の人が同様の問題に遭遇したことを再確認したことを除いて、それは私には役に立たなかったようです:(

私のシナリオでは、約 500 個の長方形のテクスチャが画面上を移動しています。コードはすべて VAO なしで正常に動作しますが、USE_VAO (私の定数) を定義すると、最初の描画要素呼び出しでクラッシュします。私は明らかにVAOを正しく理解していません...しかし、私は自分のやり方のエラーを見ることができません!

setupBeforeRender メソッドは、レンダリング ループに入る前のセットアップの最後の部分として呼び出されます。

-(void) setupBeforeRender {

glClearColor(0.6, 0.6, 0.6, 1);
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
glEnable(GL_DEPTH_TEST);

glUniform1i(_textureUniform, 0);
glActiveTexture(GL_TEXTURE0); 

glEnableVertexAttribArray(_positionSlot);
glEnableVertexAttribArray(_colorSlot);
glEnableVertexAttribArray(_texCoordSlot);


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

}

そして、これがrenderメソッドです

- (void)render:(CADisplayLink*)displayLink {

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Model view matrix and projection code removed for clarity

GLsizei stride = sizeof(Vertex);
const GLvoid* colourOffset = (GLvoid *) sizeof(float[3]);
const GLvoid* textureOffset = (GLvoid *) sizeof(float[7]);

 for (my objectToDraw in objectToDrawArray)
 {

    if (objectToDraw.vertexBufferObject == 0)
    {

        #ifdef USE_VAO

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

        glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, stride, 0);
        glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, stride, colourOffset);
        glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE,stride, textureOffset);    

        objectToDraw.vertexBufferObject = [objectToDraw createAndBindVBO];
        objectToDraw.vertexArrayObject = _vao;
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArrayOES(0);

        #else

        objectToDraw.vertexBufferObject = [objectToDraw createAndBindVBO];

        #endif
    }

   // Texture binding removed for clarity     

    #ifdef USE_VAO

    // This code crashes with EXC_BAD_ACCESS on the glDrawElements  

    glBindVertexArrayOES(objectToDraw.vertexArrayObject);
    glDrawElements(GL_TRIANGLES, sizeof(Indices) / sizeof(Indices[0]), GL_UNSIGNED_SHORT,0);
    glBindVertexArrayOES(0);                

    #else        

    // This path works fine. So turning VAO off works :(

    glBindBuffer(GL_ARRAY_BUFFER, storyTile.vertexBufferObject);
    glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, stride, 0);
    glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, stride, colourOffset);
    glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE, stride, textureOffset);

    glDrawElements(GL_TRIANGLES, sizeof(Indices) / sizeof(Indices[0]), GL_UNSIGNED_SHORT,0);

    #endif

} // End for each object

[_context presentRenderbuffer:GL_RENDERBUFFER];

}

最後に、VBO の作成とバインドのメソッドは次のようになります。

-(GLuint) createAndBindVBO {

const float* rgba = CGColorGetComponents([self.colour CGColor]);

Vertex Vertices[] = {
    {{0, 1, 0}, {1, 0, 1, 1}, {0,1}},
    {{0, 0, 0}, {1, 0, 1, 1}, {0,0}},
    {{1, 1, 0}, {1, 0, 1, 1}, {1,1}},
    {{1, 0, 0}, {1, 0, 1, 1}, {1,0}}

};

// Code removed for clarity - sets up geometry and colours    

GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);

return vertexBuffer;
}

これのさまざまな順列を試し、コードに glGetError() を振りかけて、問題が発生した場所を特定するのに役立つかどうかを確認しました。残念ながら、drawElements 呼び出しで BAD_ACCESS がクラッシュする以外、エラーは発生しません。

編集:示唆されているように、残念ながらこれも機能しません

objectToDraw.vertexBufferObject = [objectToDraw createVBO];

glGenVertexArraysOES(1,&_vao);
glBindVertexArrayOES(_vao);
glBindBuffer(GL_ARRAY_BUFFER, objectToDraw.vertexBufferObject);

glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, stride, 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, stride, colourOffset);
glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE,stride, textureOffset);    

objectToDraw.vertexArrayObject = _vao;
glBindVertexArrayOES(0);

私は頂点配列オブジェクトでばかげたことをしているに違いありません...しかし、誰かが問題が何であるかを理解できますか?

4

3 に答える 3

4

頂点配列有効フラグは VAO 状態の一部であるため、VAO がバインドされている間に glEnableVertexAttribArray を使用して頂点属性配列を有効にする必要があります。

出典: http://www.khronos.org/registry/gles/extensions/OES/OES_vertex_array_object.txt

結果の頂点配列オブジェクトは、すべての状態値 (表 6.2 にリストされていますが、ARRAY_BUFFER_BINDING を除く) を含む新しい状態ベクトルです。

  • VERTEX_ATTRIB_ARRAY_ENABLED
  • VERTEX_ATTRIB_ARRAY_SIZE、
  • VERTEX_ATTRIB_ARRAY_STRIDE、
  • VERTEX_ATTRIB_ARRAY_TYPE、
  • VERTEX_ATTRIB_ARRAY_NORMALIZED、
  • VERTEX_ATTRIB_ARRAY_POINTER、
  • ELEMENT_ARRAY_BUFFER_BINDING、
  • VERTEX_ATTRIB_ARRAY_BUFFER_BINDING.
于 2012-07-04T20:09:40.610 に答える
0

私は同様の問題を抱えていましたが、何が原因なのかわかりませんでした。

最終的に、glDrawArrays に const int 数の頂点を入れなければならないことが判明しました。sizeof() は正しく実行されていませんでした。

于 2012-12-05T17:32:24.970 に答える
0

関数呼び出しのglVertexAttribPointer後に呼び出す必要があります。glBindBuffer

于 2012-07-04T19:18:20.267 に答える