针对equalizer(v0.3)中eqPly的分析

此次分析以0.3版本中所带的eqPly应用为对象,从入口(main)函数入手,由外向内逐步深入,重点是流程与主要对象的结构。

一个Equalizer驱动的系统包括一个服务器(server)与若干客户端,其中客户端分为两类,一类是应用客户端(application),一类是渲染客户端(render client)。

客户端的编程接口由一系列以树状结构管理的资源对象实现,这些对象包括config、node、pipe、window、channel,通过一个nodeFactory对象进行封装,并根据客户端从服务器获取的compoun进行配置,同时由各个对象的可重载Task接口自动响应来自服务器的各项指令。

main函数

1. 创建eqPly::LocalInitData对象,解析命令行参数;

2. 创建NodeFactory用于Equalizer的初始化;

3. 创建一个客户端的子类client=eqPlay::Application对象,该对象是应用与渲染过程的主要对象;

4. 运行client对象;

5. 释放对象并退出;

其中第2至5步为主要的工作。

一个EqPly应用客户端中包含三个主要的对象,用于管理全部Equalizer资源的nodeFactory对象,其中的各个成员对象负责完成配置的管理以及响应来自服务器的指令;用于应用配置的InitData对象,其中包括解析命令行所获得的参数,从系统自动获得的状态信息,以及用于进行分布式渲染的数据;客户端client对象则用于管理整个客户端应用。

命令行的解析

命令行的解析是由LocalInitData对象利用TCLAP命令行工具实现,该工具可直接将命令行参数解析为不同的参数。

其中以TCLAP::CmdLine作为命令行的解析器,然后将不同类型的TCLAP::Arg对象添加到该解析器内部,由TCLAP::CmdLine::parse命令完成对命令行的解析。

命令行解析后的参数作为成员变量由LocalInitData类及其父类的对象保存,并通过公共接口获取实际数据。

eq::init

该函数首先根据命令行参数中的“eq-server”确定服务器的地址,然后构造Global::_nodeFactory,最后根据命令行参数对eqNet进行初始化。

Application::run()

1. 首先根据命令行参数创建server对象并与之建立连接;

2. 然后从server获取配置数据,即Config对象,其中包含的FrameData对象就是用于多个客户端之间同步的帧数据;

3. 根据初始化数据对Config对象进行初始化,其中也包括FrameData对象数据的初始化,此时server会等待所有的client与renderer都完成初始化后才会返回;

4. 进入渲染循环,首先在config::startFrame中更新同步数据_frameData,打包并向外发送数据,;

5. 退出config对象;

6. 清空并退出;

空间数据的管理

根据Ply模型数据以顶点和面作为基本的构成元素的特点,eqPly中通过一组模板类对模型(N对象进行封装,即typedef PlyModel< NormalFace > Model,其中face的类型ormalFace)与vertex的类型(ColorVertex)均为模板对象的实例类型。

PlyFileIO.h与PlyFileIO.h定义文件操作类PlyFileIO,该类首先根据文件名尝试加载已经处理成八叉树结构的二进制文件,如果加载失败则尝试加载原始的ply文件,注意ply文件同样存在ascii与二进制两种类型。

PlyModel.h与PlyModel.cpp用于定义模板类template<class FaceType> class PlyModel,该类基于多边形面和八叉树的包围盒对模型数据进行管理。“八叉树类似于轴对齐BSP树,沿着长方体的三条轴对长方体进行同时分割,分割点必须位于长方体的中心,这样可以生成8个新的长方体”。每个包围盒以其长方体的顶点坐标中的最大值、最小值两个三维向量进行描述,见PlyModel::calculateBBox()。

在直接从ply文件中读取模型数据时,PlyModel通过setFaces获取面数据并根据松散八叉树规则进行划分,从而构造完整的模型对象;当以二进制形式加载已经处理好的模型数据时,PlyModel以二进制形式从缓存中直接读取以八叉树形式存储的数据来填充模型对象。

PlyModel的二进制文件格式如下:

version (文件版本号)

_nFaces (模型的总面数)

_faces (多边形的面数据,以bbox所定义的顺序进行存储)

_bbox (包围盒的八叉树)

normalFace.h、colorVertex.h、Vertex.h用于定义上述模板类中所用的FaceType与VertexType类型,这里均是以结构体形式定义,而不是类的形式,估计Eileman认为这些对象只是用于封装数据而与操作无关。

eqPly中的模型加载,在进行包围盒处理时由于内存占用过多导致分配失败,具体见PlyModel::fillBBox。因此如何解决大规模数据的加载与处理是首先需要解决的问题。

eqPly的渲染

eqPlay对模型的管理在eqPly::Node中进行,在Node::IniConig中加载模型,若命令行参数中指定了加载的模型并能够从工作目录中成功加载该模型,就以该模型进行渲染,否则如果是从VC中运行,则从缺省路径下获取rockerArm.ply模型,如果直接从命令行运行或者该模型仍无法正常加载,则构造简单的四边形模型对象。

命令行中采用[-m string]的格式指定模型文件,string为ply模型的文件名,eqPly首先察看是否存在已经进行了格式转换,即进行了包围盒划分的二进制数据文件(*.b32),如果有该文件可直接加载,否则就需要先加载ply文件,在完成文件解析和包围盒划分后创建模型对象,同时将模型数据保存为二进制数据文件(*.b32)共以后的快速加载,模型文件的加载由PlyFileIO类实现。

加载好的模型对象由PlyModel的对象,以八叉树的包围盒结构进行管理,每个包围盒节点包含包围盒数据,包围球以及其中的多边形面数据。

在渲染某个节点时,首先根据该根节点的包围球与视锥的信息进行可视化检测,若该包围球完全位于视锥内则认为该包围盒内的多边形均为可见,则遍历该节点下的所有节点并逐个执行各个节点的渲染指令;若包围球只是部分的位于视锥内,则该节点为部分可见,此时需要对该节点的所有子节点进行可见性的检测。上述迭代过程从模型对象的根节点开始,直至对模型的所有节点进行检测和渲染后结束。

当确定某个节点可以进行渲染时,首先查找该节点的对应显示列表是否存在,若存在则直接采用显示列表进行渲染,否则根据节点内存储的多边形面数据创建显示列表并据此进行渲染。


 

你可能感兴趣的:(针对equalizer(v0.3)中eqPly的分析)