Skip to content

Latest commit

 

History

History
509 lines (323 loc) · 25 KB

File metadata and controls

509 lines (323 loc) · 25 KB

十一、使用 C++ 和 OpenGL 开发安卓游戏

我们已经看到了安卓应用和安卓游戏的区别。安卓软件开发工具包非常有能力兼顾这两者。当然,出现的问题是“在本地语言(如 C 和 C++)中,独立开发工具集的要求是什么?”与 Java 相比,C 和 C++ 更难管理和编写代码。答案在于问题本身。Java 架构运行在与 Android 操作系统相关联的 JVM 上。这会产生额外的延迟,从而导致性能滞后。滞后的规模取决于应用的规模。

一个高度 CPU 密集型的应用可能会在 Java 架构中造成大量可见的延迟。本地语言代码可以处理得更快。此外,本机代码可以根据中央处理器/平台架构而变化,这在安卓软件开发工具包使用的 Java 架构的情况下是不可能的。

安卓使用的是 OpenGL 渲染系统。所以,用 OpenGL 制作的应用也可以选择 Android 作为目标平台。本机代码有助于使用 OpenGL 直接构建应用。

我们将在本章中通过以下主题详细了解这些方面:

  • 第三代 NDK 简介
  • 游戏用 C++ 的利弊
  • 本机代码性能
  • OpenGL 简介
  • 使用 OpenGL 渲染
  • 不同的中央处理器架构支持

安卓 NDK 简介

安卓其实是基于 Java 架构的。然而,安卓应用的一部分可以使用本地语言开发,如 C 和 C++。这就是安卓 NDK 进入画面的地方。

安卓 NDK 是一个用于开发应用模块的工具集,它可以更快地与硬件交互。众所周知,C 和 C++ 能够直接与本机组件交互,这减少了应用和硬件之间的延迟。

NDK 是如何运作的

一个安卓原生代码段通过 Java 原生接口 ( JNI )与主应用交互。安卓 NDK 附带了一个构建脚本,可以将本机代码转换为二进制代码,并将其包含在主安卓应用中。

这个二进制文件基本上是一个本机代码库,可以根据需要在任何安卓应用中使用。NDK 构建脚本创建.so文件,并将它们添加到应用路径中。

安卓构建过程创建 Dalvik 可执行文件(.dex)在安卓操作系统的 Dalvik 虚拟机(或 ART)上运行。Java 可执行文件识别本机库并加载实现的方法。本机方法用native关键字声明:

public native void testFunc (int param);

该方法始终具有公共访问权限,因为本机库始终被视为外部源。在这里,开发人员应该始终记住,对于所有包含的本机库,对于同一声明,永远不应该有多个方法定义。这总是会产生编译错误。

本机构建过程可以将本机项目构建成两种类型的库:

  • 本机共享库
  • 本机静态库

原生共享库

本地构建脚本从 C++ 文件创建.so文件,这被称为本地共享库。然而,它并不总是在真正意义上的应用之间共享。安卓应用是一个 Java 应用,但是本地应用可以通过本地共享库触发。

对于游戏开发,如果游戏是用原生语言编写的,那么游戏代码就包含在共享库中。

原生静态库

原生静态库基本上是编译对象和.a文件代表的的集合。这些库包含在其他库中。编译器可以在编译期间移除未使用的代码。

建立依赖关系

安卓软件开发工具包能够在 Java 的支持下将安卓应用项目构建并打包成 APK 文件。然而,NDK 不足以建立和包装 APK 档案。以下是创建除 NDK 之外的 APK 安卓应用的依赖项:

  • 安卓 SDK
  • C++ 编译器
  • 计算机编程语言
  • 格拉德尔
  • Cygwin
  • Java 语言(一种计算机语言,尤用于创建网站)

Android SDK

安卓应用基本都是 Java 应用。因此,为了创建安卓应用包,拥有安卓软件开发工具包是绝对必要的。

C++ 编译器

一个原生的安卓应用是用 C++ 写的,所以需要一个 C++ 编译器来编译开发平台上的代码库。C++ 编译器是平台相关的,所以在每个平台上可能不是同一个 C++ 编译器。

例如,在 Windows 机器上,C++ 11 编译器目前用于开发行业,而 GC++ 编译器用于 Linux 机器。

在语法和 API 调用方面,这些可能会为实际的开发项目创建不同的代码基础。

蟒蛇

