我使用Java和OpenGL ES 2.0在Android Studio上构建一个简单的游戏。
如果直到现在我更关注创意方面,现在我已经到了性能开始发挥重要作用的地步,实际上是在我的设备上测试它(三星) Galaxy S8)我开始注意到一些滞后或散射。
我说的游戏非常简单,它是2D,屏幕上的对象相对较少(10/15)。这些对象移动,因此有一个基本的碰撞检测引擎。
我创建了一个类来帮助我跟踪性能和函数执行时间(它创建一个字符串,其中显示了函数的名称及其执行时间,然后我在Excel中创建了一个简单的例程,将它们全部排序在表格中。欢迎以更好的方式跟踪表现的任何建议。从这些测试中我推断出游戏中较慢的部分是纹理动画和绘制调用。
使用纹理动画我指的是我切换纹理以实现流畅动画的方式。例如,如果我在屏幕上有一个按钮,并且我想要对此按钮的背景进行动画处理,那么我就会使用这种技术。
为了实现动画,我创建了一个大的纹理,并在其中添加了动画的帧。我把它们放在纹理的下半部分。我使用方法Texture
创建了一个void animate (int numbOfFrames, int animDuration)
类,每当我必须绘制动画对象时,我都会调用它。该方法基于经过的时间切换纹理坐标。
我认为这种方法变慢的原因是它每次调用时都必须在对象的VBO中更新纹理组件。
我还尝试将动画的帧放在不同的纹理中(一帧=一个纹理),但我的应用程序在几秒钟后就崩溃了。事实上,我认为改变纹理并几乎每帧都上传它是非常昂贵的。
我不想发布我的Texture
课程的源代码,因为我想了解我使用的技术是否合适。如果是,那么我会尝试自己优化它。这是我的第一个游戏,所以我想通过它的发展来学习。
我游戏中另一个较慢的部分是平局调用。
我为不同类型的对象构建了不同类的应用程序。例如,我为汽车创建了一个类Cars
,为飞机创建了Planes
等等。每个类的每个对象都存储自己的值(例如它的位置,纹理,速度,坐标,模型矩阵,着色器程序......)。每个对象都有一个绘制自己的方法。
然后我为每种对象创建了一个类,它负责动态创建或删除它们。例如,我有一个Cars_Builder_
,一个Planes_Builder_
,...每个 Builder 都有一个ArrayList,其中包含要绘制的对象。当我调用xxxBuilder.draw()
时,它会迭代到ArrayList并调用每个对象的draw()
方法。
Online我读过更改OpenGL状态的代价很高。通过我做的方式我做了很多次改变它们。实际上,每个绘图调用都必须选择正确的着色器程序,绑定数据(glVertexAttribPointer
),调用glDrawArrays
,以及另一堆状态更改内容。
因此,我正在考虑更改每个对象类的draw()
(Cars
,Planes
,...)中的draw()
的实现。我想把每个类型的每个对象的坐标放到一个 big 数组中,然后通过xxxBuilder
调用真正的MVPmatrix * vertex
方法。这样我大量减少了昂贵的电话(每种类型的电话一个),但我有几个疑问:
glDrawArrays
。事实上,每个模型都有不同的位置。glDrawArrays
调用绘制它们?如果有一种方法可以解析{{1}}调用,那么我的第一个疑问也会被解决:实际上我会为每个对象传递不同的制服(所以纹理和MVPmatrix)。感谢您阅读我的问题,对不起,如果我的英语不是很好,或者我询问/说明显的事情或是否过于宽泛。