我正在开发2D侧面滚动游戏,我需要优化我的平铺代码以获得更好的帧速率。截至目前,我正在使用纹理图集和16x16图块,以获得480x320的屏幕分辨率。级别在两个方向上滚动,并且明显大于1个屏幕(数千个像素)。我使用glTranslate进行实际滚动。
到目前为止,我已经尝试过:
将整个地图绘制为显示列表(在较小的水平上很好,在大的地方放慢速度)
将地图划分为显示列表的一半大小,然后剔除显示列表(对于双向滚动仍然会变慢,过度绘制效率不高)
任何建议都值得赞赏,但我特别想知道:
谢谢:)
答案 0 :(得分:9)
以下是我对快速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中爆炸tile实例数据,并使用GL_TRIANGLES
。您可以爆炸更少的数据和备用GPU内存,在着色器中计算顶点属性。)
在任何情况下,你最好不要复制纹理贴图数据并保留纹理图集和VBO和IBO。
我会使用动态VBO(和表示GL_TRIANGLES
的静态IBO,所以0,1,2,2,1,3,0 + 4,1 + 4,2 + 4 ..,)表示拼贴位置,纹理坐标,图层,并通过glBufferSubData
在屏幕上使用可见动态图块进行更新,并通过glDrawElements
绘制图块。
当然这意味着您可以按照glDrawElements
绘制最大数量的动态切片,因此如果达到此限制,则必须对VBO进行第二次更新/绘制。< / p>
如果您的OpenGL实现不支持VBO / IBO(如在OpenGL ES 1.0中),请使用VA。我不建议使用DL或立即模式(在OpenGL ES上不支持它)。
最后,使用glOrtho
将相机移动到水平位置,放大/缩小等等。祝你好运!