OpenGL 顶点缓冲区绑定点可以在不同的 VAO 之间重用吗?

2023-11-23

假设我使用新的(从 OpenGL 4.3 开始)glBindVertexBuffer 机制设置了两个 VAO:

glGenVertexArrays(1, &vaoIndex0);
glGenVertexArrays(1, &vaoIndex1);

...

glBindVertexArray(vaoIndex0)
glBindVertexBuffer(bindingIndex0, ...)
glEnableVertexAttribArray(0)
glVertexAttribFormat(0, ...)
glVertexAttribBinding(0, bindingIndex0)
...
glBindVertexArray(0)

...

glBindVertexArray(vaoIndex1)
glBindVertexBuffer(bindingIndex1, ...)
glEnableVertexAttribArray(0)
glVertexAttribFormat(0, ...)
glVertexAttribBinding(0, bindingIndex1)
...
glBindVertexArray(0)

假设两者是独立的,除非它们存在于同一 OpenGL 上下文中;它们绑定不同的缓冲区并用于绘制不同的东西。

BindingIndex0 是否需要与 BindingIndex1 不同?两个指数的相等(或不相等)有什么意义吗?

...

EDIT:

在收到答案后,我开始明白,对于真正知道什么是“顶点缓冲区绑定点”,特别是其范围是什么的人来说,我的问题似乎提出了与我的意图不同的问题。也许更好的措辞是“是否需要特意阻止 OpenGL 顶点缓冲区绑定点indices为了防止冲突而被重用,甚至跨多个 VAO?”但无论如何,似乎这两个问题现在都已经得到了解答:不,你不能重用“绑定点”,不,你不需要避免索引以这种方式发生冲突。


所有这些调用都会修改 VAO 状态。因此,您不能在 VAO 之间重复使用这些设置。您当然可以在多个 VAO 中将它们设置为相同,但是在设置每个 VAO 时必须进行一次必要的状态设置调用。

The bindingIndex0 and bindingIndex1您在代码片段中使用的值没有任何特殊含义。它们只是在您绑定到绑定索引的缓冲区之间建立连接glBindVertexBuffer(),以及您指定为使用该绑定索引的属性。

唯一的条件是绑定索引必须小于您可以查询的值MAX_VERTEX_ATTRIB_BINDINGS,保证至少为 16。由于这些调用会修改每个 VAO 状态,因此您绝对可以对多个 VAO 使用相同的绑定索引。

查看这些较新的状态设置调用的一种方法是,它们引入了以前不可用的间接级别:

  • 如果没有这些调用,您可以通过调用在顶点属性和缓冲区之间建立直接连接glVertexAttribPointer()当所需的缓冲区已绑定时。
  • 通过这些较新的调用,顶点属性现在具有到绑定索引的连接,该连接是通过以下方式建立的glVertexAttribBinding()。然后将绑定索引连接到一个缓冲区,该缓冲区是通过以下方式建立的glBindVertexBuffer().

换句话说,在旧式中,连接是:

attribute index --> buffer

这些 4.3+ 调用的新样式:

attribute index --> buffer index --> buffer

这种新的灵活性的优点之一是您可以通过一次调用将新缓冲区绑定到多个属性。只要所有这些属性具有相同的缓冲区索引,您只需调用一次glBindVertexBuffer()为所有属性指定一个新的缓冲区。

半正式定义

以下根本不是官方符号。我刚刚弥补了。但我认为通过写下一些伪数据结构来更正式地定义关系可能会很有用。

假设每个 VAO 包含两个数组来捕获上面解释的连接:

struct VAO {
    ...
    uint bufferIndexBindings[MAX_VERTEX_ATTRIB_BINDINGS];
    uint attribBufferIndices[MAX_VERTEX_ATTRIBS];
}

这里讨论的两个调用将修改这个结构,如下所示:

glBindVertexBuffer(uint bindingIndex, uint buffer, ...) {
    CurrentVAO.bufferIndexBindings[bindingIndex] = buffer;
}

glVertexAttribBinding(uint attribIndex, uint bindingIndex) {
    CurrentVAO.attribBufferIndices[attribIndex] = bindingIndex;
}

然后使用该状态来获取具有索引的给定属性的缓冲区attribIndex as:

CurrentVAO.bufferIndexBindings[CurrentVAO.attribBufferIndices[attribIndex]]

