当使用IBO / EBO时,程序仅在我创建VAO后调用glBindBuffer绑定IBO / EBO时才有效

时间:2015-07-02 05:27:46

标签: c++ c opengl vbo vao

出于某种原因,此程序仅在我创建VAO后绑定IBO / EBO 时才有效。我在线阅读和多个SO帖子,glBindBuffer只绑定当前缓冲区,并且将它附加到VAO。我认为glVertexAttribPointer是将数据附加到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时,只使缓冲区成为其他函数的活动缓冲区。

Pastebin (FULL CODE)

2 个答案:

答案 0 :(得分:2)

问题在于您的初始通话顺序。 GL_ELEMENT_ARRAY_BUFFER绑定是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_ELEMENT_ARRAY_BUFFER绑定是VAO状态的一部分,序列末尾的glBindVertexArray()调用将建立GL_ELEMENT_ARRAY_BUFFER缓冲区绑定,它是VAO的一部分{{1你有约束力。自您刚刚创建vao以来,vao0。因此,在此序列的末尾,您没有绑定元素数组缓冲区。

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

为了使这项工作符合您的预期,您需要在绑定VAO后之后进行初始GL_ELEMENT_ARRAY_BUFFER绑定。然后它成为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);

答案 1 :(得分:-2)

如果查看规范,Vertex Array Object状态不包含Element Buffer Object。

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