随着计算机图形技术与网络技术的迅猛发展,两者的结合势在必行。在商业、科研、教育、娱乐等领域,用于分布式虚拟环境(Distributed Virtual Environments; DVEs)和计算机支持协同工作(puter Supported Cooperative Work; CSCW)的图形系统已成为研究与应用的热点。著名的DVEs系统有DIVE、dVS、MR、Repo…3D等。但是这些DVEs系统缺乏3D开发工具的交互式图形功能以及通用性,而通用的3D开发工具如Open Inventor则又不支持分布式计算和协同工作。由于在窗口系统、图形支撑库、编程语言等方面存在差异,上述DVEs系统和3D开发工具难以方便地结合使用。
我们多方面分析了3D需求及软硬件条件,研制完成运行于PC平台,支持协同工作的交互式三维图形软件开发系统,如图5。8所示。其中:
(1)Intra3D 2。0是基于OpenGL的通用交互式三维图形软件开发工具,可用于快速开发Window 9x/NT下的交互式三维图形应用软件。
(2)CNC 1。0是支持协同工作的网络通讯开发系统(Cooperative work municator),其核心是支持“发布—订阅模式”与“组播模式”的服务器与API。
结合Intra3D 2。0和CNC 1。0,可以快速开发支持协同工作的交互式三维图形应用软件。
图5。8 支持协同工作的交互式三维图形软件开发系统
5。5。2 通用交互式三维图形软件开发工具 Intra3D 2。0
Intra3D 2。0的核心是集成了场景数据结构、图形对象、三维交互算法和图形用户界面的C++类库与(ponent Object Model)对象库,支持Visual C++、Visual Basic、Delphi等语言的应用编程。Intra3D的核心库分四层创建:
(1)第一层为“基础对象与函数”(Basic Objects and Functions);
(2)第二层为“图形对象”(Graphical Objects);
(3)第三层为“场景图与节点”(Scene Graph and Nodes);
(4)第四层为“绘制与交互”(Rendering and Interaction)。
体系结构如图5。9所示,其中高层构件可以引用低层构件,但低层构件不能引用高层构件。
图5。9 Intra3D 2。0 的体系结构
Intra3D 2。0是免费软件,有配套书籍《交互式三维图形技术与程序设计》。标准版软件约25兆,核心库7万多行C++代码全部公开,用户可以方便地修改内核以适应不同的需求。
5。5。2。1 主要模块和功能
一、基础对象与函数层
(1)定义了用于对象引用计数的内存管理基类;
(2)矢量、矩阵与四元组运算,鼠标跟踪球算法;
(3)点阵字体与三维矢量字体输出,常用于数据可视化图形的数据标注;
(4)图像输入输出以及纹理映射,支持BMP、GIF、JPEG、SGI、TGA等图像格式;
(5)常用几何图元的绘制,如锥、柱、球、环等,并支持Swept形体,螺旋体的绘制;
(6)提供450余种材质,在第四层中可以交互式编辑这些材质。
二、图形对象层
图形对象能将数据转化为几何模型并可以绘制出来。Intra3D 2。0版提供了三类图形对象:
(1)常用几何对象,如长方体、锥体、圆柱体、球体、圆环体、Swept形体等;
(2)多边形模型对象,可用于绘制Autodesk公司。3ds模型和Wavefront公司的。obj模型;
(3)商业统计图形对象,如柱形图、带状图、条形图、折线图、面积图、饼图、塔形图、曲线图、曲面图、进程图、股票图等。
图形对象的开发与应用问题密切相关,用户可以使用继承方法扩充新的图形对象,而不会影响到其它三层的构件。
三、场景图与节点
场景图(Scene Graph)是有向无环图,Scene Graph的主要节点有:(1)SceneNode是所有节点的基类。在SceneNode中定义了局部坐标系以及相应的图形变换,这样便于第四层以同样的操作方式实现三维交互。(2)相机节点(CameraNode)支持平行投影与透视投影,支持多个相机切换。(3)光源节点有三种:平行光源节点(DirLightNode)、点光源节点(PointLightNode)和锥光源节点(SpotLightNode)。(4)形体节点(ShapeNode)用于引用图形对象,有关图形对象的三维交互均由ShapeNode处理。
四、绘制与交互层
Intra3D的交互分两类:一类是对形体、光源和相机的直接操作,另一类是真实感属性的编辑。Intra3D的场景视图构件(SceneView)封装了交互式绘制的所有细节,如消息处理、场景节点的遍历绘制、多重采样消锯齿、鼠标交互等。为了便于编辑真实感属性,Intra3D定制了一些常用对话:矢量字体对话(FontDialog)、颜色对话(ColorDialog)、材质库对话(MaterialLibDialog)、材质对话(MaterialDialog)与光源对话(DirLightDialog; PointLightDialog; SpotLightDialog)。
5。5。2。2 用户界面设计
Intra3D的场景视图构件SceneView用于快速创建交互式3D应用程序的主界面。SceneView支持selecting、scaling、rotating、translating、creating、deleting等三十余种操作,并提供工具条方便于交互,如图5。10所示。
为了编辑真实感属性,常需在对话框中绘制3D 图形。Microsoft的窗口系统不提供3D的对话窗口。使用Intra3D的Window3D构件可在对话框中创建多个3D视图,图5。11的材质对话和图5。12的材质库对话都使用了Window3D构件。颜色编辑是3D图形程序中最常用的交互,材质与光源的编辑实际上是通过改变颜色分量来实现的。需要进行颜色编辑的交互均涉及HSV与RGB模式的颜色转换。Intra3D的“绘制与交互层”实现了这些计算,并且提供彩色的滑动条用于鼠标交互。图5。13、图5。14分别为点光源对话和颜色对话。
图5。10 用于直接操作的三维交互工具条
图5。11 材质对话 图5。12 材质库对话
图5。13 点光源对话 图5。14 颜色对话
5。5。3 支持协同工作的网络通讯开发系统 CNC 1。0
最简单的协同工作模式是让两个客户机直接通讯,可以用Socket编程实现。假设有 n 个客户机参加协同工作,每个客户机将与所有其它的客户机通讯。那么总共存在n(n…1)/2 个Socket直接通讯,并且每个客户机的变动将导致其它客户机的修改。这种Socket直接通讯使得协同工作的管理和客户机的程序设计变得非常困难。CNC系统提供了支持“发布—订阅(Publish…Subscribe)”与“组播(Multicast)” 模式的服务器与API,可以高效地管理多个组群的协同工作,并使得客户机的程序设计十分简单。CNC 1。0的系统结构如图5。15所示。
CNC 服务器将客户机分组管理。在“发布—订阅”模式中,将产生数据的进程称为生产者(Producer),将接受数据的进程称为消费者(Consumer)。生产者可以向服务器发布数据,服务器保存这些数据。消费者可以向服务器订阅数据。每个客户机可能是很多数据的生产者或消费者。同一时刻,CNC系统允许有任意多个生产者和消费者存在。CNC的“发布—订阅” 功能是用TCP协议实现的。
在“组播” 模式中,服务器动态地分配每个组的组播地址。客户机可以向服务器申请加入任意组,允许向任意组播放消息,服务器不保存这些组播消息。CNC的“组播”功能是用UDP协议实现的。
图5。15 CNC 1。0 的系统结构
5。5。3。1 CNC 客户机的API设计
类CNCClient客户机用来实现“发布—订阅”和“组播”功能,主要接口(公有函数)如下:
class CNCClient
{public:
BOOL Connect(…);// 连接服务器
BOOL Disconnect();// 与服务器断开连接
BOOL PublishData(…);// 向服务器发布数据
BOOL QueryData(…); // 向服务器查询数据
BOOL SubscribeData(…);// 向服务器订阅数据
GROUPIP QueryGroupIP(…); // 向服务器查询组播地址
DWORD MulticastMessage(…);// 发送组播消息
virtual void MessageResponse(…);// 响应组播消息
…
};
一、客户程序的“发布”协议
客户机向服务器发布的每个数据报均含有数据类型、工作组名称、数据名称、生命期和数据长度的信息。报文格式如图5。16所示,数据结构见 DataPublish :
struct DataPublish
{
BYTE iDataType;// 2 个字节数据类型,宏定义为DATA_PUBLISH
charstrGroupName'16';// 16个字节的工作组名字
charstrDataName'16';// 16个字节的数据名字
DWORDdwLifeTime;// 4 个字节的数据生命期,以秒为单位
DWORDdwLength;// 4 个字节的数据内容的长度
char*pchContent;// 数据内容
};
2字节 16字节 16字节 4字节 4字节
图5。16 用于发布的报文格式
二、客户程序的“订阅”协议
客户机向服务器订阅数据分两步实现:
(1)先调用函数QueryData向服务器发送一个 DataQuery格式的报文,用于查询要订阅的数据是否存在。
struct DataQuery
{
BYTEiDataType;// 2 个字节数据类型,宏定义为DATA_QUERY
char strGroupName'16';// 16个字节的工作组名字
char strDataName'16'; // 16个字节的数据名字
};
(2)服务器接收到查询时,按照 DataQuery结构中的strGroupName和strDataName进行搜索。如果该数据不存在,Server向Client发送一个FALSE标志。如果该数据存在,服务器先向客户机发送一个TRUE标志,之后立即再向客户机发送该数据(DataPub