OpenGL - 渲染大量实体的推荐方法,每个实体都有独特的程序纹理

时间:2016-05-26 11:44:00

标签: opengl graphics 2d textures simulation

考虑具有以下属性的2D模拟:

  • 实体填满屏幕并四处移动,有时会死亡并消失
  • 每个实体都有一个独特的,程序生成的纹理集合作为其"精灵"。鉴于程序性质,纹理是在运行时生成的。任何两个实体具有相同纹理的可能性极低
  • 屏幕上一次最多可存在5,000个实体(任何给定的游戏中都不存在最大的实体数量 - 当它们死亡时,内存被释放)
  • 应该将精灵拉回到前面,这样前景实体就会重叠实体""它们。
  • 该SIM与OpenGL 3.0兼容
  • GL_MAX_TEXTURE_SIZE为2048,与旧版移动设备兼容
  • 纹理具有透明度,因此z缓冲区不适用于绘制顺序

如果我没弄错的话,有两种解决这个问题的方法:

  1. 在运行时使用每个实体新生成的纹理动态更新纹理图集。当一个实体死亡时,删除它的纹理也为新的实体留下空白。这里的优点是你只需要1次抽签。缺点是纹理图谱使系统不可能。如果你有一个2048x2048图集并且你的精灵是64x64,那么在空间不足之前你只能生成1024个精灵。如果每个实体由5个精灵组成,用于动画目的,则任何时候只能存在大约200个实体。您还必须在运行时不断更新纹理。
  2. 为每个敌人创建一个单独的纹理对象,并为每个敌人进行绘制调用。这里的优点是您可以根据需要不断创建新纹理(在内存限制内)。缺点显然是潜在的大量绘制调用(仅对实体高达5,000,不包括背景纹理等)。
  3. 所以#1似乎完全没有问题。 #2是实现这一目标的唯一方法,还是有更好的方法我还没考虑过?

2 个答案:

答案 0 :(得分:0)

从你的描述中不清楚为什么#1不可能。这是绘制多个小精灵的常用方法。您不仅限于1024个精灵,因为您可以创建多个地图集。即使一次批量处理200个实体,您也可以比逐个绘制它们做得更好。 但是,生成精灵的机制似乎很重要。如果你每帧都更新整个地图集,你可能会想要做其他事情。

答案 1 :(得分:0)

您可以使用多个地图册并通过额外的顶点属性(或3D纹理坐标)在一次调用中绘制,该属性告诉着色器使用哪个地图集。

有几种选择:

  • 使用阵列纹理或3D纹理。
  • 将它们绑定到不同的纹理单元(从OpenGL 3.0获得至少16个IIRC)

Array Textures可能是最优雅的解决方案,也是3.0的核心。