gpt4 book ai didi

c++ - VAO 是否同时记住 EBO/IBO(元素或索引)和 VBO?

转载 作者:可可西里 更新时间:2023-11-01 16:38:15 26 4
gpt4 key购买 nike

我的代码正常工作,但这可能是巧合,我不想稍后再讨论错误,所以我尽量保持它的整洁:

我执行以下操作来初始化网格:

  1. 生成并绑定(bind) VBO 和缓冲数据
  2. 生成并绑定(bind) IBO 和缓冲数据
  3. 生成并绑定(bind)VAO
  4. 绑定(bind)与之前相同的 VBO,在 1 中生成。
  5. 启用我需要的顶点属性数组并设置顶点属性指针
  6. 再次绑定(bind)IBO(不知道为什么)
  7. 将 VertexArray 绑定(bind)回 0,这样我就不会弄乱我刚刚创建的 VAO

根据我的理解,VAO 将存储我启用的顶点属性数组的状态。它还将存储我绑定(bind)的 VBO 和 IBO。由于我通过将顶点数组绑定(bind)回 0 来“关闭”了 VAO 上的所有操作,因此我确保没有其他代码会弄乱我的 VAO。所以如果这没问题,我需要渲染的是:

  1. 绑定(bind)VAO
  2. 绘制元素
  3. 解绑VAO(绑定(bind)到0)

这应该会带来 AttribArray 状态以及存储的 VBO 和 IBO。我的问题是:

A. 设置 VertexAttribPointers 后是否需要绑定(bind) IBO?如果是,为什么?

B. VAO 是否真的存储VBO IBO?我听说它只存储绑定(bind)的 last 缓冲区,这意味着我必须像这样呈现:

  1. 绑定(bind)VAO
  2. 绑定(bind)VBO
  3. 绘制元素
  4. 解绑VAO

但这是没有意义的,当它们不存储两个缓冲区对象时为什么要使用 VAO?这不就和绑定(bind) VBO 和 IBO,然后在不绑定(bind) VAO 的情况下绘制元素一样吗?

预先感谢您的帮助。

代码如下:

初始化

// generate VBO
glGenBuffers(1, &m_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, m_vertices.size()*sizeof(GLfloat), m_vertices.data(), GL_STATIC_DRAW);

// generate IBO
glGenBuffers(1, &m_ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size()*sizeof(unsigned short), m_indices.data(), GL_STATIC_DRAW);

// generate VAO
glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);

// set the vertex attribute pointer
glEnableVertexAttribArray(0);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,vertexSize,reinterpret_cast<const GLvoid*>(0));

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);
glBindVertexArray(0);

绘图

glBindVertexArray(m_vao);
glDrawElements(GL_TRIANGLES,size,GL_UNSIGNED_SHORT,reinterpret_cast<const GLvoid*>(0));
glBindVertexArray(0);

还有,如果我这样写是不是更干净了:

  1. 生成并绑定(bind)VAO
  2. 生成并绑定(bind) IBO 和 BufferData
  3. 生成并绑定(bind) VBO 和 BufferData
  4. 我需要的 EnableVertexAttribArrays 并设置 VertexAttribPointers
  5. 解绑VAO(绑定(bind)到0)

看起来更干净了,但我不知道结果是否相同,特别是因为第 4 步和第 5 步之间缺少 IBO 绑定(bind)。

最佳答案

解决您的问题:

A. Do I need to bind the IBO after I set the VertexAttribPointers? If so, why?

没有。您可以先绑定(bind)元素数组(在您的术语中为 IBO),然后再绑定(bind)顶点属性,但一般来说,它们在 VAO 中是单独的绑定(bind)。例如,您可以绑定(bind) IBO 以及多个 VBO,并使用 IBO 中的数据使用 glDrawElements(和变体)或使用 glDrawArrays(和变体)进行渲染) 仅使用 VBO 中的顺序顶点数据 - 渲染命令决定是否使用 IBO。

B. Does the VAO really store both the VBO and the IBO?

是的。一个VAO可以存储单个IBO和至少16个VBO的绑定(bind)信息。

I've heard it only stores the last buffer that was bound, meaning I have to render like this:

Bind VAO
Bind VBO
Draw Elements
Unbind VAO

正如您在原始帖子中推测的那样,此声明是不正确的,并且您包含的 VBO 的绑定(bind)是不必要的。一个 VAO 可以存储依赖于实现的最大(至少为 16)数量的 VBO,每个 VBO 都可以绑定(bind)到一个顶点属性。

Also, isn't it cleaner if I put it like this:

  1. Gen and bind VAO
  2. Gen and bind IBO and BufferData
  3. Gen and bind VBO and BufferData
  4. EnableVertexAttribArrays that I need and set VertexAttribPointers
  5. Unbind VAO (binding to 0)

是的。正如您所指出的,这允许您仅使用三个命令进行绑定(bind)、渲染和清理。

真的,这就是 VAO 的全部要点,收集所有这些绑定(bind)和顶点属性关联,这样您就可以一次完成所有管道,然后稍后即发即弃。

关于c++ - VAO 是否同时记住 EBO/IBO(元素或索引)和 VBO?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17332657/

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