C++ 当使用IBO/EBO时,仅当我在创建VAO后调用glBindBuffer绑定IBO/EBO时,程序才起作用

C++ 当使用IBO/EBO时,仅当我在创建VAO后调用glBindBuffer绑定IBO/EBO时,程序才起作用,c++,c,opengl,vbo,vao,C++,C,Opengl,Vbo,Vao,由于某些原因,只有在创建VAO后再次绑定IBO/EBO时,此程序才起作用。我在网上和多篇SO帖子中读到,glBindBuffer只绑定当前缓冲区,而不将其附加到VAO。我认为glVertexAttributePointer是将数据附加到VAO的函数 float points[] = { -0.5f, 0.5f, 0.0f, // top left = 0 0.5f, 0.5f, 0.0f, // top right = 1 0.5f, -0.5f,

由于某些原因,只有在创建VAO后再次绑定IBO/EBO时,此程序才起作用。我在网上和多篇SO帖子中读到,glBindBuffer只绑定当前缓冲区,而不将其附加到VAO。我认为glVertexAttributePointer是将数据附加到VAO的函数

float points[] = {

   -0.5f,  0.5f, 0.0f, // top left      = 0
    0.5f,  0.5f, 0.0f, // top right     = 1
    0.5f, -0.5f, 0.0f, // bottom right  = 2
   -0.5f, -0.5f, 0.0f, // bottom left   = 3

};

GLuint elements[] = {

    0, 1, 2,
    2, 3, 0,
};

// generate vbo (point buffer)
GLuint pb = 0;
glGenBuffers(1, &pb);
glBindBuffer(GL_ARRAY_BUFFER, pb);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);

// generate element buffer object (ibo/ebo)
GLuint ebo = 0;
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

// generate vao
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);


glBindBuffer(GL_ARRAY_BUFFER, pb);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);


glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); // when I bind buffer again, it works


glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
如果我没有第二个glBindBuffer,程序就会崩溃。我想知道的是,为什么在创建VAO之后,当调用glBindBuffer时,我必须再次调用glBindBuffer,因为它只会使该缓冲区成为其他函数的活动缓冲区


如果查看规范,顶点数组对象状态不包括元素缓冲区对象


实际上,启用VAO不会设置元素bindibg点

问题在于您最初通话的顺序。
GL\u元素\u数组\u缓冲区
绑定是VAO状态的一部分。看看这个序列:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
由于
GL\u元素\u数组\u缓冲区
绑定是VAO状态的一部分,因此序列末尾的
glBindVertexArray()
调用将建立
GL\u元素\u数组\u缓冲区
缓冲区绑定,该绑定是要绑定的VAO
VAO
的一部分。因为您刚刚创建了
vao
,所以它是
0
。因此,在这个序列的末尾,没有元素数组缓冲区绑定

或者,从另一个方向看,当您在开始时进行
glBindBuffer(GL\u ELEMENT\u ARRAY\u BUFFER,ebo)
调用时,VAO
0
被绑定。因此,此绑定成为VAO
0
状态的一部分。然后,当您绑定不同的VAO
VAO
时,您将丢失绑定,并将其替换为VAO
VAO
状态的一部分绑定

要使这项工作如您所期望的那样工作,您需要在绑定VAO后进行初始
GL\u元素\u数组\u缓冲
binding。然后,它将成为VAO状态的一部分,并将在以后每次绑定VAO时再次建立:

GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);

很抱歉直言不讳,但这是完全错误的。元素缓冲区绑定是VAO状态的一部分。也许我需要再次阅读OpenGL规范。。。最近我写不出关于OpenGL的正确答案。Sob.例如,如果您手头有OpenGL 3.3规范文档,请查看第281页的表6.5。该表名为“顶点数组对象状态”,包含
元素数组缓冲区绑定