在OpenGL中优化2D平铺滚动

use*_*517 9 opengl scroll

我正在开发一个2D侧面滚动游戏,我需要优化我的平铺代码以获得更好的帧速率.截至目前,我正在使用纹理图集和16x16图块,以获得480x320的屏幕分辨率.级别在两个方向上滚动,并且明显大于1个屏幕(数千个像素).我使用glTranslate进行实际滚动.

到目前为止,我已经尝试过:

  • 使用glTriangles仅绘制屏幕上的图块,每平方米图片2个(顶部太多)
  • 将整个地图绘制为显示列表(在较小的水平上很好,在大的地方上减速)

  • 将地图划分为显示列表的一半大小,然后剔除显示列表(对于双向滚动仍然变慢,过度绘制效率不高)

任何建议表示赞赏,但特别是我想知道:

  • 我已经看到Vertex Arrays/VBO为此提出了建议,因为它们是动态的.什么是利用这个的最佳方式?如果我只保留1个顶点屏幕加上一些过度绘制,我必须每隔几帧重新复制一次数组,以考虑相对坐标的变化(将所有内容移动并添加新的行/列).如果我使用更多的透支,这似乎不是一个大赢家; 这就像半屏显示列表的想法.
  • 如果在像这样的一堆小瓷砖上使用glScissor会给出任何增益,无论是显示列表还是顶点数组/ VBO
  • 仅仅使用大纹理构建级别然后使用glScissor会更好吗?如果我这样做,那么失去平铺的内存节省是移动开发的一个问题(只是好奇,我目前在PC上)?这里提到这种方法

谢谢 :)

Str*_*ger 10

以下是我对快速2D磁贴引擎进行编码的方法:

首先,我会在动态切片(字符,项目..)和静态切片(水平)之间进行清晰的分离.

静态瓷砖:

为了绘制静态的(构建整个级别的tile),我将使用一个静态缓冲区(存储在缓冲区对象中),其中包含每个tile位置(x,y,layer)和atlas纹理数据的索引(i ).由于纹理图集包含16x16像素的固定大小的图块,因此您可以轻松地在每个顶点的顶点着色器纹理坐标中进行计算.

为了绘制关卡,我将使用形成四边形的三角形条带的单个绘制调用(使用实例化),将顶点数据存储在静态VBO(由4个顶点组成)中,并将索引数据存储在静态IBO(由4个索引组成)中,使用顶点着色器中的每个实例值计算顶点属性.

这将使您在GPU上完成几乎"免费"的磁贴剔除,因为剪切硬件非常快.即使您的关卡中有大量的牌,也就是说30*20(平铺/在屏幕上),约50个屏幕/等级,它会生成30,000个牌.我认为它仍然可以接受(即使是在低端GPU上.顺便说一下,你是针对iPhone/Android吗?如果是OpenGL ES 1.0上没有实例/着色器,OpenGL ES 2.0没有实例支持但可以做着色器,所以你会必须在VBO/IBO中爆炸瓦片实例数据,并使用GL_TRIANGLES.你可以爆炸更少的数据和备用GPU内存,在着色器中计算顶点属性).

在任何情况下,你最好不要复制纹理贴图数据并保留纹理图集和VBO和IBO.

动态瓷砖:

我会使用动态VBO(以及代表GL_TRIANGLES0,1,2,2,1,3,0 + 4,1 + 4,2 + 4 .. 的静态IBO )来表示平铺位置,纹理坐标,图层和更新它通过屏幕上的可见动态图块来glBufferSubData绘制并通过图块绘制glDrawElements.

当然,这意味着您可以绘制每个动态切片的最大数量glDrawElements,因此如果达到此限制,则必须对VBO进行第二次更新/绘制.

如果您的OpenGL实现不支持VBO/IBO(如在OpenGL ES 1.0中),请使用VA.我不建议使用DL或立即模式(在OpenGL ES上不支持它).

最后,glOrtho用于将相机移动到水平,放大/缩小等.祝你好运!