零、前言

移动性和对高性能计算的需求往往紧密相连。当前的移动应用执行许多计算密集型操作,例如 3D 和立体渲染、图像和音频识别以及视频解码和编码,尤其是增强现实等新技术的诞生。这包括移动游戏、3D 用户界面软件和社交软件,涉及媒体流处理。

从某种意义上来说,手机游戏开发迫使我们回到了几年前,由于有限的硬件能力、低内存带宽和宝贵的电池资源,但也让我们重新考虑与用户交互的基本形式。

基于手势输入、互联网接入、环境音效、高质量文本和图形的流畅响应用户界面是成功移动应用的要素。

所有主要的移动操作系统都为软件开发人员提供了开发接近硬件的不同可能性。谷歌提供了安卓原生开发套件(NDK),以方便将现有应用和库从其他平台移植到安卓,并利用现代移动设备提供的底层硬件的性能。C,尤其是 C++,都有着难学的语言和难写用户界面代码的语言的美誉。这确实是真的,但只有当有人试图从头开始写一切的时候。在本书中,我们使用 C 和 C++编程语言,并将它们链接到完善的第三方库,以允许创建具有现代基于触摸的界面的内容丰富的应用,并访问流行网站(如脸书、推特、Flickr、Picasa、Instagram 等)的代表性状态转移(REST)API。

尽管关于如何在用 Java 或. net 编写的应用中使用互联网资源的信息是可用的。NET 语言中,关于用 C++编程语言来做这件事已经说得不多了。现代 OpenGL 版本需要足够的努力来创建和使用最新的扩展。使用 OpenGL API 的编程通常在文献中以特定于平台的方式进行描述。随着移动版本 OpenGL ES 的出现,事情变得更加复杂,因为开发人员必须调整现有的着色器程序,以允许它们在移动图形处理单元(GPU)上运行。在 C++中使用标准安卓工具进行声音回放也不简单,例如,应该做一些事情来为 OpenAL 库重用现有的 PC 代码。这本书试图阐明这些主题,并结合一些有用的方法来简化安卓 NDK 的多平台友好开发。

安卓是一个基于 Linux 内核的移动操作系统,为智能手机、平板电脑、上网本和其他便携式设备而设计。安卓的最初开发是由安卓公司开始的,该公司于 2005 年被谷歌收购。2007 年 11 月,第一个版本发布,然而,第一款基于安卓系统的商用智能手机,HTC Dream,几乎在一年后的 2008 年发布。

安卓版本除了数字命名之外,还有官方代号——每个主要版本都以一种甜点命名。以下是与 NDK 相关的安卓平台技术和功能的一些重要里程碑:

  • 1.5 版本(纸杯蛋糕):这个安卓版本的特色是首次发布了支持 ARMv5TE 指令的安卓原生开发工具包。
  • 1.6 版本(甜甜圈):首次引入 OpenGL ES 1.1 原生库支持。
  • 2.0 版本(艾克蕾尔) : OpenGL ES 2.0 原生库支持。
  • 2.3 版(姜饼):
    • 达尔维克虚拟机中的并发垃圾收集器。这具有更快的游戏性能和改进的 OpenGL ES 操作效率。
    • 本机开发工具包的功能得到了极大的扩展,包括传感器访问、本机音频 OpenSL ES、EGL 库、活动生命周期管理和对资产的本机访问。
  • 3.0 版(蜂巢):
    • 支持带有大触摸屏的平板电脑
    • 支持多核处理器
  • 4.0 版(冰淇淋三明治):
    • 智能手机和平板电脑的统一用户界面
    • 硬件加速的 2D 渲染。虚拟专用网客户端应用编程接口
  • 版本 4.14.2(凉粉):
    • 这提高了渲染性能和三重缓冲
    • 外部显示器支持,包括通过无线网络的外部显示器
    • 他们有高动态范围的摄像头支持
    • 用于调试和分析的新内置开发人员选项。Dalvik 虚拟机运行时优化
  • 4.3 版(果冻豆) : OpenGL ES 3.0 原生库支持。
  • 4.4 版本(KitKat) :引入了从 NDK 访问 RenderScript。该功能向后兼容任何运行 Android 2.2 或更高版本的设备。

安卓原生开发套件(NDK)用于要求达尔维克无法提供的性能的多媒体应用,以及直接访问原生系统库。NDK 也是可移植性的关键,这反过来允许使用熟悉的工具(如 GCC 和 Clang 工具链等)进行相当舒适的开发和调试过程。NDK 的典型用法决定了本书的范围——集成了一些最常用的用于图形、声音、网络和资源存储的 C/C++库。

最初,NDK 基于仿生图书馆。它是谷歌为安卓开发的 BSD 标准 C 库(libc)的衍生。仿生的主要目标如下:

  • 许可:原版 GNU C 库(glibc)是 GPL 许可的,Bionic 有 BSD 许可。
  • 尺寸:仿生相比 GNU C 库尺寸要小很多。
  • 速度:仿生是为时钟频率相对较低的移动 CPU 设计的。例如,它有一个 pthreads 的自定义实现。

仿生缺乏在完整 libc 实现中发现的许多重要特性,例如 RTTI 和 C++异常处理支持。然而,NDK 为几个库提供了不同的 C++助手运行时来实现这些特性。这些是 GAbi++运行时、STLport 运行时和 GNU 标准 C++库。除了基本的 POSIX 特性,Bionic 还支持特定于 Android 的机制,例如日志记录。

NDK 是重用大量现有 C 和 C++代码的非常有效的方法。

这本书涵盖了什么

第一章建立构建环境,讲解如何在微软 Windows 和 Ubuntu/Debian Linux 口味上安装配置 Android SDK 和 NDK,如何在基于 Android 的设备上构建运行自己的第一个应用。您将学习如何使用安卓 NDK 系统附带的不同编译器和工具链。还介绍了使用 adb 工具调试和部署应用。

第二章移植公共库,包含一套将成熟的 C++项目和 API 移植到安卓 NDK 的食谱,如 FreeType 字体渲染库、FreeImage 图像加载库、libcurl 和 OpenSSL(包括 libssl 和 libcrypto 的编译)、OpenAL API、libmodplug 音频库、Box2D 物理库、Open Dynamics Engine (ODE)、libogg 和 libvorbis。其中一些需要更改源代码,这将在后面解释。这些库中的大多数将在后面的章节中使用。

第 3 章联网,向您展示了如何使用知名的 libcurl 库使用 HTTP 协议下载文件,以及如何使用 C++代码直接从流行的 Picasa 和 Flickr 在线服务中形成请求并解析响应。如今,大多数应用都以这样或那样的方式使用网络数据传输。HTTP 协议是脸书、推特、皮卡萨、Flickr、SoundCloud 和 YouTube 等所有热门网站的 API 的基础。本章的剩余部分专门讨论 web 服务器开发。应用中有一个小型网络服务器,允许开发人员远程控制软件并监控其运行时间,而无需使用特定于操作系统的代码。本章开头还介绍了一个用于后台下载处理的任务队列和简单的智能指针,以实现高效的跨线程数据交换。这些线程原语稍后将在第 4 章组织虚拟文件系统第 5 章跨平台音频流中使用。

第 4 章组织虚拟文件系统,完全致力于异步文件处理、资源代理和资源压缩。许多程序将数据存储为一组文件。加载这些文件而不阻塞整个程序是一个重要的问题。所有现代操作系统的人机界面指南规定应用开发人员避免程序工作流程中的任何延迟或“冻结”(在安卓系统中称为应用不响应(ANR)错误)。安卓程序包只是带有。apk 扩展,用熟悉的 ZIP 算法压缩。允许直接从。apk 我们必须给。使用 zlib 库的 zip 格式。涉及的另一个重要主题是虚拟文件系统概念,它允许我们抽象底层操作系统文件和文件夹结构,并在应用的安卓和电脑版本之间共享资源。

