65.9K
CodeProject 正在变化。 阅读更多。
Home

3D图形应用程序的可自定义架构

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (28投票s)

2013 年 6 月 24 日

GPL3

13分钟阅读

viewsIcon

59827

通过一个基本的OpenGL应用程序,解释了一个统一的3D图形软件架构。

1. 引言

2. 背景和涵盖的主题

3.IssiGraph 项目 

3.1 要求  

3.1.1 功能要求 

3.1.2 非功能性要求

3.1.3 用例 

3.2 架构

3.3 高层设计

3.3.1 用户界面

3.3.2 数据管理

3.4 详细设计 

3.4.1 类图

3.4.1.1 演示子系统 

3.4.1.2 基本层次子系统

3.4.1.3 曲面子系统 

3.4.1.4 二次曲面子系统

3.4.1.5 世界子系统 

3.4.1.6 工具子系统

3.5 实现 

3.5.1 编译器 

3.5.2 库 

3.5.3 框架 

3.5.4 代码分发 

3.6 测试  

3.6.1 白盒测试 

3.6.2 黑盒测试 

4. 版本和功能 

5. 贡献 

6. 1.41 版本中的新功能

7. 延伸阅读和参考资料 

1. 引言   

本文包含用于创建 3D 图形应用程序基础架构的信息和构建工件。其主要目标是作为构建各种 CAD 应用程序的起点,重用所解释的架构作为图形软件的设计模式。 

2. 背景和涵盖的主题  

本文的预期读者是具有 C++ 编程和软件方法学强大背景的软件分析师和软件工程师。因此,为了很好地理解本文,您最好精通以下主题:  

  • UML 2.0。 
  • 软件方法学。 
  • 设计模式。 
  • ANSI/ISO C++ 面向对象编程。 
  • GUI 编程和设计。 
  • 3D 图形基础数学。 

本文旨在传达这样一种概念:一组类可以独立于所使用的语言或框架,在面向对象范式中促进 3D 图形软件的构建。

3. ISSIGraph 项目  

ISSIGraph 项目被构想为曲面建模器作业的基础原型。它是由国家远程教育大学 (UNED) 的软件工程和计算机系统系开发的。最新的更改和更新体现在您在此处看到的成果中。为了设计和实现该工具,我遵循了一种类似于 RUP (Rational Unified Process) 的小型方法。在接下来的章节中,您将能够看到用于编写ISSIGraph 的主要软件工程生命周期。

3.1 要求  

在我构思ISSIGraph 应用程序时,我试图满足以下功能和非功能性要求。 

3.1.1  功能要求 

ISSIGraph 应用程序应允许轻松地以线框方式绘制 Bezier 和 NURBS 曲面,以及任何其他曲面,如球体、圆锥体、圆柱体、茶壶、环面等。此外,还必须能够渲染 3D 文本。所有这些对象都必须能够以简单直接的方式在场景中移动、旋转和缩放。   

该应用程序应支持 BMP、JPEG 和 PNG 文件格式导出,并可以更改背景颜色,以及导出屏幕内模型的 XML。 

与其他自定义图形应用程序一样,用户应自由执行复制、粘贴和剪切操作,以及撤销/重做操作。最后,应用程序应允许在初始 1024 x 768 窗口外部的虚拟空间中移动、旋转和缩放 3D 对象,方法是使用控制器面板。 

3.1.2 非功能性要求  

以下列出了一些最重要的性能和环境要求: 

  • 以最低的 CPU 成本实现高性能。 
  • 复杂度为 O(n) 的算法。 
  • OpenGL 作为 3D 库。 
  • 跨平台:Windows、Linux 和 Mac OS X。
  • 使用 wxWidgets 2.9.3 框架。
  • 低内存开销。
  • 吸引人的设计。
  • 易于安装和使用。
  • 安全系统。
  • 可读代码。 
  • 以开源形式发布。 

3.1.3 用例   

用例图有助于捕获实现ISSIGraph 应用程序所需的请求。图的左侧是与系统交互的主要参与者;右侧是主要用例: 

图 1。 用例图

3.2 架构 

ISSIGraph 的基本架构基于三层应用程序。如下所示,自下而上的层执行用户界面管理,中间层执行业务逻辑,底层处理图形和硬件库。最后,所有这些层都建立在平台实现之上。   

 

图 2。 架构布局

3.3 高层设计 

3.3.1 用户界面   

[1]所述,用户界面的目标是: 

A) 将控制权交给用户 

  • 定义交互模式,以便用户不必执行不必要的操作。
  • 考虑灵活的交互。  
  • 用户交互必须是可中断和可撤销的。 
  • 向用户隐藏技术复杂性。  
  • 直接与屏幕对象交互。  

B) 减轻用户内存负担 

  • 减少短期记忆需求。  
  • 使用默认值。  
  • 使用快捷方式。 
  • 视觉格式必须是世界的隐喻。  
  • 使用嵌套菜单。   

C) 构建一致的界面 

  • 允许用户在合适的上下文中执行任务。例如,对象选择器。
  • 在应用程序系列中保持一致性。
  • 使用助记规则。 

