0

出于某种原因,该程序仅在我创建 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(完整代码)

4

2 回答 2

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您正在绑定的 VAO 的一部分。哪一个,因为你刚刚创建vao,是0. 所以在这个序列的最后,你没有绑定元素数组缓冲区。

或者,从不同的方向来看,当你glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)一开始打电话时,VAO0就被绑定了。所以这个绑定成为 VAO 状态的一部分0。然后,当您绑定不同的 VAO 时vao,您会丢失该绑定,并且它会被作为 VAO 状态一部分的绑定替换vao

要使这项工作按预期进行,您需要在绑定 VAOGL_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);
于 2015-07-02T15:22:27.413 回答
-2

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

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

于 2015-07-02T05:32:41.353 回答