History: Ogre Internals Dissection FAQ
Preview of version: 58
- «
- »
Table of contents
- answers :
- 0.About
- 1. ROOT - THE OBLIGATORY CLASS/ OBJECT.
- 1a. Why do I have to allocate root on heap, and not on stack ?
- 1b. How to create similar class with getSingleton() method ?
- 1b2. I need more than one window for my app, can I create more than one root object for that purpose ?
- 1b3. Can I run Ogre3d without actually initializing root ? What functions I do have at hand then ?
- 1b4. But I have read the tutorial and source SDK , the root is created nowhere !!
- 1c. Ogre::Root::initialise fails — the most common causes.
- 1d. Where is the main rendering loop ? How does it work ( diagram and scheme )
- 1d. Explicit 'delete root' causes application crash.
- 1d2. Explicit 'root->shutdown()' causes application crash.
- 1d3.Ways of properly shouting down the Ogre3d without leaking the resources.
- 1e. Ogre::Root extra parametes
- 1e2. Example Window without borders.
- 1f. root->showConfigDialog displays an empty window.
- 1g. What are Root's important containers I would have to modify through it's methods ? (
- Diagram and Schemes.
- 1g. How the life cycle of handling FrameListeners look like ? ( Diagram or Scheme )
- 2. RESOURCES, MATERIALS, AND RESOURCES' MANAGMENT
- 2a. Do I need to use the Resource, ResouceManagers schemes ?
- 2a2. Can I make my game without this mechanism ?
- 2b. Why does my object display as white (or black) in Ogre?
- 2b2. Why does my resource creation or load fail in strange ways?
- 2b3. What is the Ogre::Resource's typical lifecycle ( diagram or scheme ) ?
- 2b4. What are usual methods of managing this lifecycle ?
- 2b5. Why is OgreCore.zip missing?
- 2b6. Is there any way to iterate through all resources in a ResourceGroup ( for example not only from files)?
- 2c. Why it only service small part of assets' types needed to create game (e.g. no music , sound files , no third party data ).
- 2c2. How do I extend that mechanism for all assets in my game ?
- 2c3. How do I write my own Resource type ?
- 2c4. How do I write my own Resource manager ?
- 3. SCENEMANAGERS AND SCENENODES
- 3a. Is it necessary to use them in my game ?
- 3b. How does it generally work ?
- 3b2. There seems to be very little transformations types, why so ?
- 3b3. What is the order of visiting the SceneNodes tree graph ? Where does it happen in code ?
- 3c. Can I have more than one Entiety to a SceneNode attached ?
- 3d. Can I create cycles in the Ogre3d graph ?
- 3e. Can I prevent from inheriting any property from parent to child ?
- 3e2. I have two nodes which ain't parent/child related yet I would like two of them to share one of the properties.
- 3f. When I attach / detach a node then the Ogre3d seems to have delays. Why is it so ? Can I improve that ?
answers :
0.About
0a. What is OGRE?
OGRE (Object-Oriented Graphics Rendering Engine) is a scene-oriented, flexible 3D engine written in C++ designed to make it easier and more intuitive for developers to produce applications utilising hardware-accelerated 3D graphics. The class library abstracts all the details of using the underlying system libraries like Direct3D and OpenGL and provides an interface based on world objects and other intuitive classes.
0b. What can it do?
Lots of things! See the features page for an up-to-date list of the current features. Also, take a look at the screenshots page to see for yourself the kinds of eye candy OGRE can pump out.
0c. Is OGRE a Game Engine?
No. OGRE can be (and indeed has been) used to make games, but OGRE is deliberately designed to provide just a world-class graphics solution; for other features like sound, networking, AI, collision, physics etc, you will need to integrate it with other libraries, something several frameworks have done, and we have a collision / physics reference integration library as an example in our distribution.
0d. Why it is not ?
Well, one reason is that not everyone who needs a 3D engine wants to make games, so we don’t assume that you do – you can use OGRE for games, simulations, business applications, anything at all. Secondly, even within the games industry, requirements can vary widely; for example a MMORPG will need a very different kind of network library than an FPS, and a flight sim will need a different kind of collision / physics system to fighting game. If OGRE included all these features, we would be enforcing a particular set of libraries on you, with an inbuilt set of assumed requirements, and that’s not good design. Instead, we provide a very integration friendly API and let YOU choose the other libraries, if you want them. Many experienced game developers have expressed their approval of this approach, because there are no inbuilt constraints. It can be more daunting for newer users who just want to build another FPS-style game, but for those people there are a growing number of existing frameworks using OGRE which provide a complete solution using a given combo of libraries; but it’s important to realise that OGRE itself will always remain separate, flexible enough to be incorporated into any of these. The principle is of collaboration and integration with other libraries, rather than assimilation of them, a standard tenet of component-based design.
0e. Why should I consider using OGRE (rather than the other zillion 3D engines out there)?
Many other engines, whilst technically impressive, lack the cohesive design and the consistent documentation to allow them to be used effectively. Many of them have long features lists, but have the feel of a bunch of tech demos lashed together with twine, with no clear vision to hold them together. Like any other software system this becomes their downfall as they become larger. Most other engines are also designed for one particular style of game or demo (e.g. first-person shooters, terrain roamers).
OGRE is different. OGRE is design-led rather than feature-led. Every feature that goes into OGRE is considered thoroughly and slotted into the overall design as elegantly as possible and is always fully documented, meaning that the features which are there always feel part of a cohesive whole. Quality is favored over quantity, because quantity can come later – quality can never be added in retrospect. OGRE uses sound design principles learned, tried and tested many times in commercial-grade software – the object-orientation mentioned in it’s moniker is just one of those approaches – frequent use of design patterns is another. The core development team is kept deliberately small, and all of its members are veteran software engineers with many years of real-world experience. Patches are welcomed from community, but they undergo a strict review for both quality and cohesion with the Ogre philosophy before being accepted.
OGRE does not assume what type of game or demo you want to make. It uses a flexible class hierarchy allowing you to design plugins to specialise the scene organisation approach taken to allow you to make any kind of scene you like. Want to render indoor levels fast? Fine, use the BSP/PVS plugin scene manager which has already been written. Want an outdoor landscape? Again, use another plugin scene manager. The rest of the engine continues to function exactly as before.
So the short answer is – if you favour design quality, flexibility and clear documentation, choose OGRE. You know it makes sense. 😉
0f. Is it really free?
The Ogre source is made available under the MIT License, which basically means you can use it however you like as long as you include the content of our COPYING file somewhere in your application. The source to your application, or your modifications to Ogre do not have to be released (although it would be nice if you did). See the licensing page for full licensing terms.
0g. How do I find out more?
If you want to find out about the principles under which OGRE has been developed and to get a quick overview of the design, go to the OGRE Manual now. You can also read the tutorials to help you get started, and then reference the API documentation online.
The best way to appreciate OGRE is to use it. I recommend using Mercurial to download the latest version since the code is under constant improvement. If you don’t want to use Mercurial, a snapshot is released periodically for download. For both these options, see the downloads page.
If you have any specific questions, just email the Ogre Team using the email address listed on the contact page.
1. ROOT - THE OBLIGATORY CLASS/ OBJECT.
Note : All those classes are Singletons except RenderManager, SceneManager, RenderWindow. TextureManager is an abstract class, whose instance is created with RenderManager.
1a. Why do I have to allocate root on heap, and not on stack ?
That is why I do have to write
Root *root = new Root();
and not just :
Root root = Root();
?
A:
Well, devel sindbad often holds root inside a manager class so Root gets constructed as soon as the manager is. So it actually becomes:
class SomeManager { protected: Ogre::Root mOgreRoot; ... }
You might construct Root like that in your entry point Before the frame loop
is kicked off. When using the RAII technique ( that is what this snippet does )
you must just watch out that mOgreRoot won't be popped off from stack while the
app is running. This is hard to do with the RAII, as with that the function
call frames are deleted in the order opposite to how they were put onto the stack — that
is the 'newest ' call frame first, but when using say threading the things
get more complicated... ( note : This is actually the same consideration as making sure you
don't call 'delete mOgreeRootPointer' during the program's main loop.)
Thus there really isn't a concrete need to manage Root using new/delete, although you can if you want.
1b. How to create similar class with getSingleton() method ?
This pattern is called Singleton :
http://en.wikipedia.org/wiki/Singleton_pattern
Deriving from Ogre::Singleton is merely a matter of doing this:
MyAwesomeClass :: public Ogre::Singleton<MyAwesomeClass> { //code omitted - obviously }; And in the implementation file: template<> MyAwesomeClass* Ogre::Singleton<MyAwesomeClass>::ms_Singleton = 0;
The Ogre3d's Singleton has been written by Scott Bilas, here's his blog entry
discussing similar Singleton variant :
http://scottbilas.com/publications/gem-singleton/ .
1b2. I need more than one window for my app, can I create more than one root object for that purpose ?
Two instances of root is not possible/recommend/supported.
(M)Ogre uses Singletons, that is one instance of the object in the same
application context) e.g. TextureManager, MeshManager and of course
Ogre::Root, creating -> the second created root will "override" the first one.
Ogre supports having multiple windows; just don't use multiple Roots to achieve that purpose.
1b3. Can I run Ogre3d without actually initializing root ? What functions I do have at hand then ?
Yes. It is possible to run Ogre3D without initializing root, but having limited functionality.
The XMLConverter and the MeshUpgrader tools initialize the individual systems that they require to operate. Note that in some cases, you may need to initialize some systems that are indirectly used by the ones you need (like the LogManager).
Because this is very low level, we recommend that if you want to look into this, research the source code (particularly the mentioned tools) and do some experimentation.
1b4. But I have read the tutorial and source SDK , the root is created nowhere !!
Most of the tutorials use the ExampleApplication framework, which does a lot of behind-the-scenes stuff, including the creation of the root.
1c. Ogre::Root::initialise fails — the most common causes.
1d. Where is the main rendering loop ? How does it work ( diagram and scheme )
1d. Explicit 'delete root' causes application crash.
The most possible cause is : your application must have had deleted root
explictly or implicitly before your 'delete root' .
1d2. Explicit 'root->shutdown()' causes application crash.
1d3.Ways of properly shouting down the Ogre3d without leaking the resources.
1e. Ogre::Root extra parametes
1e2. Example Window without borders.
First assign a value of "none" to misc%22Border%22
Next, make sure that when you initialise Ogre, you tell it NOT to create a default window. (pass false as the first param)
Then, create a render window, and assign it to the "window" member variable of your application.
// create some custom attributes for our manually created window Ogre::NameValuePairList misc; misc["border"] = "none"; misc["monitorIndex"] = "0"; //I use two monitors, so I tell Ogre to draw on my main (#1) monitor // Here we tell the system not to create a default rendering window by passing 'false' mWindow = mRoot->initialise(false, "BasicTutorial7 Render Window"); //now we need to create a render window manually //for now, the dimensions are hardcoded to MY desktop size so the window LOOKS full screen mWindow = mRoot->createRenderWindow("BasicTutorial7 Render Window",1680,1050,false, &misc ); //pass our custom attributes in "misc"
1f. root->showConfigDialog displays an empty window.
First you might not have the plugins.cfg file present in your exec's directory . The error message might be quite cryptic though — the last message being some problems with GUI library , and the one about missing plugins.cfg is mysteriously hidden ...
./plugins.cfg not found, automatic plugin loading disabled.
[+]
Creating resource group GUI
Added resource location './/gui' of type 'FileSystem' to resource group 'GUI' with recursive option
Added resource location './/gui/schemas' of type 'FileSystem' to resource group 'GUI' with recursive option
Creating resource group Graphics
Added resource location './/materials/RTShaderLib' of type 'FileSystem' to resource group 'Graphics' with recursive option
Added resource location './/materials/RTShaderLib/materials' of type 'FileSystem' to resource group 'Graphics' with recursive option
Added resource location './/materials/RTShaderLib/GLSL' of type 'FileSystem' to resource group 'Graphics' with recursive option
Added resource location './/materials/RTShaderLib/Cg' of type 'FileSystem' to resource group 'Graphics' with recursive option
Added resource location './/materials/scripts' of type 'FileSystem' to resource group 'Graphics' with recursive option
Added resource location './/materials/textures' of type 'FileSystem' to resource group 'Graphics' with recursive option
Added resource location './/models' of type 'FileSystem' to resource group 'Graphics' with recursive option
Creating resource group Music
Added resource location './/music' of type 'FileSystem' to resource group 'Music' with recursive option
Creating resource group Sound
Added resource location './/sounds' of type 'FileSystem' to resource group 'Sound' with recursive option
Error: Shell widget menu has zero width and/or height
If you have none plugins.cfg create one ; at least should be there :
- Define plugin folder
PluginFolder=/usr/lib/OGRE
and if you have there a file say RenderSystem_GL.so ( or with longer multiply extensions as on Unixes* ) just paste the filename there:
When everythings fine you should see in the Ogre.log ( or any other file you log into ) as well in terminal ( iff called from terminal ) :
16:16:19: Loading library /usr/lib/OGRE/RenderSystem_GL
16:16:19: Installing plugin: GL RenderSystem
16:16:19: OpenGL Rendering Subsystem created.
16:16:19: Plugin successfully installed
1g. What are Root's important containers I would have to modify through it's methods ? (
Diagram and Schemes.
1g. How the life cycle of handling FrameListeners look like ? ( Diagram or Scheme )
2. RESOURCES, MATERIALS, AND RESOURCES' MANAGMENT
2a. Do I need to use the Resource, ResouceManagers schemes ?
2a2. Can I make my game without this mechanism ?
2b. Why does my object display as white (or black) in Ogre?
2b2. Why does my resource creation or load fail in strange ways?
2b3. What is the Ogre::Resource's typical lifecycle ( diagram or scheme ) ?
2b4. What are usual methods of managing this lifecycle ?
See the Legend in the picture above ...
2b5. Why is OgreCore.zip missing?
2b6. Is there any way to iterate through all resources in a ResourceGroup ( for example not only from files)?
Unfortunately resource groups are protected members so you can't get to them directly, and only the file based resources are easily accessed by users (resources like a material file are stored in one container, the actual materials within it or manually created resources with no file are stored in a different container. Only the former can be queried by users via the ResourceGroupManager). Like :
Ogre::StringVectorPtr resInGroup = Ogre::ResourceGroupManager::getSingletonPtr()->listResourceNames("AResourceGroup");
The hard way of filtering out that is : iterate over all resources' managers , over all resources of each of them and call
Ogre::Resource::getGroup()
2c. Why it only service small part of assets' types needed to create game (e.g. no music , sound files , no third party data ).
2c2. How do I extend that mechanism for all assets in my game ?
2c3. How do I write my own Resource type ?
2c4. How do I write my own Resource manager ?
3. SCENEMANAGERS AND SCENENODES
3a. Is it necessary to use them in my game ?
The scene manager is the primary part of ogre that deals with rendering the user's scene. It handles the creation and destruction of most classes (cameras, lights, renderables, etc). While it's possible to access Ogre's lower level render systems directly, that's not really recommended and isn't documented.
SceneNodes are needed because they hold the transform data for objects, are used for visibility culling and are the way that the scene manager knows which objects to render (anything that isn't attached to a scene node isn't part of the scene, so won't be drawn).
Well, mostly. Certain things don't need scene nodes. In Ogre 1.9 and below, cameras, static geometry and lights don't need scene nodes. They are still part of the scene manager though. In Ogre 2.0, things are a little different. Cameras get added to the root scene node automatically. Static geometry is done with static scene nodes and static entities. I think lights work the same though (not sure).
3b. How does it generally work ?
3b2. There seems to be very little transformations types, why so ?
It depends on what you exactly mean by transform types. In the 3D computer graphics special kind of transformations is studied with a special care — Affine_transformation http://en.wikipedia.org/wiki/Affine_transformation , that is most of the "most necessary" operations are derived from it, also from almost two decades the graphical PC hardware is geared toward the fastest processing of that family of operations.
As to Ogre3d: It supports translation, scale and orientation in the transform of a scene node. The only other transform type that other engines might typically support is skew. Ogre doesn't support skew itself, but it can be done inside of a vertex shader. 3 out of 4 isn't really "very little".
3b3. What is the order of visiting the SceneNodes tree graph ? Where does it happen in code ?
if (includeChildren)
{
ChildNodeMap::iterator child, childend;
childend = mChildren.end();
for (child = mChildren.begin(); child != childend; ++child)
{
SceneNode* sceneChild = static_cast(child-second);
sceneChild-_findVisibleObjects(cam, queue, visibleBounds, includeChildren,
displayNodes, onlyShadowCasters);
}
}
3c. Can I have more than one Entiety to a SceneNode attached ?
You can have as many renderable objects of any type attached to one scene node. They will all share the same local origin however, as things like entities have no concept of world transforms, the scene node does that for them.
3d. Can I create cycles in the Ogre3d graph ?
The Ogre scene manager uses a directed acyclic tree.
3e. Can I prevent from inheriting any property from parent to child ?
The node class has setInheritOrientation() and setInheritScale() methods. These let you enable or disable inheriting those two properties from a parent node. There is no direct position equivalent (you can just use a second scene node instead).
3e2. I have two nodes which ain't parent/child related yet I would like two of them to share one of the properties.
If a parent-child relation is no option for you, then you are stuck with handling it yourself by either:
a) Keeping track of all changes of the node you want to follow yourself
b) Using an Ogre::Node::Listener that you can attach to the node you want to track (the "parent") and the once an update event is fired, you update the tracking ("child") node as well:
API: Ogre::Scenenode::setListener()
API: Ogre::Node::Listener::nodeUpated()
3f. When I attach / detach a node then the Ogre3d seems to have delays. Why is it so ? Can I improve that ?
That may depend on the scene manager implementation you're using (i.e. Default vs Octree vs BSP, etc). In some implementations attaching/detaching may be expensive. For this reason SceneNode::setVisible was implemented (which calls MovableObject::setVisible), which as its doxygen documentation states, it is nice for toggling visibility quickly; whereas detaching-reattaching can be used when the node goes out of the scene for long terms.
If you're hierarchy is too vertical and deep (i.e. Node E is child of D, which is child of C, child of B, child of A, child of root), attaching and detaching costs tend to go up. So if you're having performance issues, try flattening your hierarchy.
In Ogre 2.0 the attaching/detaching cost has been greatly reduced; however if you happen to trigger a memory cleanup or a memory pool growth, there can be a significant delay (which can be mitigated by respecting LIFO order of operations and by telling Ogre to allocate a very large pool; respectively).