Python 是单独开发的语言。它可以用来为安卓创建应用,并且可以通过将源代码转换为本地语言来支持多个平台。在 Android NDK 开发的情况下,Python 用于将 C++ 代码转换为本机二进制。

【T0 度】

Gradle 是构建脚本和安卓原生构建工具用来将原生代码转换成共享库的。它还提供了一个虚拟的 Unix 环境来制作应用包。

Cygwin

安卓需要一个 Unix 环境来构建一个 NDK 应用项目。Windows 系统没有 Unix 环境。Cygwin 需要提供一个虚拟的 Unix 环境来支持搭建平台。

爪哇

最后但同样重要的是 Java 创建安卓应用包的要求。然而,任何类型的安卓开发都需要 Java。

原生项目构建配置

一个安卓项目需要以下配置,以便从本地源代码创建一个应用包。本机项目构建取决于这两个文件中定义的配置:

  • Android.mk
  • Application.mk

安卓. mk 配置

位置

Android.mk文件可以是位于<Application Project Path>/jni/的。

配置选项:

Android.mk文件包含以下创建应用包的选项:

  • CLEAR_VARS:这个清除局部和用户定义的变量。该选项由include $(CLEAR_VARS)语法调用。
  • BUILD_SHARED_LIBRARY:这个包括共享库中所有本地文件,在LOCAL_MODULELOCAL_SRC_FILES中定义。它由include $(BUILD_SHARED_LIBRARY)语法调用。
  • BUILD_STATIC_LIBRARY:此指定静态库来创建共享库使用的.a文件。它由include $(BUILD_STATIC_LIBRARY)语法调用。
  • PREBUILT_SHARED_LIBRARY:这个表示在特定路径上的预建共享库,用于从本地包含构建依赖共享库。它由include $(PREBUILT_SHARED_LIBRARY)语法调用。
  • PREBUILT_STATIC_LIBRARY:这个表示在特定路径上的预构建静态库,用于从本地包含构建依赖共享库。它由include $(PREBUILT_STATIC_LIBRARY)语法调用。
  • TARGET_ARCH:这个表示 ARM、x86 等处理器架构家族的基本类型。
  • TARGET_PLATFORM:这个定义了目标安卓平台。上述平台必须通过 Android SDK 管理器安装在开发系统中。它指示安卓应用编程接口级别,以便创建应用包。
  • TARGET_ARCH_ABI:这个表示目标处理器架构的具体 ABI,比如 armeabi、armeabi-v7、x86 等等。
  • LOCAL_PATH:此指向当前文件目录。该变量不会被CLEAR_VARS命令清除。它由LOCAL_PATH := $ (call my-dir)语法调用。
  • LOCAL_MODULE:此表示所有唯一的本地模块名称。它由LOCAL_MODULE := "<module name>"语法调用。
  • LOCAL_MODULE_FILENAME:此表示包含已定义LOCAL_MODULE的库名。它由LOCAL_MODULE_FILENAME := "<module library file name>"语法调用。
  • LOCAL_SRC_FILES:这个表示要编译到共享库中的所有原生源代码文件路径。它由LOCAL_SRC_FILES := <Local source file path>语法调用。

还有其他可选的配置可以在该文件中设置,如LOCAL_C_INCLUDESLOCAL_CFLAGSLOCAL_CPP_EXTENSIONLOCAL_CPP_FEATURESLOCAL_SHARED_LIBRARIESLOCAL_STATIC_LIBRARIESLOCAL_EXPORT_CFLAGS

应用 mk 配置

位置

Application.mk文件可以位于<Application Project Path>/jni/

配置选项

Application.mk文件包含以下创建应用包的选项:

  • APP_PROJECT_PATH:这个是项目根目录的绝对路径。
  • APP_OPTIM:这个表示创建构建包作为发布或调试的可选设置。
  • APP_CFLAGS:这个为构建定义了一组 C 编译器标志,而不是在Android.mk文件中改变。
  • APP_CPPFLAGS:这个为构建定义了一组 C++ 编译器标志,而不是在Android.mk文件中改变。
  • APP_BUILD_SCRIPT:此是一个可选设置,用于指定除默认jni/Android.mk脚本之外的构建脚本。
  • APP_ABI:该选项指定了安卓应用包需要优化的 ABI 集合。以下是每个 ABI 支持的完整列表和关键词:
    • armv 5:t0]
    • armv 7:t0]
    • armv 8:t0]
    • 英特尔 32 位:x86
    • 英特尔 64 位:x86_64
    • MIPS 32 位:mips
    • MIPS 64 位:mips64
    • 全部设置:all
  • APP_PLATFORM:此选项指定目标安卓平台。
  • NDK_TOOLCHAIN_VERSION:该选项指定 GCC 编译器的版本。默认情况下,版本 4.9 和 4.8 分别用于 64 位和 32 位编译。
  • APP_STL:这是一个可选的配置,用来链接可选的 C++ 实现。
  • APP_LDFLAGS:在构建共享库和可执行文件的情况下,此选项用于将标志链接到构建系统以链接应用。

