簡體   English   中英

OpenGLES2 iOS頂點數組對象在drawElements上導致錯誤的訪問錯誤

[英]OpenGLES2 iOS vertex array objects causing bad access error on drawElements

今天下午,當我從使用VBO轉到VAO / VBO時,我一直在抨擊我的openGLES2.0代碼。 基本上我正在通過Apple對openGLES的“專家”建議工作,並且轉向使用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);

}

這是渲染方法

- (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];

}

最后,我的create和bind 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);

我必須對頂點數組對象做一些愚蠢的事情......但有人能弄明白問題是什么嗎?

啟用頂點數組的標志是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。

你應該在glBindBuffer函數調用之后調用glVertexAttribPointer

我有類似的問題,不知道是什么導致它。

最終我發現我必須在glDrawArrays中放入一個const int數量的頂點。 sizeof()做得不對。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM