java - 纹理动画和绘制调用性能 | OpenGLES 2.0 + Java
问题描述
我正在使用 Java 和 OpenGL ES 2.0 在 Android Studio 上构建一个简单的游戏。
如果直到现在我更关心创意方面,现在我已经到了性能开始发挥重要作用的地步,事实上,在我的设备(三星 Galaxy S8)上测试它时,我开始注意到一些滞后或分散。
正如我所说的游戏非常简单,它是 2D 的,屏幕上的对象相对较少(10/15)。这些物体移动,因此有一个基本的碰撞检测引擎。
我创建了一个类来帮助我跟踪性能和函数执行时间(它创建一个字符串,其中指示函数的名称及其执行时间,然后我在 Excel 中创建了一个简单的例程,将它们全部排序在一个表中。任何建议欢迎以更好的方式跟踪性能)。从这些测试中我推断出我的游戏中较慢的部分是纹理动画和绘制调用。
纹理动画
对于纹理动画,我的意思是我切换纹理以实现流畅动画的方式。例如,如果我在屏幕上有一个按钮,并且我希望这个按钮的背景是动画的,那么我就使用这种技术。
为了实现动画,我创建了一个大纹理并将动画的帧放入其中。我把它们放在纹理的下部。我用一个方法创建了一个Texture
类,void animate (int numbOfFrames, int animDuration)
每次我必须绘制我的动画对象时都会调用该方法。此方法根据经过的时间切换纹理坐标。我认为使这种方法变慢的原因是,每次调用它时它都必须更新我对象的 VBO 中的纹理组件。
我还尝试将我的动画帧放入不同的纹理(一帧 = 一个纹理),但我的应用程序在几秒钟后最终崩溃。事实上,我认为几乎每一帧都改变纹理并上传它是非常昂贵的。
我不想发布我的Texture
课程的源代码,因为我想了解我使用的技术是否可以。如果是的话,我会尝试自己优化它。这是我的第一个游戏,所以我想通过它的开发来学习。
绘制调用
我游戏中另一个较慢的部分是draw call。
我用不同的类为不同类型的对象构建了我的应用程序。例如,我Cars
为汽车、Planes
飞机等创建了一个类。每个类的每个对象都存储自己的值(例如,它的位置、它的纹理、它的速度、它的坐标、它的模型矩阵、它的着色器程序……)。每个对象都有一个绘制自身的方法。
然后我为每种对象创建了一个类,负责动态创建或删除它们。例如,我有 a Cars_Builder_
, a Planes_Builder_
, ... 每个Builder都有一个 ArrayList ,其中包含要绘制的对象。当我调用xxxBuilder.draw()
它时,它会迭代到 ArrayList 并调用draw()
每个对象的方法。
在线我读到改变 OpenGL 状态是昂贵的。通过做我正在做的事情,我改变了很多次。事实上,每个绘图调用都必须选择正确的着色器程序、绑定数据 ( glVertexAttribPointer
)、调用glDrawArrays
以及其他一堆改变状态的东西。
所以我正在考虑改变draw()
每个对象种类的类(Cars
,,Planes
...)中的实现。我想将我必须绘制的每种类型的每个对象的坐标放入一个大数组中,然后draw()
通过xxxBuilder
. 通过这种方式,我大大减少了昂贵的调用(每种类型的对象一个),但我有几个疑问:
- 我必须
MVPmatrix * vertex
在 CPU 上计算。事实上,每个模型都有不同的位置。 - 即使相同类型的对象相似,它们也不相同,例如它们可能具有不同的纹理。但是,如果我有相同的 VBO,如何将不同的纹理 ID 传递给着色器,所以我用相同的
glDrawArrays
调用来绘制它们?如果有办法分段glDrawArrays
调用,那么我的第一个疑问也将得到解决:实际上我会为每个对象传递不同的制服(所以纹理和 MVPmatrix)。
感谢您阅读我的问题,如果我的英语不是很好,或者我问/说了明显的事情,或者它太宽泛,我很抱歉。
解决方案
推荐阅读
- kubernetes - 如何更好地理解 k8s 上的本地临时存储配置
- c - 如何使用 rsync 或其他方式将文件复制到目录中?
- azure - Azure 更新管理以 csv 格式生成补丁状态报告
- python - 如何读取 Kinesis 客户端库 (KCL) 的 Python 客户端属性文件中的环境变量?
- python - 如何允许作者和管理员同时修补和删除权限?
- java - 用java spring处理不断增长的excel文件
- javascript - 具有空值的firebase推送方法是否仅用于获取ID,触发child_added事件?
- r - 使用 stringr 匹配所有换行符
- php - 如何制作 Laravel 动态数据表?
- python - 不能接受多个输入