游戏开发中的纹理图集工具

游戏开发过程中,优化图像资源是提升游戏性能和减少内存浪费的重要步骤。纹理图集工具应运而生,它能够将多个图像打包成一个纹理,从而提高加载速度,减少GPU内存的浪费。本文将介绍这种工具的主要特点、工作原理以及如何使用它。

纹理图集工具的特点

纹理图集工具具有以下显著特点:

1. 加载速度快:与传统的PNG格式相比,纹理图集能够实现近5倍的加载速度提升。

2. 一键操作:简化了艺术流程,用户只需点击一次,即可创建多种格式的多个图集。

3. 开源:提供Java源代码,用户可以根据自己的需求进行修改。

纹理图集是什么?

纹理图集是一种将多个图像打包到一个单一纹理的技术。在某些平台上,如OpenGL,纹理的大小必须是2的幂次方。如果单独加载这些图像,将需要大量的填充,这意味着GPU内存的浪费。此外,将所有图像打包到一个纹理中,可以实现绘制调用的批处理,即多个精灵可以一次性绘制。

适用对象

虽然这个工具是为iPhone开发的,但它对大多数平台都很有用,包括Android和PC。该工具是用Java编写的,可以在Windows、Mac和Linux上运行。

附带的示例iPhone项目展示了如何加载纹理图集。代码是用C++编写的,设计为可移植的。

如何使用

1. 下载并解压文件AtlasMaker_jar_2.2.1.zip。需要在机器上安装Java才能使用它。如果需要创建PVR压缩纹理,可能还需要安装Imagination Technologies的PVRTexTool。

2. 输入文件夹:项目源图像必须是PNG格式,并根据文件格式组织在目录中。选择输入文件夹的位置,将显示目录结构。然后选择每个目录所需的文件格式。

3. 输出文件:选择输出文件的名称和位置。纹理图集将保存到同一目录中。

4. 高级选项:点击“选项...”按钮打开高级选项。可以设置最大纹理大小、是否为2的幂次方、透明像素的alpha阈值、PVRTexTool的位置等。

纹理图集的创建过程

应用程序尝试将图像放入尽可能小的纹理大小中。如果是2的幂次方纹理,首先尝试放入32x32,然后是32x64,然后是64x64,依此类推,直到最大值。如果是非2的幂次方,它将自动选择最小的任意大小。如果图像无法放入最大大小的纹理中,将创建额外的纹理,直到所有内容都适合。

如果选择了PVR格式,纹理将是正方形且为2的幂次方。每个文件将根据目录和索引号命名。例如,如果图像在目录"images"中,可能会创建以下纹理:images0.tga, images1.tga, images2.tga等。

输出XML文件

应用程序创建一个XML文件,其中包含每个纹理图集中每个图像的所有数据。例如:

<atlas numImages="4"> <texture file="testImages0.pvr" trans="true"> <image name="arch" x="0" y="0" width="89" height="71"/> <image name="prowlerBody0_1" x="36" y="342" width="43" height="34" yOffset="5" transWidth="46" transHeight="39"/> </texture> <texture file="dump0.pvr" trans="true"> <image name="arrowDownPressed" x="400" y="54" width="46" height="39"/> <image name="arrowUpPressed" x="448" y="54" width="46" height="37"/> </texture> </atlas>

首先,“atlas”元素告诉图集中的总图像数,因此在加载时可以预先分配内存。然后每个纹理元素都有文件名、透明度和图像元素列表。每个图像元素包含以下数据:x, y, width, height(图像在纹理中的位置和大小),xOffset, yOffset, transWidth, transHeight(精灵动画的填充数据)。

为什么PNG不适合游戏

PNG是一种复杂的格式,解码速度慢。以下是一些基准测试,显示了PNG的慢速:

格式 加载Windows (libpng) 加载iPhone 3GS 大小 压缩大小
PNG 64 ms 385 ms 1.27 MB 1.26 MB
Targa 32-bit 9 ms 83 ms 2.42 MB 1.25 MB
Targa 16-bit 5 ms - 1.23 MB 339 kB

如所见,在iPhone上加载纹理比32位Targa慢4.6倍。尽管Targa文件是两倍大,但它在压缩后的大小相同,因此包大小将相同。此外,如果图像只需要16位质量,可以节省双倍。PNG没有16位选项。

如所见,使用Targa是明智的选择。

注意事项

PNG在iPhone上使用原生iOS API(即UIImage)解码。Targa是压缩的RLE Targa。

16位Targa存储为GL_UNSIGNED_SHORT_4_4_4_4。然而,如果纹理图集完全不透明,则不保存alpha通道,像素存储为GL_UNSIGNED_SHORT_5_6_5。如果选择了“Targa True Color”,则根据是否有alpha透明度,将其保存为32位或24位。

示例iPhone项目

包括一个xcode项目,它打开生成的纹理并显示一个精灵。大部分代码是用C++编写的,以便于移植。

项目中使用了以下类:

  • Game:主游戏对象。
  • ResManager:设置OpenGL状态并初始化所有资源。
  • AtlasMaster:读取图集XML文件并创建AtlasImage对象和纹理,并将它们存储在映射中以供检索。
  • XParser:快速XML解析器,功能简化。使用前向方法解析,以避免创建DOM的开销。
  • TargaReader:读取32位和16位Targa文件。
  • CommonBuffer:所有纹理文件都加载到一个共享缓冲区中,而不是每次创建和删除。
  • ImagePVR:加载PVR纹理。
  • AtlasImage:为每个图像创建一个纹理四边形。

注意:该项目使用boost/unordered_map.hpp。需要下载boost并将项目包含头文件在xcode中指向安装boost的位置。或者,可以在precompile.h中将行: #define fmap boost::unordered_map 更改为: #define fmap std::map

版本2.0:

  • 增加了非2的幂次方功能。
  • 允许用户指定最大纹理大小。
  • 改进了图集创建算法。
  • 使代码更加健壮。
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485