游戏用 C++ 的优点和缺点

C++ 和 Java 之间有一场永无止境的辩论。但是,我们不会进入争议,将尝试从游戏开发的角度来看待它们。C++ 在性能上比 Java 稍有优势,而 Java 以简单著称。

可能有很多程序员用 C++ 比用 Java 更舒服,反之亦然。在游戏开发中,个人选择编程语言并不重要。因此,必须根据需求决定使用 NDK 还是软件开发工具包。我们总是建议您使用安卓软件开发工具包来开发应用,而不是使用 NDK。

让我们讨论一下使用本地语言进行游戏编程的优缺点。

使用 C++ 的优势

我们先通过以下几点来看看使用 C++ 进行游戏编程的积极的一面:

  • 通用游戏编程语言
  • 跨平台可移植性
  • 更快的执行
  • 中央处理器架构支持

通用游戏编程语言

在游戏开发的情况下,C++ 被广泛用于很多平台,尤其是游戏机和 PC 游戏开发。这就是许多游戏引擎选择 C++ 作为主要编程语言的原因。

有时,很难学习许多编程语言来在不同的平台和不同的架构上工作。C++ 为这个问题提供了一个最常见的解决方案,因为大多数程序员都熟悉 C++ 库和 API 的使用。

跨平台可移植性

相同的 C++ 代码被编译成一个针对特定操作平台的库。因此,可以为不同的平台编译相同的项目。因此,如果游戏是用 C++ 编写的,将它移植到各种平台是非常容易的。

比如著名且有效的跨平台游戏引擎 Cocos2d-x 就采用了 C++ 作为开发语言。因此,同一个游戏可以很容易地移植到很多平台上,比如安卓、iOS、Mac OS 和 Windows。

更快的执行

C++ 能够很好地与平台硬件交互,用 C++ 编写游戏有助于提升它们的性能。然而,在安卓的情况下,如果游戏不是 CPU 密集型的,性能提升几乎不明显。

CPU 架构支持

C++ 代码可以针对特定的目标 CPU 架构进行编译,例如 x86、ARM、Neon 或 MIPS。该规格表明该特定处理器的性能更好。

安卓 NDK 系统的 CPU 架构编译器配置确保了每个平台的最佳结果。然而,并不总是需要定义每个平台来避免额外的编译。

使用 C++ 的缺点

现在,让我们通过以下几点来讨论硬币的另一面:

  • 高程序复杂性
  • 平台相关编译器
  • 手动内存管理

高程序复杂度

C++ 自带额外的程序复杂度。在 Java 编程的情况下,JVM 完全负责内存,并遵循面向对象的概念。C++ 在提供这一功能方面比较落后。因此,开发人员处理每一个编程方面都会产生额外的开销。

与 Java 相比,C++ 本身具有复杂的体系结构。如果使用 C++ 的话,面临异常和错误的几率会增加。

平台相关编译器

使用 C++ 时,跨平台很容易。然而,在大多数情况下,配置构建脚本可能是一件痛苦的事情。由于错误的配置,同一款游戏无法在移植平台上运行,这是非常常见的情况。此外,随着游戏在其他平台上成功运行,发现问题变得很困难。

很多时候,不同的平台使用不同的 C++ 编译器。因此,如果需要的话,需要额外的努力来识别特定于平台的代码,并为每个平台找到替代代码。

手动内存管理

Java 不要求内存管理由开发者实现,内存由 JVM 高效管理(安卓情况下为 DVM)。因此,不存在面临内存泄漏或碎片的可能性。JVM 运行垃圾收集器来自动释放未使用的内存。然而,垃圾收集器调用会消耗一些性能,频繁的垃圾收集器调用会导致性能严重下降。

开发人员应该使用最佳内存,因为如果代码中有任何活动引用,垃圾收集器就无法识别未使用的内存块。

结论

C++ 有自己的优势。但是说到安卓的游戏编程,在技术意义上帮助不大。因此,如果我们比较选择 C++ 而不是用 Java 为安卓编写代码所花费的精力和承担的风险,那么 Java 应该永远是安卓的首选。DVM 运行 Java 代码的效率足以在 Android 设备上实现合理的性能。此外,安卓 NDK 库实际上并不是为了开发独立的安卓应用而设计的。即使它有本机活动支持,作为 DVM 和用 C++ 编写的本机应用之间的中间层,它也没有多大帮助。

如果开发者选择不走跨平台,只把游戏范围保持在安卓以内,那么建议你用安卓 SDK,而不是安卓 NDK。它将降低开发速度和复杂性,而性能损失可以忽略不计。

本机代码性能

我们已经知道,原生代码可以以更好的处理速度运行得更快。这可以针对特定的中央处理器架构进行进一步优化。性能提升的主要原因是内存操作中指针的使用。但是,这取决于开发人员和编码风格。

让我们看一个简单的例子,在这个例子中,我们可以更好地理解母语的性能提升。

考虑一下这个 Java 代码:

int[] testArray = new int[1000];
for ( int i = 0; i < 1000; ++ i)
{
  testArray[i] = i;
}

在这种情况下,数组中 1000 个字段的地址由 JVM 处理(在 Android Dalvik 系统的情况下是 DVM)。所以,解释器解析到 i th 位置,每次执行赋值操作,要花费很多时间。

现在,让我们使用本机 C/C++ 语言实现相同的功能,并使用指针:

int testArray[1000];
int *ptrArray = testArray;
for ( int i = 0; i < 1000; ++ i)
{
  *ptrArray = i;
  ptrArray += i * sizeof(int);
}

在这个例子中,解释器不需要解析到目标内存位置。该位置的地址由ptrArray指出。因此,该值可以直接分配给存储单元。

特别是对于多维数组,在为相同功能正确编写本机代码的情况下,可以观察到显著的性能提升。本机代码的其他重要用途是二进制数据处理和图像处理,一次处理大量数据。

使用 OpenGL 渲染

安卓使用 OpenGL 进行渲染。安卓软件开发工具包库包括 OpenGL 库,专门为安卓优化。Android 从 API 级别 4 开始支持 OpenGL,然后随着级别的提高,增加了对 OpenGL 的支持。目前 OpenGL 支持的最大版本是来自 API 级别 21 的 OpenGL ES 3.1。

OpenGL 版本

不同的 OpenGL 版本有一套不同的特性。1.0 和 2.0 版本在编码风格、API 便利性、功能和特性支持方面有很多不同。让我们讨论以下对安卓开发有重要意义的 OpenGL ES 版本:

  • OpenGL 是 1.x
  • OpenGL 是 2.0
  • OpenGL 是 3.0
  • OpenGL 是 3.1

OpenGL 1.x

OpenGL1 . x 版本已经通过共享的 OpenGL ES 1.x 库libGLESv1.so从 Android API 级得到了支持。标题gl.hglext.h包含了 OpenGL 功能的所有必要的应用编程接口。

OpenGL 2.0

在当前的行业中,一个开发者更喜欢将 OpenGL ES 2.0 用于游戏,因为几乎每个设备都支持这个 OpenGL 版本,并且它提供了对游戏有用的顶点和片段着色器。通过在项目中包含libGLESv2.so共享库,可以在安卓原生开发项目中使用 OpenGL ES 2.0,如下所示:

LOCAL_LDLIBS := -lGLESv2

标题为gl2.hgl2ext.h。Android API 级支持 OpenGL ES 2.0。

OpenGL 3.0

从安卓 API21 级开始,支持 OpenGL ES 3.0。开发者可以包含libGLESv3.so使用 OpenGL 3.1,如下:

LOCAL_LDLIBS := -lGLESv3

标题为gl3.hgl3ext.h

OpenGL 3.1

从安卓 API 21 级开始,支持 OpenGL ES 3.1。开发者可以包含libGLESv3.so使用 OpenGL 3.1,如下:

LOCAL_LDLIBS := -lGLESv3

标题为gl31.hgl3ext.h

很多安卓设备都不支持 OpenGL ES 3.0 和 OpenGL ES 3.1。如果开发人员打算使用它们,那么在使用该版本之前应该进行 OpenGL 版本检查。此外,必须使用适当版本的 OpenGL ES 在该特定设备上运行游戏。最新的安卓 N 有对 OpenGL ES 3.2 的支持。

检测并设置 OpenGL 版本

这段安卓 Java 代码可以用来为安卓游戏实现适当的 OpenGL ES 支持:

private GLSurfaceView glSurfaceView;
void setOpenGLVersion()
{
  final boolean supportOpenGLEs3 = configurationInfo.reqGlEsVersion >= 0x30000;

  if (supportOpenGLEs3) 
  {
    glSurfaceView = new GLSurfaceView(this);
    glSurfaceView.setEGLContextClientVersion(3);
    glSurfaceView.setRenderer(new RendererWrapper());
    setContentView(glSurfaceView);
  }
  else
  {
  final boolean supportOpenGLEs2 = configurationInfo.reqGlEsVersion >= 0x20000;

  if (supportsOpenGLEs2) 
    {
      glSurfaceView = new GLSurfaceView(this);
      glSurfaceView.setEGLContextClientVersion(2);
      glSurfaceView.setRenderer(new RendererWrapper());
      setContentView(glSurfaceView);
    }
    else
    {
      glSurfaceView = new GLSurfaceView(this);
      glSurfaceView.setEGLContextClientVersion(1);
      glSurfaceView.setRenderer(new RendererWrapper());
      setContentView(glSurfaceView);
    }
  }
}

纹理压缩和 OpenGL

纹理压缩对 OpenGL 处理的渲染过程有显著影响。它可以提高或降低不同类型纹理压缩的性能。让我们快速了解一些重要的纹理压缩格式:

  • 空中交通管制
  • PVRTC(全球定位系统)
  • DXTC(数据中心)

空管

ATI 纹理压缩常被称为 ATITC。这种压缩支持带和不带 alpha 通道的 RGB。这是安卓最常见、使用最广泛的压缩技术。

PVRTC

Power VR 纹理压缩使用 2 位和 4 位像素压缩,有或没有 alpha 通道。全球许多游戏开发人员都使用这种方法。

DXTC

DXTC 也叫 S3 纹理压缩,也是 OpenGL 用的。这使用 4 位或 8 位 ARGB 通道。

OpenGL 清单配置

Android 需要应用中使用的 OpenGL 的版本定义,以及其他需要的选项。

下面是 OpenGL ES 的版本声明语法:

<uses-feature android:glEsVersion=<Target version goes here> android:required="true" />

以下是目标版本选项:

  • 1.0 版的0x00010000
  • 1.1 版的0x00010001
  • 2.0 版的0x00020000
  • 3.0 版的0x00030000
  • 3.1 版的0x00030001
  • 3.2 版0x00030002

以下是纹理压缩声明的可选设置:

<supports-gl-texture android:name=<Compression support type goes here> />

这些是压缩类型选项:

  • GL_OES_compressed_ETC1_RGB8_texture
  • GL_OES_compressed_paletted_texture
  • GL_EXT_texture_compression_s3tc
  • GL_IMG_texture_compression_pvrtc
  • GL_EXT_texture_compression_dxt1
  • GL_EXT_texture_compression_dxt2
  • GL_EXT_texture_compression_dxt3
  • GL_EXT_texture_compression_dxt4
  • GL_EXT_texture_compression_dxt5
  • GL_AMD_compressed_3DC_texture
  • GL_EXT_texture_compression_latc
  • GL_AMD_compressed_ATC_texture
  • GL_ATI_texture_compression_atitc

但是,并非所有设备都支持所有纹理压缩。开发人员应根据硬件和安卓版本要求,始终选择目标纹理压缩。

如果目标设备不支持声明的一种或多种纹理格式,谷歌会自动对设备进行过滤。

选择目标 OpenGL ES 版本

正如你已经了解到的,并不是所有的设备都支持所有的 OpenGL 版本。所以,在开发游戏之前,选择正确的 OpenGL 版本是非常重要的。以下是选择 OpenGL 版本时应该评估的几个因素:

  • 表演
  • 纹理支持
  • 设备支持
  • 渲染特征
  • 编程舒适性

性能

是注意到 OpenGL 1.x 版本比 OpenGL 1.x 版本快,比 OpenGL 1.x 快很多,所以在游戏中使用最新可能的版本总是比较好的。

纹理支持

纹理压缩支持因 OpenGL 版本而异。旧版本支持旧的纹理压缩因子。此外,安卓版本支持并不是所有的 OpenGL 版本都通用的。同样,最好使用最新版本的纹理支持。

设备支持

这个约束让开发者脚踏实地。并非所有设备都支持 OpenGL 的最新版本。因此,为了瞄准更大范围的设备,用户应该将 OpenGL 版本更改为 2.0,因为大多数设备都支持该版本。