这也说明了我上面解释的间接,它在这里显示为对状态表的两级查找。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OpenGL 顶点缓冲区绑定点可以在不同的 VAO 之间重用吗? 的相关文章

  • 编写每个三角形/面具有纯色的 GLSL 片段着色器的方法

    我有顶点和三角形数据 其中包含每个数据的颜色triangle 面 不是每个顶点 即单个顶点由多个面共享 每个面可能具有不同的颜色 我应该如何在 GLSL 中解决这个问题以获得每个的纯色分配face正在渲染 通过平均顶点相邻多边形的颜色来计算
  • 使用 GLFW + GLEW 时 glGenFramebuffers() 访问冲突

    我收到此错误 执行位置 0x00000000 时发生访问冲突 当我在 Windows 上使用 GLFW GLEW 时 我使用的是 Windows 7 我也有自己的实现 从头开始 它创建一个窗口 初始化 OpenGL 上下文 初始化 GLEW
  • OpenGL C++ 鼠标光线拾取 glm:unproject

    我目前正在开发 C 游戏引擎 我想在应用程序中构建鼠标交互 我之前通过光线拾取完成了此操作 但当时我使用了固定的鼠标位置 现在我想不使用它 我读到您可以使用 glm unProject 函数来执行此操作 但我的函数不起作用 该函数给出的坐标
  • cmake 在 OS X 上找不到 gl.h

    我在 OS X 10 10 上并尝试使用 GLUT 和 OpenGL 构建一个 C 项目 我将其简化为展示我的问题的最小示例 我有以下内容CMakeLists txt cmake minimum required VERSION 2 8 F
  • 在 OpenGL 着色器中检测 NaN 的最佳方法

    今天早上我遇到了一个似乎神秘的错误 我很幸运能够很快找到解决方案 我除以计数器以生成片段着色器内部的平均值 当然 当计数器为零时 所得的颜色值变为 NaN 在混合过程中 NVidia 优雅地将 NaN 视为 0 值 但 Intel 没有这样
  • 从活动顶点数组生成平滑法线

    我正在尝试通过挂钩 OpenGl 调用来破解和修改旧版 opengl 固定管道游戏的多个渲染功能 而我当前的任务是实现着色器照明 我已经创建了一个适当的着色器程序 可以正确照亮大部分对象 但该游戏的地形是在没有提供正常数据的情况下绘制的 游
  • OpenGL:仅使用一个帧缓冲区并切换目标纹理

    我是否可以只创建一个帧缓冲区对象并通过在需要时切换其目标纹理来实现相同的结果 而不是使用多个帧缓冲区对象 在所有情况下这都是一个坏主意吗 如果是 为什么 我一直在实现一个功能render SetTargetTexture 在我的程序的 AP
  • 模拟绘画应用的笔触

    我正在尝试编写一个应用程序 可用于使用模拟笔触创建看起来像绘画的图片 是否有任何好的资源可以提供模拟笔触的简单方法 例如 给定用户拖动鼠标经过的鼠标位置列表 画笔宽度和画笔纹理 如何确定要在画布上绘制的内容 我尝试将画笔纹理倾斜到鼠标移动的
  • 3D 图形矩阵 4x4 中最后一行的 magic 4 的用途是什么?

    当我阅读有关WebGL的书时 我看到了下一个矩阵描述 有关于书中最后一行的信息 WebGL 初学者指南 初学者指南 Diego Cantor Brandon Jones 神秘的第四排 第四排没有任何特殊之处 意义 元素 m4 m8 m12
  • 静态链接库时出现 glew 链接器错误

    我正在尝试在 Visual Studio 2012 中构建一个 opengl 项目 我想静态包含 glew 库 因此我从源代码构建它并将生成的 glew32sd lib 复制到我的 lib 目录 我将此 lib 路径提供给 Visual S
  • OpenGL NURBS 曲面

    我正在学习 OpenGL 我想要一个中间有轻微驼峰的表面 我目前正在使用这段代码 但我不确定如何调整 ctrl 点以使其达到我想要的方式 它目前就像 我想要这样的 我不完全确定我应该使用哪些控制点 并且我对其工作原理感到困惑 include
  • 交错顶点提交如何提高性能?

    我已经阅读并看到了其他问题 这些问题通常都指向将顶点位置和颜色等交错到一个数组中的建议 因为这可以最大限度地减少从 cpu 发送到 gpu 的数据 我不清楚的是 即使使用交错数组 您仍然必须对位置和颜色指针进行单独的 GL 调用 OpenG
  • 哪个对缓存最友好?

    我试图很好地掌握面向数据的设计以及如何在考虑缓存的情况下进行最佳编程 基本上有两种情况我无法完全确定哪个更好以及为什么 是拥有一个对象向量更好 还是拥有对象原子数据的多个向量更好 A 对象向量示例 struct A GLsizei mInd
  • CPU 到 GPU 法线映射

    我正在创建一个地形网格 然后这个答案 https stackoverflow com a 5284527 1356106我正在尝试将 CPU 计算法线迁移到基于着色器的版本 以便通过降低网格分辨率并使用在片段着色器中计算的法线贴图来提高性能
  • 在 OpenGL 中,为什么 glVertexAttribPointer 要求“指针”参数以 void* 形式传入?

    规格为glVertexAttribPointer如下 void glVertexAttribPointer GLuint index GLint size GLenum type GLboolean normalized GLsizei s
  • gluPerspective 与 gluOrtho2D

    我查看了 MSDN 上关于这两个函数的文档 但是 我不太明白这两个功能之间的区别 一个是用于设置 3D 相机视图 另一个是用于设置 2D 相机视图 如果能得到解答就太好了 预先感谢您的评论 正交投影基本上是没有透视的 3D 投影 本质上 这
  • 使用 glDrawElements 时在 OpenGL 核心配置文件中选取三角形

    我正在使用 glDrawElements 绘制三角形网格 并且希望能够使用鼠标单击来拾取 选择三角形 三角形的网格可以很大 在固定功能 OpenGL 中 可以使用 GL SELECT http content gpwiki org inde
  • 即使在顶点着色器中使用,glGetUniformLocation()也会返回-1

    我正在尝试用法线渲染一个简单的立方体 我使用以下代码来初始化着色器 void initShader const char vertexShaderPath const char fragmentShaderPath cout lt lt I
  • 简单的线框格式?

    我正在寻找一种用于线框模型的简单文件格式 我知道 VRML u3D 等 但这些对于我的需求来说似乎很重要 我的标准是 必须有明确的规格 要么是开放的 要么是非常完善 记录的 我只需要 想要 简单的模型 顶点和边 我不想处理面孔或物体 如果格
  • OpenGL 与 Eclipse CDT + MinGW + GLEW + GLFW:未定义的参考

    Edit 与此同时 我已经弄清楚了这一点 并在下面写了详细的答案 我刚刚尝试在 Win7 上从 Express 版本的 MSVC 10 切换到 Eclipse CDT 在配置时遇到了以下简单 OpenGL 代码的问题 在 Visual St

随机推荐