gpt4 book ai didi

opengl - VAO 和元素缓冲区对象

转载 作者:行者123 更新时间:2023-12-02 05:32:28 27 4
gpt4 key购买 nike

我一直在阅读一些有关 VAO 如何与 VBO 配合使用的内容。据我了解,当我们调用 glVertexAttribPointer 时,VAO 仅存储有关 VBO 的状态信息。我的问题是,它何时存储有关 EBO 的状态(用于索引绘图),当调用 glVertexAttribPointer 时是否保存两者的状态?

//Vertices of the rectangle
std::vector<GLfloat> vertices
{
0.5f, 0.5f, 0.0f, // Top Right
0.5f, -0.5f, 0.0f, // Bottom Right
-0.5f, 0.5f, 0.0f, // Top Left
-0.5f, -0.5f, 0.0f, // Bottom Left
};

//Indices of the triangle
std::vector<GLuint> indices
{
0, 1, 3,
0, 3, 2
};


GLuint VAO, VBO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);

glBindVertexArray(VAO); //Bind the VAO

//Bind the buffers
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);

glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), &vertices[0], GL_STATIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);

glBindVertexArray(0); //Unbind the VAO

//Supply Index Buffer information
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

//Custom shader class that stores the program to be used at render time
Shader shader("..path_to_shader\\shaders\\vertexshader.vert", "..path_to_shader\\shaders\\fragmentshader.frag");

while (!glfwWindowShouldClose(window))
{
glUseProgram(shader.Program());
glBindVertexArray(VAO); //Bind the VAO to draw.
glClearBufferfv(GL_COLOR, 0, &color[0]);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);

glfwPollEvents();
glfwSwapBuffers(window);

glBindVertexArray(0);
glUseProgram(0);
}

最佳答案

当您使用以下方式绑定(bind)时,GL_ELEMENT_ARRAY_BUFFER 绑定(bind)将成为 VAO 状态的一部分:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...);

当 VAO 已绑定(bind)时。

请注意,在没有 VAO 绑定(bind)的情况下绑定(bind)元素数组缓冲区也是合法的。这仅在使用 glBufferData() 或类似调用填充数据时才真正有用。由于在 Core Profile 中,您需要为任何绘制调用绑定(bind) VAO,因此您需要在绑定(bind) VAO 时绑定(bind)要用于渲染的元素数组缓冲区。

关于您的代码,您使用的调用顺序不会给出所需的结果。以下是您接到的关键电话,并附有解释结果的评论:

glBindVertexArray(VAO);
// VAO is now bound. If this is the first time, it will have the default VAO state.

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
// The element array buffer is bound, and this binding becomes part of the VAO state.

glBindVertexArray(0);
// The VAO is unbound. Since the element array buffer binding was part of the
// VAO state, the element array buffer is also unbound.

glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint),
&indices[0], GL_STATIC_DRAW);
// This will not work, since you do not have an element array buffer bound.

要使其正常工作,最简单的解决方案是更改最后两个调用的顺序:

glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint),
&indices[0], GL_STATIC_DRAW);
// The currently bound element array buffer is filled with data.

glBindVertexArray(0);
// The VAO is unbound. Since the element array buffer binding was part of the
// VAO state, the element array buffer is also unbound.

为了进一步探索这一点,以下序列也可以:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
// The element array buffer is bound, Since no VAO is bound, the binding becomes
// part of the global state (or more precisely, of the default VAO 0).
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint),
&indices[0], GL_STATIC_DRAW);
// The currently bound element array buffer is filled with data.

glBindVertexArray(VAO);
// VAO is now bound. If this is the first time, it will have the default VAO state.
// Since the element array binding is part of the VAO state, the previously bound
// element array buffer is not bound anymore.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
// The element array buffer is bound, and this binding becomes part of the VAO state.
glBindVertexArray(0);
// The VAO is unbound. Since the element array buffer binding was part of the
// VAO state, the element array buffer binding is restored to the binding that
// was current before the VAO was bound.

注意,在这个序列中,绑定(bind)VAO后必须再次绑定(bind)元素数组缓冲区,因为一旦绑定(bind)VAO,VAO状态下的元素数组缓冲区绑定(bind)就会覆盖当前绑定(bind)。

关于opengl - VAO 和元素缓冲区对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33863426/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com