c - VBO究竟如何保存其内容?

标签 c opengl gpu

我开始学习并面临一些模糊:我不明白我们什么时候为VBO分配内存?

我认为我们在调用 glBufferData 时分配内存,但这是否意味着我们始终保持大量分配的内存独立于我们绑定(bind)的 VAO?所以我只需要为属性绑定(bind)VAO,只是为了告诉GPU从哪个VBO获取数据(已经在GPU上)以及如何解释这些数据......这就是VAO和VBO之间的所有联系,只能通过attribs......

最佳答案

VBO 最有可能(但并非总是!)分配在 GPU 的内存中。直到最近,glBufferData 仍然是在 VBO 上分配内存的唯一方法(如果您使用的是 GL4.5,glBufferStorage 现在是推荐的分配内存的方法)。 VBO 中的数据基本上只是一大堆未知的东西(嗯,GPU 不知道)。从CPU/主内存中,我们调用glBufferData,GPU将分配一 block 内存来保存数据,并将数据从主内存中盲目复制到GPU内存中。 GPU 不知道它包含什么......

VAO 只是缓冲区内存布局的描述。让我们举个例子......

  • VBO1:包含立方体的顶点和法线数据。
  • VBO2:包含球体的顶点和法线数据。

假设法线和顶点被打包到一个如下所示的结构中:

struct VertexNormal {
  float vx, vy, vz;
  float nx, ny, nz;
};

在这两种情况下,所有这些都是正确的:

  • 顶点的偏移量为 0
  • 法线的偏移量为 12(即 3 x sizeof(float))
  • 每个顶点和法线元素的步幅为 24 (6 x sizeof(float))

这些信息需要从CPU传递到GPU,以便GPU在渲染时可以正确地将数据从缓冲区读取到顶点属性中。如果没有这些信息,GPU 只会将 VBO 视为一团未知的东西。

我们将此信息传递给 GPU 的方式是通过 VAO。 VAO 存储有关着色器所需的给定顶点属性的以下信息:

  • 数据类型(GL_FLOAT、GL_INT 等)
  • 元素数量(Vec2、Vec3、Vec4??)
  • 每个元素之间的步幅
  • 包含该数据的缓冲区[又名绑定(bind)点]

对于相当复杂的着色器来说,每个顶点的信息可能会变得相当大,因此我们不想经常设置它。这就是 VAO 的用武之地。我们创建一个 VAO,并用有关顶点着色器的每个输入属性的信息填充它。

鉴于我们的立方体和球体可能使用相同的着色器渲染,并且两个缓冲区中的顶点和法线数据相同,因此在这种情况下我们可以使用 1 VAO(只需更改缓冲区[s])我们正在绑定(bind)到 glVertexArrayVertexBuffers)。

关于c - VBO究竟如何保存其内容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57210517/

相关文章:

c - OpenCL 程序中的未知错误

performance - 如何为 CUDA 内核选择网格和 block 尺寸?

directx - 我的 GPU 中有多少个内核?

用 C 创建更高效​​的矩阵转置代码

传递给 `msgpack_pack_int()` 宏的计数器变量不递增

opengl - 想要一个OpenGL 2D示例(VC++,绘制一个矩形)

C++、OpenGL 裁剪

c - 查找最大数字在数组中出现的次数

c - 如何在不加载其依赖项的情况下加载共享库?

opengl - glDrawElements 不渲染来自 obj 文件的输入