Read more about this book |
(For more resources on this subject, see here.)
Up until now, the ExampleApplication class has started and initialized Ogre 3D for us; now we are going to do it ourselves.
This time we are working on a blank sheet.
#include "OgreOgre.h"
int main (void)
{
return 0;
}
"plugin.cfg":
Ogre::Root* root = new Ogre::Root("plugins_d.cfg");
if(!root->showConfigDialog())
{
return -1;
}
Ogre::RenderWindow* window = root->initialise(true,"Ogre3D
Beginners Guide");
Ogre::SceneManager* sceneManager = root-
>createSceneManager(Ogre::ST_GENERIC);
Ogre::Camera* camera = sceneManager->createCamera("Camera");
camera->setPosition(Ogre::Vector3(0,0,50));
camera->lookAt(Ogre::Vector3(0,0,0));
camera->setNearClipDistance(5);
Ogre::Viewport* viewport = window->addViewport(camera);
viewport->setBackgroundColour(Ogre::ColourValue(0.0,0.0,0.0));
camera->setAspectRatio(Ogre::Real(viewport->getActualWidth())/
Ogre::Real(viewport->getActualHeight()));
root->startRendering();
We created our first Ogre 3D application without the help of the ExampleApplication. Because we aren't using the ExampleApplication any longer, we had to include Ogre3D.h, which was previously included by ExampleApplication.h. Before we can do anything with Ogre 3D, we need a root instance. The root class is a class that manages the higher levels of Ogre 3D, creates and saves the factories used for creating other objects, loads and unloads the needed plugins, and a lot more. We gave the root instance one parameter: the name of the file that defines which plugins to load. The following is the complete signature of the constructor:
Root(const String & pluginFileName = "plugins.cfg",const String &
configFileName = "ogre.cfg",const String & logFileName = "Ogre.log")
Besides the name for the plugin configuration file, the function also needs the name of the Ogre configuration and the log file. We needed to change the first file name because we are using the debug version of our application and therefore want to load the debug plugins. The default value is plugins.cfg, which is true for the release folder of the Ogre 3D SDK, but our application is running in the debug folder where the filename is plugins_d.cfg.
ogre.cfg contains the settings for starting the Ogre application that we selected in the config dialog. This saves the user from making the same changes every time he/she start our application. With this file Ogre 3D can remember his choices and use them as defaults for the next start. This file is created if it didn't exist, so we don't append an _d to the filename and can use the default; the same is true for the log file.
Using the root instance, we let Ogre 3D show the config dialog to the user in step 3. When the user cancels the dialog or anything goes wrong, we return -1 and with this the application closes. Otherwise, we created a new render window and a new scene manager in step 4. Using the scene manager, we created a camera, and with the camera we created the viewport; then, using the viewport, we calculated the aspect ratio for the camera. After creating all requirements, we tell the root instance to start rendering, so our result would be visible. Following is a diagram showing which object was needed to create the other:
We have now created our first Ogre 3D application, which doesn't need the ExampleApplication. But one important thing is missing: we haven't loaded and rendered a model yet.
We have our application, now let's add a model.
Ogre::ResourceGroupManager::getSingleton().
addResourceLocation("../../Media/packs/Sinbad.zip","Zip");
Ogre::ResourceGroupManager::getSingleton().
initialiseAllResourceGroups();
Ogre::Entity* ent = sceneManager->createEntity("Sinbad.mesh");
sceneManager->getRootSceneNode()->attachObject(ent);
We used the ResourceGroupManager to index the zip archive containing the Sinbad mesh and texture files, and after this was done, we told it to load the data with the createEntity() call in step 3.
Adding a new line of code for each zip archive or folder we want to load is a tedious task and we should try to avoid it. The ExampleApplication used a configuration file called resources.cfg in which each folder or zip archive was listed, and all the content was loaded using this file. Let's replicate this behavior.
Using our previous application, we are now going to parse the resources.cfg.
the resources_d.cfg:
Ogre::ConfigFile cf;
cf.load(«resources_d.cfg»);
Ogre::ConfigFile::SectionIterator sectionIter =
cf.getSectionIterator();
Ogre::String sectionName, typeName, dataname;
while (sectionIter.hasMoreElements())
{
sectionName = sectionIter.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap *settings = sectionIter.
getNext();
Ogre::ConfigFile::SettingsMultiMap::iterator i;
for (i = settings->begin(); i != settings->end(); ++i)
{
typeName = i->first;
dataname = i->second;
Ogre::ResourceGroupManager::getSingleton().
addResourceLocation(dataname, typeName, sectionName);