Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / Win32

A Customizable Architecture for 3D Graphics Applications

4.88/5 (28 votes)
24 Mar 2015GPL313 min read 58.1K  
Explanation of a consistent 3D graphics software architecture through a basic OpenGL application

1. Introduction

2. Background and Covered Topics

3. The IssiGraph Project 

3.1 Requirements  

3.1.1 Functional requirements 

3.1.2 Non-functional requirements

3.1.3 Use Case 

3.2 Architecture

3.3 High-Level Design

3.3.1 User Interface

3.3.2 Data Management

3.4 Detailed Design 

3.4.1 Class diagram

3.4.1.1 Presentation Subsystem 

3.4.1.2 Base-hierarchy Subsystem

3.4.1.3 Surface Subsystem 

3.4.1.4 Quadrics Subsystem

3.4.1.5 World Subsystem 

3.4.1.6 Tool Subsystem

3.5 Implementation 

3.5.1 Compilers 

3.5.2 Libraries 

3.5.3 Frameworks 

3.5.4 Code Distribution 

3.6 Tests  

3.6.1 White-Box Testing 

3.6.2 Black-Box Testing 

4. Release and Features 

5. Contribute 

6. New Features in 1.41 version

7. Further Reading and References 

1. Introduction   

The present article contains the information and building artefacts to create a base architecture for 3D graphics applications. Its main goal is to be useful as a starting point for the construction of a great variety of CAD applications, reusing the explained architecture as a design pattern for your graphics software. 

2. Background  and Covered Topics  

The intended audience of this article are Software Analysts and Software Engineers with a strong background in C++ programming and software methodologies. Thus, for a good understanding of this article it is desirable that you are proficient in the following topics topics:  

  • UML 2.0.  
  • Software methodologies.  
  • Design patterns. 
  • ANSI/ISO C++  Object Oriented Programming. 
  • GUI programming and design. 
  • Basic maths for 3D graphics. 

The main idea that this article tries to transmit is the concept of a set of classes that facilitate the construction of 3D graphics software in an Object Oriented paradigm independently of the language or frameworks used.

3. The ISSIGraph Project  

The ISSIGraph project is conceived as a base prototype for surface modeller assignment. It has been developed for the Software Engineering and Computer Systems department from the National University of Distance Education (UNED). The latest changes and updates result in the work you can see here. For the design and implementation of the tool I followed a tiny methodology similar to RUP (Rational Unified Process). In the following sections you will be able to observe the main Software Engineering Life Cycle used to code ISSIGraph.

3.1 Requirements  

When I conceived the ISSIGraph application I tried to fulfil to the following functional and non-functional requirements.  

3.1.1  Functional requirements 

The ISSIGraph application should allow the easy drawing of Bezier and NURBS surfaces in a wireframe fashion, as well as any other surfaces like spheres, cones, cylinders, teapots, toroids, etc. In addition, it must be possible to render 3D text. All these objects must be moved, rotated and resized over the scene in an easy and straightforward way.   

The application should support the BMP, JPEG and PNG file format exportation with the possibility of changing the background colour, as well as the XML exportation of in-screen models.  

Like any other custom graphics application, the user should be free to do copy, paste and cut operations, as well as undo/redo actions. Finally the application should allow moving, rotating and zooming the 3D objects across the virtual space outside the initial 1024 x 768 window, by using a a controller panel. 

3.1.2 Non-functional requirements  

In the following list, some of the most important performance and environmental requirements are enumerated: 

  • High performance at the lowest CPU cost. 
  • Algorithms of O(n) maximum complexity. 
  • OpenGL as 3D library. 
  • Cross-platform: Windows, Linux and Mac OS X.
  • Using the wxWidgets 2.9.3 framework.
  • Low memory overhead.
  • Attractive design.
  • Easy to install and use.
  • Secure system.
  • Legible code. 
  • Released as Open Source. 

3.1.3 Use Case   

The use case diagram is useful for the requirement capture needed to implement the ISSIGraph application. On the left of the diagram below is the main actor that interacts with the system; on the right side are the main use cases: 

Image 1

Fig. 1. Use case diagram

3.2 Architecture 

The fundamental architecture of ISSIGraph is based on a three-tier application. As shown below, the bottom-up layer performs user interface management, while the middle layer performs business logic and the lower layer, handles the graphics and hardware libraries. Finally, all these tiers lay on the platform implementation.   

 

Image 2

Fig. 2. Architecture layout

3.3 High-Level Design 

3.3.1 User Interface   

As in [1] the intended goals for the users interface were: 

A) Give the control to user 

  • Define interaction modes so that the user does not have to perform unnecessary actions.
  • Have in mind a flexible interaction.  
  • User interaction must be interruptible and undoable. 
  • Hide technical complexity to user.  
  • Direct interaction with screen objects.  

B) Reduce user memory overload  

  • Reduce short-term memory demand.  
  • Use default values.  
  • Use short-cuts. 
  • The visual format must be a world's metaphor.  
  • Use nested menus.   