第 5 章跨平台音频流,从使用 OpenAL 库组织音频流开始。在这之后,我们继续进行 RIFF WAVE 文件格式的读取,OGG 沃尔比斯流解码。最后,我们学习如何使用 libmodplug 播放一些追踪器音乐。最近的安卓 NDK 包括一个开放源码软件应用编程接口实现。然而,我们正在寻找桌面电脑和其他移动平台之间的完全可移植的实现,以实现无缝的游戏调试功能。为此,我们将一个 OpenAL 实现预编译成一个静态库,然后在 libogg 和 libvorbis 之上组织一个小型多线程声音流库。

第六章统一 OpenGL ES 3 和 OpenGL 3 ,给出了桌面 OpenGL 3 和移动 OpenGL ES 3.0 的基本渲染循环。将应用重新部署到移动设备是一项冗长的操作,会妨碍开发人员快速进行功能测试和调试。为了允许在 PC 上开发和调试游戏逻辑,我们提供了一种在移动 OpenGL ES 中使用桌面 GLSL 着色器的技术。

第七章跨平台 UI 和输入系统,将教你如何以便携的方式实现多点触控事件处理和手势识别。手机现在几乎是基于手势的触摸输入的同义词。没有图形用户界面,任何面向用户的现代应用都不可能存在。组织交互有两个基本问题:输入和文本呈现。为了便于测试和调试,我们还向您展示了如何在配备多种鼠标设备的 Windows 7 PC 上模拟多点触控输入。由于我们的目标是开发交互式游戏应用,因此我们必须以熟悉的方式实现用户输入。我们将系统地向您展示如何创建屏幕上的游戏手柄用户界面。在全球多元文化环境中,非常希望任何应用都有多语言文本呈现器。我们将向您展示如何使用 FreeType 库来呈现拉丁文、西里尔文和从左到右的文本。多语言 UTF-8 本地化界面的组织将以基于词典的方式呈现。

第八章写一个 Match-3 游戏,将我们介绍的所有技术放在一起,写一个简单的 Match-3 游戏,包括使用 OpenGL ES 渲染,输入处理,资源打包,PC 端调试。该游戏还可以在 Windows 桌面电脑上运行和调试,并且可以轻松移植到其他移动平台。

第九章写一个图片益智游戏,将提供一个更复杂的例子,整合了上面提到的所有东西。以上所有关于图形和输入的元素都将使用本地网络库和应用编程接口从 Picasa 在线服务下载图像。

这本书你需要什么

这本书以一台基于视窗的个人电脑为中心。由于模拟器在 3D 图形和本机音频方面的限制,建议使用安卓智能手机或平板电脑。

本书的源代码基于开源的 Linderdaum Engine,是对引擎中使用的一些方法和技术的硬挤压。你可以到达 http://www.linderdaum.com。

假设具有 C 或 C++的基本知识,包括指针操作、多线程和基本的面向对象编程概念。读者应该熟悉高级编程概念,如线程和同步原语,并对 GCC 工具链有一些基本的了解。我们也希望读者不要害怕从终端/农场管理器/记事本/升华文本中开发没有集成开发环境(是的,开发没有自动完成功能的集成开发环境肯定一项技能)。

本书不涉及 Android Java 开发。你必须读点别的东西来熟悉它。

三维空间中线性代数和仿射变换的一些工作知识有助于理解 OpenGL 编程和手势识别。

这本书是给谁的

您想将现有的 C/C++应用移植到安卓系统吗?你是一个有经验的 C++开发人员,想投身于现代移动开发吗?你想提高你的基于 Java 的安卓应用的性能吗?你想在你的安卓应用中使用用 C++编写的优秀库吗?你想通过在电脑上调试手机游戏来提高工作效率吗?