渲染特征

随着 OpenGL 版本的增加,在选择 OpenGL 版本时,特征列表成为一个重要因素。开发人员必须知道开发应用所需的支持,因此,他们必须选择版本。

编程舒适度

OpenGL 版本之间有着巨大的编码风格和 API 变化。如果实际上可以在公司轻松开发,开发人员应该选择版本。

不同 CPU 架构支持

开发人员有机会为单独的处理器架构优化安卓应用。从高层次来看,这是一个很棒的特性。然而,这一特性付出了巨大的代价。让我们来看看这个特性的细节。

可用的中央处理器架构

以下是 NDK 构建目前支持的体系结构:

  • 手臂ˌ武器ˌ袖子ˌ装备
  • x86
  • 每秒百万条指令

ARM

ARM 代表 Acorn RISC 机T4。这是一款基于 RISC ( 精简指令集计算 ) 的处理器,主要针对嵌入式或移动计算。正如基地所说,对于安卓这样的操作系统来说,这是非常高效的。

目前,安卓平台上使用的大多数处理器都来自 ARM 系列。它可以进一步细分如下:

  • armv 5 你
  • ARMv7 战斗机
  • ARMv8 战斗机

x86

英特尔为处理器推出了 x86 架构。起初,这些处理器主要用于台式机/笔记本电脑。然而,它们经过优化,以赛扬或凌动处理器的形式用于移动设备。

安卓 NDK 版本可以设置两种 x86 架构:

  • i686
  • x86-64

霓虹

霓虹架构基于 ARM 技术,针对移动计算进一步优化。安卓构建也可以针对这种特定的架构进行优化。所有 Cortex 处理器基本上都是基于 Neon 的处理器。

MIPS

MIPS 代表无联锁的微处理器 管道阶段。这一类别中有 32 位和 64 位处理器的变体。顾名思义,这种架构用于小规模计算的嵌入式设备中的微处理器。后来,它以 64 位架构引入安卓。然而,这种类型的处理器在今天的安卓系统中很少使用。

集成多架构支持的优缺点

安卓移动设备在内存和处理能力方面有种不同的配置。包含独立的体系结构支持可能会提高更大的构建规模带来的性能。

本机构建工具为每个目标处理器构建一个单独的共享库,并将其包含在构建包中。

以下是提供独立处理器架构支持的一些优点和缺点。

让我们先看看优点:

  • 更快的操作:独立处理器的独立架构带来了更快的游戏指令处理速度。如果安卓应用支持处理器架构,那么处理器不需要执行任何转换,可以以更快的速度运行指令。
  • 处理器的最佳使用:操作系统总是寻找集成处理器的具体架构。相同的架构优化了处理器的使用。
  • 最小功耗:最佳处理直接意味着处理的最佳和最小功耗。
  • 最佳内存使用:如果安卓应用支持相同的处理器架构,处理器不需要使用额外的运行时内存来执行指令。

现在让我们看看缺点:

  • 更大的构建大小:为单独的架构使用单独的共享库会显著增加构建包的大小。通过不同的处理器优化,整个本机指令代码在单独的共享库中被重写。
  • 目标设备数量减少:如果 APK 的大小很大,那么对于低存储设备来说,容纳它会产生更多问题。因此,设备支持变少。

总结

在这一章中,我们简单地看了一下 Android NDK,澄清了一些关于原生开发的疑问。有许多开发人员认为,用母语开发游戏会带来巨大的处理能力。然而,这并不总是正确的。处理和性能取决于开发风格和标准。在大多数常见的场景中,本机开发和 SDK 开发之间的差异可以忽略不计。

OpenGL 可以在任何场景下与 Android 协同工作。后端渲染是基于 OpenGL 的 NDK 和软件开发工具包。我们已经讨论了 OpenGL 的所有技术方面。在这里,您学习了哪个版本的 OpenGL 与 Android 一起工作,以及我们应该使用什么。显然,OpenGL ES 2.0 是一个不错的选择,因为大多数安卓设备都支持它。另一方面,OpenGL ES 1.0 已经过时,目前大多数安卓设备还不支持 OpenGL ES 3.0。

到目前为止,我们已经涵盖了安卓游戏开发的几乎每个方面。然而,完成游戏的实现并不意味着开发周期的完成。开发人员需要在游戏进入发布就绪状态后对其进行润色,以提高其整体质量。我们将在下一章讨论游戏打磨,以表明游戏开发过程的完成。