图 3。 用户界面 

3.3.2 数据管理  

为了实现持久性,我没有使用序列化,因为这不适合信息交换。为了实现具有互操作性和信息可移植性的持久性,我选择使用 XML 文件格式,编码为 UTF-8。  XML 是一个结构良好的规范,允许您组织和交换数据以供以后使用。您可以在此处查看用于在ISSIGraph 中存储 3D 模型的 XML 示例。 

3.4 详细设计   

3.4.1 类图

3.4.1.1 演示子系统

该子系统负责通过wxWidgets 用户界面框架管理用户交互。IssiFrame 类包含对 IssiGLCanvas 的引用,这是一个适合渲染 OpenGL 基元的上下文。此类启动并处理OnPaint 事件。此子系统通过向业务域对象发送消息与 World 子系统进行交互。

图 4。 演示子系统

 

3.4.1.2 基本层次子系统

该子系统是应用程序中其余对象继承的核心基类。Box 抽象类允许您管理和实现后续继承类的行为;但它在 QuadricBoxVertexBox 核心基类中被覆盖。 

 

图 5。 基类 

3.4.1.3 曲面子系统 

这是从 Box 类继承的第一个子系统。VertexBox 核心类允许您实现 NURBS、Bezier 和控制点 3D 数学特殊要求。 

 

图 6。 曲面子系统 

3.4.1.4 二次曲面子系统 

与曲面子系统一样,该子系统允许您实现基本 3D 曲面,如立方体、茶壶、球体、圆锥体等。最终继承的类,如 CylinderConeTorus 等,实现了在 QuadricBoxQuadric 等顶层核心类中定义的虚拟行为。请注意,OneDimension TwoDimension 类实现了更改体积尺寸(如高度和宽度)的设施。

图 7。 二次曲面子系统 

3.4.1.5 世界子系统

最后,World 类是接收来自演示子系统wxWidgets 框架生成的事件的所有消息的接收对象。该子系统实现了所有与业务逻辑相关的行为,即整个ISSIGraph 应用程序的功能。  

Axis 类实现了可移动的坐标系统,它继承自 VertexBox 抽象类。Memory 类实现了用于复制/粘贴/剪切以及撤销/重做过程的内存操作的小型设计模式。 

图 8。 世界子系统 

3.4.1.6 工具子系统 

这组简单的类是一个帮助系统包,包含所需的数学、库特定和转换例程。它们被分组为静态成员函数,对应用程序的正确性和组织性很有用。

图 9。 工具子系统 

图 10。  序列图   

  1. 用户想移动整个NURBS。他将其通知给IssiGLCanvas 对象。   
  2. IssiGLCanvas 对象向World 对象报告。 
  3. World 对象(根据业务逻辑)报告要移动的 NURBS。 
  4. NURBS 对象向上调用其Surface 基类。  
  5. Surface 对象迭代存储在列表中的所有CtrlPoint 对象以移动它们。 
  6. 现在,用户想更改环面的尺寸,所以他将其通知给IssiGLCanvas 对象。
  7. 同样,IssiGLCanvas 对象向World 对象报告。 
  8. World 对象对Torus 对象执行操作。 
  9. 因为环面对象有两个维度(内半径外半径),所以它被通知给TwoDimension 对象。    
  10. 现在用户想移动Axis 对象。   
  11. 同样,IssiGLCanvas World 对象报告。 
  12. World 对象(根据业务逻辑)报告Axis
  13. 突然,发生了一个 ONPAINT 事件。
  14. 因此,ISSIGLCanvas 通知 World 对象的渲染方法。
  15. World 对象调用其NURBS 对象来处理其控制点。 
  16. 根据这一点,NURBS 处理其所有控制点。 
  17. 现在,World 的渲染例程必须绘制其NURBS
  18. 因此,NURBS 迭代以绘制其所有控制点。 
  19. 同样,World 的渲染例程必须绘制其Torus 对象,
  20. 以及绘制选择矩形(DrawBox),
  21. NURBS 的选择矩形(DrawSelection)处理程序,
  22. 以及 Torus 的选择处理程序。  
  23. 最后,World 的渲染例程绘制Axis(坐标系统)。

3.5 实现  

3.5.1 编译器  

整个应用程序是用 C++ 在Windows XP 32 位版本的Visual C++ 2010 Express Edition 编译器上开发的。之后,该应用程序被移植到Linux (使用 GNU-GCC 4.9),最后,Leopard Mac OS X 版本使用 X-Code GCC 4.0 和 GNU Make 进行移植。 

3.5.2 库  

为了实现合适的 3D 图形输出和最先进的 3D 应用程序,我使用了 OpenGL 库进行基元绘制,并使用 GLUT 进行二次曲面和文本输出。如[2]所述,我选择使用 GLEW 库进行 NURBS 和 Bezier 绘制,而不是实现一个算法来细分它们。然而,在 Linux 和 Mac 版本中,我不得不使用freeglut 进行 GLUT 基元。   

 

3.5.3 框架  

