存储几何的索引
Posted
技术标签:
【中文标题】存储几何的索引【英文标题】:Store geometry's indices 【发布时间】:2013-10-09 08:01:05 【问题描述】:我已经阅读了很多关于 OpenGL 的资料,并且对“架构”有一些疑问。
-
OpenGL 有缓冲区,那么将几何数据存储在一个类中是否有用?我可以在实时 OpenGL 缓冲区中进行编辑,对吧?
OpenGL 索引缓冲区可以处理 GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT 和 GL_UNSIGNED_INT,在我的班级中,我该如何管理这些不同的类型?我是否需要创建一个 unsigned int 向量、一个 short 向量……?
管理无符号整数、无符号字节和无符号短索引是否有用?我之所以这么问,是因为只存储 unsigned short 会不那么痛苦,并且可以允许小型和大型模型。
【问题讨论】:
技术上正确的术语是“设计” 我建议您在开始使用像 OpenGL 这样高级的东西之前充分学习和理解 C++。 另外,你几乎不想使用无符号字节来存储索引。是使用 unsigned int 还是 unsigned short 取决于您是否可以将所有内容都放入 unsigned shorts 中。 尽可能使用最小的类型,但避免GL_UNSIGNED_BYTE
,它不是硬件友好的索引类型。使用较小的类型可以减少存储/总线流量,这是双赢的,只要硬件支持该类型(桌面 GPU 普遍支持 16 位/32 位类型)。
【参考方案1】:
关于您的问题:
OpenGL 有缓冲区,那么将几何数据存储在一个类中是否有用?我可以在实时 OpenGL 缓冲区中进行编辑,对吧?
这取决于您打算多久更新一次数据,以及您使用的 GPU 类型。如果您使用的是独立的“桌面”GPU(例如,NVIDIA 或 ATI/AMD),OpenGL 缓冲区会分配在显卡的内存上,并且编辑(通过调用 glMapBuffer
或变体)缓冲区通常需要复制数据从 GPU 回到 CPU 的内存,或者在 CPU 中保留数据的“影子副本”,在编辑后发送到 GPU。无论哪种方式,您都可能会因编辑缓冲区中的数据而导致延迟。
编辑数据的另一种(通常是更好的)方法是使用glBufferSubData
替换缓冲区的一部分,这可能有助于减少映射和取消映射缓冲区以进行交互式编辑的影响。此调用需要 CPU 内存中的数据数组,这些数据将被复制到 GPU 以替换缓冲区中的数据。您可以使用glBufferSubData
发送的数据量必须小于原始缓冲区的大小。
关于将数据保存在一个类中,如果您将经常更改数据,那么您最好的方法可能是保留一个本地副本,然后 glBufferSubData
将其发送到 GPU。
OpenGL 索引缓冲区可以处理 GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT 和 GL_UNSIGNED_INT,在我的班级中,我该如何管理这些不同的类型?我是否需要创建一个 unsigned int 向量、一个 short 向量……?
不,您只需要一个最合适类型的缓冲区,具体取决于您需要索引多少个顶点。例如,您只能使用GL_UNSIGNED_BYTE
索引访问 256 个顶点。
管理无符号整数、无符号字节和无符号短索引是否有用?我之所以这么问,是因为只存储 unsigned short 会不那么痛苦,并且可以允许小型和大型模型。
再一次,你用于索引的数据类型真的只对你想要访问多少个顶点很重要,所以如果GLushort
是最好的存储格式,那就去吧。
【讨论】:
+1:但是关于使用基于顶点数量的“最合适的类型”,我应该补充一点,桌面 GPU 无法使用 8-后 T&L 缓存的位索引(它们仅支持 16/32 位)。如果您使用 8 位元素数组,这通常意味着驱动程序将在运行时将元素填充到 16 位,并且从长远来看,您不会节省任何内存,只会增加额外的工作为司机。在 D3D 中,甚至不支持 8 位索引,我认为在嵌入式图形设备上,硬件是否支持它们更像是一个灰色地带。【参考方案2】:您要问的只是设计选择问题。最好选择适合您需求的实现,并且仅在您无法处理某个功能时进行更改。在这一点上,您将有一些工作,并且更容易进行更改以支持新内容。
我建议直接在内存中使用unsigned int
作为索引,并将索引缓冲区作为std::vector<unsigned int>
直接使用。
拉兹万。
【讨论】:
以上是关于存储几何的索引的主要内容,如果未能解决你的问题,请参考以下文章
MongoDB 2dsphere 索引失败(几何形状错误?)
Threejs:如何使用GLTFExporter导出具有绘制范围的索引几何?