Cross-Platform Game Development for C++ Developers, Part V: OGRE 3D

OGRE (Object-Oriented Graphics Rendering Engine) is a scene-oriented, flexible 3D engine written in C++. Designed to quickly and easily produce applications with hardware-accelerated 3D graphics, the class library abstracts all the details of using the underlying system libraries such as Direct3D and OpenGL and provides an interface based on world objects and other intuitive classes. To use OpenGL, OGRE requires a base OpenGL version of 1.2.1 or later, which is quite a modest requirement by today’s standards.

OGRE works with a variety of Windows, Mac OSX, and Linux C++ IDEs, including but not limited to Visual Studio .NET 2003, XCode, GCC 3.3 thru 4.0, Code::Blocks IDE, Dev C++, Cygwin/MinGW, Anjuta, and KDevelop.

OGRE is the brainchild of Steve Streeting, instigator and self-styled “benign dictator of the project. The OGRE team, Streeting with a cadre of a half-dozen developers, insures the consistency and robustness of the design philosophy. Outside developers are encouraged to contribute so long as their code meets the design goals.

The authors are quick to point out that although OGRE is a great graphics library, it is not a standalone game engine; for other features such as sound, networking, AI, collision, physics, and so forth, you need to integrate it with other libraries. However, this ground is well trod and the OGRE FAQ contains many suggestions, such as the Open Dynamics Engine (ODE) for physics/collision support.

At the SIGGRAPH 2005 conference on computer graphics and interactive techniques, OGRE was the tool used to demonstrate techniques in the paper Meshless Deformations Based on Shape Matching.

The OGRE 3D Scene Manager Approach

OGRE does not assume the type of game or demo you want to make. It uses a flexible class hierarchy that allows you to design plug-ins to specialize the scene organization approach you take. (A scene is an abstract representation of what is shown in a virtual world.) This enables you to make any kind of game you want—from flight simulator to first-person shooter to 2.5D combat.

Scenes may consist of static geometry (such as terrain or building interiors), models (such as trees, chairs, or monsters), light sources that illuminate the scene, and cameras that view the scene. Scenes can have quite different types. An interior scene might be made up of hallways and rooms populated by furniture and artwork. An exterior scene might consist of a terrain of rolling hills, trees, grass waving in the breeze, and a blue sky with moving clouds.

OGRE provides a set of scene managers, each of which is customized to best support a certain kind of scene. For example, the Binary Space Partition (BSP) Scene Manager handles Quake-type level maps for a first-person shooter type of scene, and the Terrain Scene Manager provides vertex program-based morphing between Levels of Detail and fast high-resolution terrain rendering, which could be used for a flight simulator. Of course, you can easily transition between any two scene managers to allow a character to move from a realistic outdoor setting into an underground dungeon, for example (see Figure 1).

Figure 1. The view from the lush, animated adventure game Ankh.

Inside the OGRE 3D Feature Set

Before digging into the API, take a quick glance at the major features OGRE 3D offers:

  • Common requirements (such as render state management, hierarchical culling, dealing with transparency, and so on) handled automatically
  • Support for vertex and fragment programs (shaders) including Cg, DirectX9 HLSL, or GLSL, and automatic support for many commonly bound constant parameters (such as worldview matrices, light state information, and object space eye position)
  • Fixed function operations (such as multitexture and multipass blending, texture coordinate generation and modification, independent color, and alpha operations)
  • Multiple pass effects, with pass iteration if required for the closest ‘n’ lights
  • Material LOD support (Materials decrease in cost as the objects using them get further away.)
  • Load textures from PNG, JPEG, TGA, BMP, or DDS files, including unusual formats like 1D textures, volumetric textures, cube maps, and compressed textures (DXT/S3TC)
  • Textures can be provided and updated in realtime by plug-ins; for example, a video feed
  • Import meshes from many software packages: MilkShape 3D, 3D Studio Max, Maya, Blender, and Wings3D
  • Skeletal animation, including blending of multiple animations, variable bone weight skinning, and hardware-accelerated skinning
  • Progressive meshes (LOD)
  • Multiple shadow-rendering techniques, each highly configurable and taking full advantage of any hardware acceleration available
  • Particle systems: emitters, affectors, and renderers customizable through plug-ins or scripting
  • Support for skyboxes, skyplanes, and skydomes—very easy to use
  • Billboarding for sprite graphics
  • Automatically managed transparent objects (rendering order and depth buffer settings all set up for you)

The Basic Visualization Model of OGRE 3D

The Root object is the entry point to the OGRE system. As such, it must be the first object created and the last one destroyed. An easy way to do this is to aggregate it into your application object. The Root object lets you configure the system via showConfigDialog() to detect all rendering system options and pop up a dialog for the user to customize resolution, color depth, and full-screen options on the spot. It is also the mechanism for obtaining pointers to other objects in the system, such as the SceneManager, RenderSystem, and various other resource managers.

The RenderSystem object is actually an abstract class that defines the interface to the underlying 3D API. It sends rendering operations to the API and sets all the various rendering options. This class is abstract because all the implementation is rendering-API-specific: You actually would use D3DRenderSystem for Direct3D and OpenGLRenderSystem for OpenGL. After doing Root::initialize(), the RenderSystem object for the selected rendering API is available via the Root::getRenderSystem() method. However, most applications will go directly through the SceneManager, Material, and other scene-based classes to render objects and adjust settings.

The SceneManager does the brunt of the work from the application’s point of view. It does all of the following:

  • Maintains the contents of the scene that the engine will render
  • Organizes the contents using whatever technique it deems best
  • Creates and manages all the cameras, movable objects (entities), lights, and materials (surface properties of objects)
  • Manages the “world geometry,” all of the static geometry usually used to represent the immovable parts of a scene
  • Sends the scene to the RenderSystem object when it’s time to draw

As you can imagine, most of the interaction with the SceneManager is during scene setup. For example, you pull a particular scene of out a database and call all the methods to create the geometry for each object one by one. Sometimes, you may want to create a FrameListener object to modify the contents of the scene dynamically during the rendering cycle. OGRE picks an appropriate SceneManager based on the criteria you specify to Root::setSceneManager. For example, if you tell it you want large indoor levels, it picks the BSP tree SceneManager.

The ResourceManager class is another abstract class specialized to manage specific resources. Typical OGRE resources include textures, meshes, and maps, which correspond to the TextureManager, MeshManager, and MapManager. These classes automatically manage memory and search in multiple locations, including compressed via addPath() and addArchive() methods, respectively.

More by Author

Must Read