如果你对这些问题中的任何一个说是,那么这本书就是给你的。

构建源代码

本书代码包中的示例可以使用以下命令进行编译:

  • 对于窗口:全部制作
  • 适用于安卓系统:ndk-buildant 副本-公共媒体调试

惯例

在这本书里,你会发现许多区分不同种类信息的文本风格。以下是这些风格的一些例子,以及对它们的含义的解释。

文本中的码字显示如下:“JAVA_HOME变量应该指向 Java 开发工具包文件夹。”

一段代码的排版如下:

package com.packtpub.ndkcookbook.app1;
import android.app.Activity;
public class App1Activity extends Activity
{
};

当我们希望将您的注意力吸引到特定的代码行时,相关的代码行被强调如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">App1</string>
</resources>

所有命令行输入或输出如下所示:

>adb.exe logcat -v time > 1.txt

新名词重要词语以粗体显示。你在屏幕上看到的文字,例如在菜单或对话框中看到的文字,出现在这样的文本中:“安装该设备软件与否,你应该点击安装按钮”。

警告或重要提示会出现在这样的框中。

类型

提示和技巧是这样出现的。

读者反馈

我们随时欢迎读者的反馈。让我们知道你对这本书的看法——你喜欢或可能不喜欢什么。读者反馈对我们开发您真正能从中获得最大收益的标题非常重要。

要给我们发送一般反馈,只需向<[feedback@packtpub.com](mailto:feedback@packtpub.com)>发送电子邮件,并通过您消息的主题提及书名。

如果你对某个主题有专业知识,并且对写作或投稿感兴趣,请参阅我们在www.packtpub.com/authors上的作者指南。

客户支持

现在,您已经自豪地拥有了一本书,我们有许多东西可以帮助您从购买中获得最大收益。

下载本书示例代码

你可以下载你在http://www.PacktPub.com账户购买的所有 Packt 书籍的示例源代码文件。如果您在其他地方购买了这本书,您可以访问http://www.PacktPub.com/support并注册,以便将文件直接通过电子邮件发送给您。我们努力为这本书编写和调试源代码。事实是,在现实生活中总有 bug 潜伏在代码中,需要在发布后修复。

我们建立了一个 GitHub 存储库,这样每个人都可以下载最新的源代码包,并打开 pull 请求来提交错误修复和改进。知识库可以从https://github . com/corporate shark/Android-NDK-游戏-开发-Cookbook 进行克隆。我们的源代码包的最新快照可在以下网址获得:

勘误表

尽管我们尽了最大努力来确保我们内容的准确性,但错误还是会发生。如果你在我们的某本书里发现了错误——可能是文本或代码中的错误——如果你能向我们报告,我们将不胜感激。通过这样做,你可以让其他读者免受挫折,并帮助我们改进这本书的后续版本。如果您发现任何勘误表,请访问http://www.packtpub.com/support,选择您的书籍,点击勘误表提交链接,并输入您的勘误表的详细信息。一旦您的勘误表得到验证,您的提交将被接受,勘误表将上传到我们的网站上,或添加到该标题的勘误表部分下的任何现有勘误表列表中。通过从http://www.packtpub.com/support中选择您的标题,可以查看任何现有的勘误表。

盗版

互联网上版权材质的盗版是所有媒体的一个持续问题。在 Packt,我们非常重视版权和许可证的保护。如果您在互联网上遇到任何形式的我们作品的非法拷贝,请立即向我们提供位置地址或网站名称,以便我们寻求补救。

请通过<[copyright@packtpub.com](mailto:copyright@packtpub.com)>联系我们,获取疑似盗版资料的链接。

我们感谢您在保护我们作者方面的帮助,以及我们为您带来有价值内容的能力。

问题

如果您对本书的任何方面有问题,可以在<[questions@packtpub.com](mailto:questions@packtpub.com)>联系我们,我们将尽最大努力解决。