在Open ES iPhone应用程序中使用VO围绕VBO导致调用glDrawElements时出现EXC_BAD_ACCESS [英] Use of VAO around VBO in Open ES iPhone app Causes EXC_BAD_ACCESS When Call to glDrawElements

查看:318
本文介绍了在Open ES iPhone应用程序中使用VO围绕VBO导致调用glDrawElements时出现EXC_BAD_ACCESS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将我的代码提升到一个新的水平。遵循Apple的一些最佳实践,我试图在我的顶点缓冲对象(VBO)周围实现顶点数组对象。我设置了这样的VBO和VAO:

I'm trying to take my code to the next level. Following some best practices from Apple, I'm trying to implement Vertex Array Objects around my Vertex Buffer Objects (VBO). I setup my VBOs and VAOs like this:

- (void)setupVBOs {  
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArrayOES(0);
    {
        glGenVertexArraysOES(1, &directArrayObject);
        glBindVertexArrayOES(directArrayObject);

    //    GLuint texCoordBuffer;
        glGenBuffers(1, &texCoordBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, texCoordBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(DirectVertices), DirectVertices, GL_STATIC_DRAW);

        glVertexAttribPointer(directPositionSlot, 2, GL_FLOAT, GL_FALSE, sizeof(DirectVertex), (GLvoid*)offsetof(DirectVertex, position));
        glEnableVertexAttribArray(directPositionSlot);
        glVertexAttribPointer(texCoordSlot, 2, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(DirectVertex), (GLvoid*)offsetof(DirectVertex, texCoord));
        glEnableVertexAttribArray(texCoordSlot);

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

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

        glVertexAttribPointer(positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
        glEnableVertexAttribArray(positionSlot);
        glVertexAttribPointer(colorSlot, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Color));
        glEnableVertexAttribArray(colorSlot);

    //    GLuint indexBuffer;
        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);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArrayOES(0);
}

我从 http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=287977 然后像使用它一样这个:

which I took from http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=287977 and then use it like this:

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

    glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glViewport(0, 0, backingWidth, backingHeight);

    [directProgram use];
    glBindVertexArrayOES(directArrayObject);
    glDisable(GL_DEPTH_TEST);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, videoFrameTexture);

//  // Update uniform values
    glUniform1i(videoFrameUniform, 0);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    [program use];
    glBindVertexArrayOES(arrayObject);
    glDisable(GL_TEXTURE_2D);
    glEnable(GL_DEPTH_TEST);

    CC3GLMatrix *projection = [CC3GLMatrix matrix];
    float h = 4.0f * self.frame.size.height / self.frame.size.width;
    [projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10];
    glUniformMatrix4fv(projectionUniform, 1, 0, projection.glMatrix);

    CC3GLMatrix *modelView = [CC3GLMatrix matrix];
    [modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)];
    currentRotation += displayLink.duration * 90;
    [modelView rotateBy:CC3VectorMake(currentRotation, currentRotation, 0)];
    glUniformMatrix4fv(modelViewUniform, 1, 0, modelView.glMatrix);

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

    glBindVertexArrayOES(0);

    BOOL success = [context presentRenderbuffer:GL_RENDERBUFFER];
    if(!success)
        NSLog(@"present failed");
}

对glDrawArrays的调用有效,它填充了我的纹理,但是,调用使用EXC_BAD_ACCESS使glDrawElements失败。我的着色器程序(我使用两个)包含在一个GLProgram对象中,我从 http://iphonedevelopment.blogspot.com/2010/11/opengl-es-20-for-ios-chapter-4.html

The call to glDrawArrays works, and it fills my texture, however, the call to glDrawElements fails with an EXC_BAD_ACCESS. My shader programs (i use two) are wrapped in a GLProgram object that I took from http://iphonedevelopment.blogspot.com/2010/11/opengl-es-20-for-ios-chapter-4.html

推荐答案

从设置功能结束时删除 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);

Remove glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); from the end of your setup function.

根据 OES_vertex_array_object的规范 ,顶点数组对象封装了除数组缓冲区绑定 1 之外的所有状态,因此当时没有绑定元素缓冲区你正在绘制,而你可能想要绑定 indexBuffer 。通过在绑定远离顶点数组对象时绑定 indexBuffer ,确保在返回到该顶点数组对象时它将被反弹。

Per the specification for OES_vertex_array_object, a vertex array object encapsulates all state except the array buffer binding1, so there is no element buffer bound at the time that you’re drawing, whereas you presumably wanted indexBuffer to be bound. By leaving indexBuffer bound at the time that you bind away from your vertex array object, you ensure that it’ll be rebound when you return to that vertex array object.

1 如果您想知道为什么在顶点数组对象中没有跟踪数组缓冲区绑定,这可能是因为从数组中读取顶点数据时没有直接使用当前绑定的数组缓冲区 - 而是每个顶点属性都有自己的缓冲区绑定,它由各自的 gl *指针<填充/ code>函数通过在调用函数时查看数组缓冲区绑定。

1 If you’re wondering why the array buffer binding isn’t tracked in vertex array objects, this is presumably because the currently-bound array buffer isn’t used directly when reading vertex data from arrays—rather, each vertex attribute has its own buffer binding, which is filled out by its respective gl*Pointer function by looking at the array buffer binding when the function is called.

这篇关于在Open ES iPhone应用程序中使用VO围绕VBO导致调用glDrawElements时出现EXC_BAD_ACCESS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