我用于所有应用程序的通用框架是wxWidgets 2.9.3 版本,因为它是一个免费稳定的软件,用于跨平台用户界面实现。 

3.5.4 代码分发  

分发的代码具有以下结构
 

 

源文件 含义
main.h 用户界面主头文件
main.cpp 用户界面主实现文件
box.h 基本子系统头文件
box.cpp 基本子系统实现文件
surface.h NURBS、Bezier 和控制点 头文件
surface.cpp NURBS、Bezier 和控制点实现类
quadric.h 二次曲面、体积和文本头文件
quadric.cpp 二次曲面、体积和文本实现类
textout.h GLUT 文本例程类头文件
textout.cpp GLUT 文本例程类实现文件
world.h 世界子系统头文件类 
world.cpp 世界子系统实现类
tool.h 工具子系统头文件类
tool.cpp 工具子系统实现类

表 1。 源代码文件目录结构 

3.6 测试  

根据[1],应用于ISSIGraph 测试的动态技术可以确保应用程序的质量。   

3.6.1 白盒测试   

这项技术试图根据程序的内部结构来检查程序逻辑。也就是说,它允许查看应用程序的内部(这将是一个符号框)。 

由于在 100% 的情况下进行穷尽和完整的测试是不切实际的,我试图进行代码覆盖,包括所有基本语句、决策和条件路径,以及纸上审查作为软件度量。   

3.6.2 黑盒测试     

通过这项技术,我试图根据执行的函数规范来检查应用程序的行为。之所以这样称呼,是因为它不关心应用程序的内部,而是执行响应。

为了执行黑盒测试,我使用了边界值分析,例如使用少量控制点和对象与大量控制点和对象进行比较。 

为了展示良好的应用程序性能,我设计了两个黑盒测试用例(A 和 B)作为有用的压力测试,使用了以下系统设备: 

  • Mac Book Pro   
  • Intel CPU 搭载 Core i5 (四核) M529 2.40 GHz @ 1.17 GHz
  • 2.17 GB RAM  
  • Windows XP 32 位操作系统 
  • NVidia GeForce GT 330M  

案例 A 

  • 3 个圆锥体
  • 2 个环面
  • 1 个茶壶
  • 1 个二十面体 
  • 1 个十二面体
  • 1 个菱形十二面体
  • 1 个文本
  • 1 个 NURBS
  • 1 个 Bezier
  • 1 个坐标系统  

图 11。 案例 A

旋转整个场景时的性能和开销是
 

图 12。 A 中的系统性能

 案例 B

  • 2 个茶壶
  • 2 个 NURBS

图 13。 B 案例 

 在此案例中,对象被放大 4 倍,因此性能是
 

 图 14。 B 中的系统性能

4. 版本和功能    

ISSIGraph 应用程序已通过 GPLv3.0 许可在 Web 网站 SourceForge.NET 上发布,网址为:http://issigraph.sourceforge.net 。在同一 URL 上可以找到 Win32、Linux 和 Mac 的可执行文件和源代码的下载部分。一个关于如何使用主要功能的完整教程托管在 http://issigraph.sourceforge.net/docs.html,您可以在那里找到所有有关使用程序和构建曲面的说明。 

5. 贡献  

如果您有兴趣为ISSIGraph 做出贡献并创建一个真实的 3D 应用程序,只需在 Codeproject 论坛或SourceForge.NET 论坛上给我留言,我会审核您的提案。 以下列出了一系列未来目标: 

  • 添加新曲面(立方体、线、三角形、圆、插值...)  
  • 添加材质    
  • 添加纹理   
  • 添加灯光 
  • 添加阴影 
  • 改进定位系统  
  • 导入/导出 3D 模型
  • 其他想法 

因此,如果您想实现上述任何想法或有任何其他好主意,欢迎您!

6. 1.41 版本中的新功能

  • 能源优化,小于 1%(仅在屏幕需要重绘时渲染)
  • 改进的内部复制/粘贴/剪切
  • 改进为单步循环撤销/重做
  • 修复了 Windows 7 和 8 版本中的闪烁错误
  • 修复了一些恼人的错误
  • 编译到警告级别 4(Visual C++ 和 g++ 的最高级别)

7. 延伸阅读和参考资料

[1] Robert S. Pressman。 "软件工程:实践方法(第五版)"。  McGraw-Hill。 

[2] Donald Hearn 和 Pauline Baker。 "Computer Graphics with OpenGL (第三版)"。Pearson - Prentice Hall。 

[3] Juan M. Cordero Valle 和 José Cortés Parejo。"几何建模"。  Ra-ma。

[4] Bjarne Stroustrup。 "C++ 编程语言(第三版)" 。Addison-Wesley。

[5] Julian Smart 和 Kevin Hock。 "使用 wxWidgets 进行跨平台 GUI 编程"。Prentice Hall。

[6] Shaw Garlan。 "软件架构导论"。World Scientific Publishing Company。

[7] Raphael Malveau 和 Thomas J. Mowbray 博士。 "软件架构训练营"。Prentice Hall。

© . All rights reserved.