C) Build a consistent interface 

  • Allow the user to perform a task in the suitable context. i.e. objects selector.
  • Maintain the consistence across the family of applications.
  • Use mnemonic rules. 

Image 3

Fig. 3. The user interface 

3.3.2 Data management  

In order to implement persistence I didn't use serialization, because this is not suitable for information interchange. To perform persistence with interoperability and information portability I opted to use XML file format with UTF-8 encoding.  XML is a well structured specification that allows you to organize and exchange data for a later use. You can see a XML example to store 3D models in ISSIGraph here.  

3.4 Detailed Design   

3.4.1 Class Diagram

3.4.1.1 Presentation Subsystem

This subsystem is the responsible for managing the user interaction through the wxWidgets user interface framework. The IssiFrame class contains a reference to a IssiGLCanvas which is a suitable context to render OpenGL primitives. This class starts-up and handles OnPaint events. This subsystem interoperates with the World subsystem sending messages to the business domain objects.

Image 4

Fig. 4. Presentation subsystem

 

3.4.1.2 Base-hierarchy Subsystem

This subsystem is the core base class for the rest of objects inherited in the application. The Box abstract class allows you to manage and implement the subsequent inherited class behaviour; but it is overridden in the QuadricBox and VertexBox core base classes.  

 

Image 5

Fig. 5. Base classes 

3.4.1.3 Surface Subsystem 

This is the first inherited subsystem from the Box class. The VertexBox core class allows you to implement 3D math special requirements for NURBS, Beziers and Control Points. 

Image 6

 

Fig. 6. Surface subsystem 

3.4.1.4 Quadrics Subsystem 

As the Surface subsystem, this one allows you to implement basic 3D surfaces like cubes, teapots, spheres, cones and so on. The final inherited classes like Cylinder, Cone, Torus, etc. implements the virtual behaviour defined at the top core classes like QuadricBox and Quadric. Note that the classes OneDimension and TwoDimension implements the facilities to change volume dimensions such as height and width.

Image 7

Fig. 7. Quadrics subsystem 

3.4.1.5 World Subsystem

Finally, the World class which is the receptacle object that receives all the messages from events generated by the wxWidgets framework in the Presentation subsystem. This subsystem implements all the behaviour related to the business logic, that is to say, the whole ISSIGraph application features.   

The Axis class implements the movable coordinate system which inherits from VertexBox abstract class. The Memory class implements a tiny pattern design for the memory operations used by Copy/Paste/Cut and Undo/Redo procedures. 

Image 8

Fig. 8. World subsystem 

3.4.1.6 Tool Subsystem 

This trivial set of classes is a help-system package of needed maths, library specifics and conversions routines. They are grouped as an external tool of static member functions useful for the correctness and the organization of the application.

Image 9

Fig. 9. Tool subsystem 

Image 10

Fig. 10.  Sequence diagram   

  1. The user wants to move a whole NURBS.  He notifies it to the IssiGLCanvas object.   
  2. The IssiGLCanvas object reports to the World object. 
  3. The World object (according to the business logic) reports the NURBS to move. 
  4. The NURBS object up-calls its Surface base.   
  5. The Surface object iterates through all the CtrlPoint objects stored in the list in order to move them. 
  6. Now, the user wants to change the toroid's dimensions so he notifies it to the IssiGLCanvas object.
  7. Again, the IssiGLCanvas object reports the World object. 
  8. The World object performs the action to the Torus object. 
  9. Because the toroid object has two dimensions (innerradius and outerradius) it is notified to the TwoDimension object.    
  10. Now the user wants to move the Axis object.   
  11. Again, the IssiGLCanvas reports to the World object.
  12. The World object (according to the business logic) reports the Axis.
  13. Suddenly, an ONPAINT event happens.
  14. So the ISSIGLCanvas notifies the World object's render method.
  15. The World object calls its NURBS object to process their  control points.
  16. According to this, the NURBS processes all its control points.
  17. Now, the World's render routine has to draw its NURBS.
  18. So, the NURBS iterates to draw all its control points.
  19. Again, the World's render routine has to draw its Torus object,
  20. as well as drawing the selection rectangle (DrawBox),
  21. the selection DrawSelection handler for the NURBS,
  22. and the selection handler for the Torus.  
  23. Finally, the World's render routine draws the Axis (coordinate system).

3.5 Implementation  

3.5.1 Compilers  

