我希望OpenGL ES 2.0中的顶点数组对象保存来自不同缓冲区的两个属性,第二个缓冲区是从客户端内存(glBindBuffer(GL_ARRAY_BUFFER, 0))读取的,但是出现运行时错误:

GLuint my_vao;
GLuint my_buffer_attrib0;
GLfloat attrib0_data[] = { 0, 0, 0, 0 };
GLfloat attrib1_data[] =  { 1, 1, 1, 1 };

void init()
{
    // setup vao
    glGenVertexArraysOES(1, &my_vao);
    glBindVertexArrayOES(my_vao);

    // setup attrib0 as a vbo
    glGenBuffers( 1, &my_buffer_attrib0 );
    glBindBuffer(GL_ARRAY_BUFFER, my_buffer_attrib0);
    glBufferData( GL_ARRAY_BUFFER, sizeof(attrib0_data), attrib0_data, GL_STATIC_DRAW );
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

    glEnableVertexAttribArray( 0 );
    glEnableVertexAttribArray( 1 );

    // "end" vao
    glBindVertexArrayOES( 0 );

}

void draw()
{

    glBindVertexArrayOES(my_vao);
    // (now I assume attrib0 is bound to my_buffer_attrib0,
    //  and attrib1 is not bound. but is this assumption true?)

    // setup attrib1
    glBindBuffer( GL_ARRAY_BUFFER, 0 );
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, attrib1_data);

    // draw using attrib0 and attrib1
    glDrawArrays( GL_POINTS, 0, 1 );  // runtime error: Thread1: EXC_BAD_ACCESS (code=2, address=0x0)

}

我要实现的是将两个属性的绑定(bind)包装为顶点数组缓冲区:
void draw_ok()
{
    glBindVertexArrayOES( 0 );

    // setup attrib0
    glBindBuffer( GL_ARRAY_BUFFER, my_buffer_attrib0 );
    glVertexAttribPointer( 0, 4, GL_FLOAT, GL_FALSE, 0, 0);

    // setup attrib1
    glBindBuffer( GL_ARRAY_BUFFER, 0 );
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, attrib1_data);

    glEnableVertexAttribArray( 0 );
    glEnableVertexAttribArray( 1 );

    // draw using attrib0 and attrib1
    glDrawArrays( GL_POINTS, 0, 1);  // ok
}

是否可以在顶点数组对象中绑定(bind)两个不同的缓冲区? OES_vertex_array_object与(普通的)OpenGL顶点数组对象是否不同?还要注意,我在运行iOS模拟器的XCode中遇到此错误。这些是相关链接:
  • Use of VAO around VBO in Open ES iPhone app Causes EXC_BAD_ACCESS When Call to glDrawElements
  • OES_vertex_array_object
  • 最佳答案

    好吧,引自扩展规范的引言很简单地说明了这一点:



    因此,您确实可以在VAO中绑定(bind)两个不同的缓冲区(嗯,无论如何,缓冲区绑定(bind)并不存储在VAO中,仅通过glVertexAttribPointer设置各个属性的源缓冲区),但是您不能在VAO中使用客户端空间内存VAO,仅VBO。对于桌面GL来说是相同的。

    因此,我建议您将所有顶点数据存储在VBO中。如果您想使用客户端内存,因为数据是动态更新的,并且您认为VBO不会在那里买东西,那仍然是错误的方法。只需使用具有动态用法的VBO(GL_DYNAMIC_DRAW甚至GL_STREAM_DRAW),然后使用glBuffer(Sub)DataglMapBuffer(或旧的glBufferData(..., NULL); glMapBuffer(GL_WRITE_ONLY)组合)对其进行更新。

    关于opengl-es - OES_vertex_array_object和客户端状态,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9536973/

    10-12 18:09