带有 glDrawArrays() 的 Draw 函数需要调用两次才能显示任何内容



这是一个奇怪的问题。我有一个功能:

void drawLines(std::vector<GLfloat> lines) {
glBindVertexArray(VAO2);
//positions
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(0);
//colors
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(lines[0]) * lines.size(), &lines[0], GL_STATIC_DRAW);
glUseProgram(pShaderProgram);
glDrawArrays(GL_TRIANGLES, 0, lines.size() / 6);
}

它绘制指定粗细的线条(这内置于lines的数据中,其中包含三个用于位置的浮点数和三个用于颜色的浮点数,每个点有超过 200 个点来标记线尾)。调用该函数一次不会产生任何结果,即使在遵循SwapBuffers(HDC)glFlush()之后也是如此。但是,当我调用该函数两次时,一切都会显示出来。我怀疑在通过渲染管线推送缓冲区时缺少一些细微差别,这些细微差别可能通过多次绑定缓冲区来激活。我不确定。有什么想法吗?

glVertexAttribPointer需要一个绑定到GL_ARRAY_BUFFER绑定点的缓冲区,以便在通用顶点属性和要从中获取数据的缓冲区对象之间建立关联。

但是,在调用glVertexAttribPointer之后,您将缓冲区与glBindBuffer(GL_ARRAY_BUFFER, VBO2)绑定。

这就是您需要两次调用的原因,因为第一次调用不会将任何缓冲区对象与通用顶点属性相关联,因为之前可能没有绑定缓冲区。

但是,您使用VAO的方式是可疑的,因为您在此方法/函数中所做的一切都将保存为VAO状态。因此,您既不需要每次都重新建立通用顶点属性和缓冲区对象之间的关联,也不需要在每次绘制时启用通用顶点属性。

所有这些都可以在为 VAO 执行顶点规范时完成一次

最新更新