使用 OpengL Surface 为 Android 制作游戏循环的最佳方法
Posted
技术标签:
【中文标题】使用 OpengL Surface 为 Android 制作游戏循环的最佳方法【英文标题】:Best way to make game loop for Android using OpengGLSurface 【发布时间】:2012-02-14 10:03:19 【问题描述】:据我所知,如果我想制作一个非 opengl 游戏循环,我可以做的是有一个游戏线程,在循环期间将更新游戏状态(或游戏物理)并通过锁定更新图形来自(普通)SurfaceView
的 Canvas
,通过 Canvas.drawXXX(...) 方法进行绘图,然后解锁它,此时图形会为循环更新。
在使用GLSurfaceView
和Renderer
时,我真的不知道该怎么做。据我了解,我不能再像使用常规表面那样按需绘制手工制作的游戏线程,它是Canvas
,因为现在有一个渲染线程将调用Renderer.onDrawFrame()
(在我的渲染器实现中)我传递给 GLSurfaceView 的类)。
那么我的问题是,用 GLSurfaceView 和 Renderer 制作游戏循环的好方法是什么?我是否仍然应该制作单独的游戏线程,但只处理其中的游戏状态(物理)更新,然后在我的 Renderer.onDrawFrame() 实现中使用该游戏状态来实际绘制基于当前状态的图形?我应该只使用 Rendere 的线程来进行状态更新吗?
【问题讨论】:
【参考方案1】:好吧,事实证明,最好的方法是使用 GLSurface 提供的线程。它的钩子来自 Renderer 接口的实现。实际上,可以将渲染器的 onDrawFrame() 方法视为类似于常规线程的 run() 方法。这种方式抛弃了每秒固定更新范式的概念(不是真的,但在这种情况下这样做太复杂了),但另一方面,您可以获得最佳的图形更新。
这里有关于 android 和 OpenGL 的精彩教程:
http://insanitydesign.com/wp/projects/nehe-android-ports/
【讨论】:
所以使用 onDrawFrame() 作为游戏的“更新”是不是一个坏习惯?我刚刚制作了一款游戏的原型——在没有内存分配的情况下实现了流畅的 60FPS,并且一直在想我可能应该拆分我的线程。 好吧,只使用 GLSurface 的线程意味着您的游戏将有 2 个主要线程:主线程,在此设置中主要处理 UI 输入等,而 GLSurface 线程将更新您的游戏状态和图形。我已经使用了这个设置,它工作正常。您只需要小心如何将用户输入从主线程传递到 GLSurface 线程(避免竞争条件)。除此之外,我见过一些奇特的设置,你有第三个(甚至更多)线程来处理其他东西,但我从来没有觉得需要它。 坦率地说,最好的方法是不使用 GLSurfaceView。使用计划旧的 SurfaceView 并自己进行 EGL 设置和线程管理。这是更多的工作,但你可以获得更好的结果。更多关于 Android 游戏循环的讨论可以在这里找到:source.android.com/devices/graphics/architecture.html#loops。 Grafika 中的示例代码 (github.com/google/grafika)。以上是关于使用 OpengL Surface 为 Android 制作游戏循环的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章
Android使用SurfaceView搭建OpenGL环境
Android使用SurfaceView搭建OpenGL环境
Chromium网页绘图表面(Output Surface)创建过程分析