The complete application has been developed in C++ using the Visual C++ 2010 Express Edition compiler on Windows XP 32-bit version. Later on, the application has been ported to Linux using (with GNU-GCC 4.9 and finally, the Leopard Mac OS X version has been ported with X-Code GCC 4.0 and GNU Make. 

3.5.2 Libraries  

In order  to perform a suitable 3D graphics output and a state-of-the-art 3D application, I have used the OpenGL libraries for primitive drawing and GLUT for quadrics and text output. As in [2]  I opted to use GLEW libraries for NURBS and Bezier drawing, instead of implementing an algorithm to tessellate them. However, in the Linux and Mac versions I had to use freeglut for GLUT primitives.   

 

3.5.3 Frameworks  

The common framework I used for all the application was the wxWidgets version 2.9.3, because it is a free and stable software for a cross-platform user interface implementation. 

3.5.4 Code Distribution  

The distributed code has the following structure:
 

 

Source file Meaning
main.h User interface main header
main.cpp User interface main implementation
box.h Base subsystem header
box.cpp Base subsystem implementation
surface.h NURBS, Bezier and Control Points  header classes
surface.cpp NURBS, Bezier and Control Points implementation classes
quadric.h Quadrics, volumes and text header classes
quadric.cpp Quadrics, volumes and text implementation classes
textout.h GLUT text routine class header
textout.cpp GLUT text routine class implementation
world.h World subsystem header classes 
world.cpp World subsystem implementation classes
tool.h Tool subsystem header classes
tool.cpp Tool subsystem implementation classes

Tab. 1. Source file directory structure 

3.6 Tests  

According to [1], the dynamics techniques applied to ISSIGraph tests allow the quality assurance of the application.    

3.6.1 White-Box Testing   

This technique tries to examine the program logic based on its internal structure. That is to say, it allows seeing the application internals (which would be a symbolic box). 

Since exhaustive and complete tests are impracticables in the 100% of the cases, I tried to do a Code coverage of all basic paths for the sentences, decisions and conditions, as well as revisions on paper as software metric.    

3.6.2 Black-Box Testing     

With this technique I tried to examine the behaviour of the application based on the function specification to perform. It is called so because it does not matter the application internals but the execution response.

To perform black-box testing I used Limit values analysis, for example using a few number versus a high number of control points and objects. 

In order to demonstrate a good application performance, I designed two black-box test cases (A and B) as useful stress test using the following system equipment: 

  • Mac Book Pro   
  • Intel CPU with Core i5 (four cores) M529 2.40 GHz @ 1.17 GHz
  • 2.17 GB RAM  
  • Windows XP 32-bit operating system 
  • NVidia GeForce GT 330M  

Case A:  

  • 3 Cones
  • 2 Toroids
  • 1 Teapot
  • 1 Icosahedron 
  • 1 Dodecahedron
  • 1 Rhombic dodecahedron
  • 1 Text
  • 1 NURBS
  • 1 Bezier
  • 1 Coordinate system  

Image 11

Fig. 11. A case

The performance and overhead when rotating the whole scene was:
 

Image 12

Fig. 12. System performance in A

 Case B:

  • 2 Teapots
  • 2 NURBS
Image 13

Fig. 13. B case 

 In this case the objects were zoomed 4x, so the performance was:
 

Image 14

 Fig. 14. System performance in B

4. Release and Features    

The ISSIGraph application has been released as GPLv3.0 license through the Web site SourceForge.NET where it can be accessed at the URL: http://issigraph.sourceforge.net . A download section of the executable and sources for Win32, Linux and Mac is available at the same URL. A complete tutorial on how to use the main features is hosted at  http://issigraph.sourceforge.net/docs.html where you may seek all the instructions to play with the program and build surfaces.  

5. Contribute  

If you are interested in contributing and making a real-world 3D application for ISSIGraph, just drop me a letter in either the Codeproject forum or the SourceForge.NET forum and I will check your proposal.  A set of future goals are listed below: 

  • Adding new surfaces (cubes, lines, triangles, circles, interpolations...)  
  • Adding materials    
  • Adding textures   
  • Adding lights 
  • Adding shadows 
  • Improving positioning system  
  • Import/Export 3D models
  • Other ideas 

Therefore, if you would like to implement any of the above ideas or have any other great one, you are welcome!

6. New Features in 1.41 version

  • Energy optimization, less than 1% (only renders when the screen must be repainted)
  • Improved internal copy/paste/cut
  • Improved to one-step-cycled undo/redo
  • Fixed blink bug in Windows 7 and 8 versions
  • Fixed some annoying bugs
  • Compiled at Warning Level 4 (maximum level in Visual C++ and g++)

7. Further Reading and References

[1] Robert S. Pressman.  "Software Engineering: A Practitioner's Approach (fifth edition)".  McGraw-Hill. 

[2] Donald Hearn and Pauline Baker. "Computer Graphics with OpenGL (3rd edition)". Pearson - Prentice Hall.  

[3] Juan M. Cordero Valle and José Cortés Parejo. "Modelado Geométrico".  Ra-ma.

[4] Bjarne Stroustrup. "The C++ programming language (3rd edition)" . Addison-Wesley.

[5] Julian Smart and Kevin Hock. "Cross-platform GUI Programming with wxWidgets". Prentice Hall.

[6] Shaw Garlan. "An introduction to Software Architecture". World Scientific Publishing Company.

[7] Raphael Malveau and Thomas J. Mowbray PhD. "Software Architect Bootcamp". Prentice Hall.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)