c++ - 排序子网格/VBO

标签 c++ sorting opengl vbo

我有一个关卡需要渲染。它被分成数百个子网格,其中包含有关哪个子网格可以看到哪个子网格的信息。每个级别都有一个纹理池,所有这些子网格都可以引用这些纹理。所有子网格都有按纹理排序的顶点。这是一个例子。

子网格 1

索引[1, 3, 4, 5, 6, 2, 7, 8, 10...] 纹理1

索引[12, 15, 16, 12, 13, 19] 纹理 2

当可能有 1000 个子网格和 20 个纹理时,即使考虑到可见性,纹理交换量也会变得荒谬。

我在 VBO 中依次拥有所有子网格。我一直在努力找出优化渲染和消除所有不必要的纹理交换的最佳方法。如果我只是对 VBO 进行排序,我将丢失子网格连接,可见性数据将变得无用。或者有更好的方法吗?

或者我应该根据可见性每帧创建一个索引列表还是太慢了?

编辑:这是我当前设置的 segmentation 。

具有所有顶点的 VBO 按顺序从子网格 1 纹理 1、子网格 1 纹理 2 一直运行到子网格 n、纹理 n。

我有一个 IBO,它只是所有网格的所有索引,以相同的相对顺序。

当我渲染时,我引用子网格并有一个起始索引和计数,它们是 IBO 中该子网格和纹理的起始索引,然后是具有该纹理的数字的计数。

这就是为什么我要进行如此多的交换,这实际上会减慢速度。

最佳答案

VBO with all of the vertices in order running from submesh 1 texture 1, submesh 1 texture 2, all the way to submesh n, texture n.

这是你的问题。 “子网格”应该是单个渲染调用,而不是多个 渲染调用。每个“submesh”应该等同于你的“submesh X, texture Y”对。特定的子网格使用一组特定的 glVertexAttribPointer 调用、glBindTexture 调用和单个 glDrawElements 调用来渲染。

此方案中的每个子网格都使用特定 纹理。因此,您可以根据它们使用的纹理对绘制顺序进行排序。因此所有使用纹理 1 的子网格都可以同时渲染,它们之间只需要一个 glBindTexture 调用。

为了获得最佳性能,因为所有“子网格”都使用相同的缓冲区(因此,它们都使用相同的顶点格式是一个很好的改变),您还应该尝试 use glDrawElementsBaseVertex渲染特定的“子网格”,而不是为每个子网格单独调用 glVertexAttribPointer

这个想法是让你的 VBO 有效地成为一个长数组,每个子网格的所有顶点都在同一个数组中。每个子网格存储其索引数据的基本偏移量、要渲染的顶点数和基本顶点偏移量,它表示子网格数据在大数组中从哪个索引开始。

在开始渲染所有子网格时,您进行一个glVertexAttribPointer 调用。然后它只是 glBindTextureglDrawElementsBaseVertex 从那时起。您不必为每个子网格调用 glVertexAttribPointer。您使用 BaseVertex 来定义每个子网格的数据在 VBO 中的来源。

关于c++ - 排序子网格/VBO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16536199/

相关文章:

c++ - 什么是 Apple GCC 中的 WSAAsyncSelect() 函数模拟?

Java基于三列对数组进行排序

java - 支持重复键的高效有序数据结构

java - 如何在保持排序的同时将排序的链表插入另一个排序的链表?

OPENGL 混合功能 - 以分层方式缓慢替换颜色

java - 如何在二维矩阵中找到相同元素的行?

c++ - 控制小数位数

c++ - OpenGL 似乎没有读取我的顶点/索引

c++ - 匹配别名模板作为模板参数

opengl - 光线转换中的方向向量