我正在开发一个2D侧面滚动游戏,我需要优化我的平铺代码以获得更好的帧速率.截至目前,我正在使用纹理图集和16x16图块,以获得480x320的屏幕分辨率.级别在两个方向上滚动,并且明显大于1个屏幕(数千个像素).我使用glTranslate进行实际滚动.
到目前为止,我已经尝试过:
将整个地图绘制为显示列表(在较小的水平上很好,在大的地方上减速)
将地图划分为显示列表的一半大小,然后剔除显示列表(对于双向滚动仍然变慢,过度绘制效率不高)
任何建议表示赞赏,但特别是我想知道:
谢谢 :)
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_TRIANGLES
0,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
用于将相机移动到水平,放大/缩小等.祝你好运!