7.2、读取modelplist文件

无论模型文件的格式是什么,GPU最终处理的是GPU控制内存中的顶点属性缓存和索引缓存。用正确的格式有效地向GPU发送数据才能获得良好的应用性能。结合和转换COLLADA文件为modelplist文件的主要目的,仍然是可以被iOS应用快速加载。为了加快运行时的速度,所有模型的所有网格都要结合在一个单独顶点属性缓存中,然后就可以在一次操作中全部发送给GPU。同样的,所有的索引数据也都存储在一个单独的缓存中。modelplist 文件还会保存纹理图像数据,这些纹理图像数据会在一个单独的纹理缓存操作中直接发送给GPU。

下面的代码例子显示了加载modelplist文件的步骤。粗体代码行用CocoaTouch的NSKeyedUnarchiver类从modelplist数据中反序列化对象。然后这段代码提取了一 个textureInfo对象、一个合并的网格,以及一个描述网格数据中的模型名字的字典(dictionary)。


/////////////////////////////////////////////////////////////////
// This method initializes the texture, mesh, and models loaded
// from a plist archived in data.
- (BOOL)readFromData:(NSData *)data 
   ofType:(NSString *)typeName 
   error:(NSError **)outError
{
   NSDictionary *documentDictionary = 
      [NSKeyedUnarchiver unarchiveObjectWithData:data];

   self.textureInfo = [GLKTextureInfo 
      textureInfoFromUtilityPlistRepresentation:
         [documentDictionary objectForKey:
         UtilityModelManagerTextureImageInfo]];

   self.consolidatedMesh = [[UtilityMesh alloc] 
      initWithPlistRepresentation:[documentDictionary 
      objectForKey:UtilityModelManagerMesh]];

   self.modelsDictionary = 
      [self modelsFromPlistRepresentation:[documentDictionary 
      objectForKey:UtilityModelManagerModels]
      mesh:self.consolidatedMesh]; 

   return YES;
}

plists文件可能包含CocoaTouch支持的对象的任意组合。plists文件常常用来保存数组字典的字典以及类似的嵌套结构。modelplist 格式会存储一个特定的结构,但是plists 文件天生是可扩展的。当所需元素存在时, modelplist 文件中可能要保存额外的数据。


注意

苹果公司规定了常规plist格式的标准。在modelplist文件中的特定对象结构支持本书中的例子。不同的应用肯定会保存不同的信息或者完全不用plist 格式。一个应用使用哪种格式来加载模型数据都可以,只要这个格式快速、紧凑,并且支 持你使用的资源管道。


modelplist文件必须要包含特定的对象。首先,根对象是一个NSDictionary。根对象是NSKeyedUnarchiver的“ -unarchiveObjectWithData:”方法返回的对象。根对象 包含了plist 文件中的所有其他对象。字典保存了一个键值对的集合,并且为键快速查询做了优化。在代码中创建的字典可以使用几乎任意的对象作为键,但是在plists文件中的字典通常使用字符串作为键。modelplist 文件的根字典必须至少要包含三个键,即textureImageInfo、models 和mesh。


textureImageInfo, models, and mesh.

/////////////////////////////////////////////////////////////////
// Constants used to access model properties from a plist
// dictionary.
extern NSString *const UtilityModelManagerTextureImageInfo;
extern NSString *const UtilityModelManagerMesh;
extern NSString *const UtilityModelManagerModels;

在modelplist文件中,与每个根目录键相伴的对象也是字典。图7-3图解了这个格式。灰色显示的对象在每个modelplist文件中都是一样的。白色显示的对象包含要从文 件中提取的独一无二的数据。在“models"字典里的键是所包含的模型的名字。每个模型必须要有一个独一无二的名字,因为每个键只能在一个字典中出现一次。

例子OpenGLES_Ch7_1提供了UtilityTextureInfo、 UtilityModelManager、 UtilityModel和UtilityMesh类,每个类都会从modelplist文件中提取相关的信息。UtilityTextureInfo使用"textureImageInfo” 字典。UtilityModelManager 使用“models" 字典,同时创建一个UtilityModel实例的新字典,并且每个实例都会读取一个字典。 UtilityMesh类会从“ mesh"字典中抓出数据。

接下来的一节包含了使用UtilityTextureInfo、UtilityModelManager、 UtilityModel和UtilityMesh类的代码。在第6章中,从例子OpenGLES_Ch6_2到OpenGLES_Ch6_5,网格和模型一直以大致相同的方式工作。网格就是共边三角形组成的网,并且网格定义了3D图形。网格数据的最初来源( 硬编码或者从文件加载)并不重要。GPU擅长使用类似索引顶点的优化来渲染网格。高效地向GPU发送静态/不变的网格数据 实现了高性能渲染。

图 7-3

results matching ""

    No results matching ""