原文地址:http://www.it165.net/pro/html/201403/10144.html
本文介绍 OGRE 3D 1.9 程序的启动过程,即从程序启动到3D图形呈现,背后有哪些OGRE相关的代码被执行。会涉及的OGRE类包括:
Root RenderSystem RenderWindow ResourceGroupManager LogManager Viewport SceneManager Camera SceneNode Entity Light建议在阅读本文时参考OGRE API Reference,OGRE官方给的API Reference没有类的协作图,可以自己用Doxygen生成API文档,见:Bullet的学习资源(用Doxygen生成API文档)。
关于如何安装OGRE和如何配置一个可以运行的OGRE HelloWorld程序见:OGRE 1.9 的第一个程序(OGRE HelloWorld程序)。
本节所有代码如下,可以先迅速浏览,然后看后面详细解释,后面将用“启动代码”来指代这段代码:
#include<OgreRoot.h>
#include<OgreRenderSystem.h>
#include<OgreRenderWindow.h>
#include<OgreConfigFile.h>
#include<OgreResourceGroupManager.h>
#include<OgreLogManager.h>
#include<OgreViewport.h>
#include<OgreSceneManager.h>
#include<OgreCamera.h>
#include<OgreLight.h>
#include<OgreEntity.h>
int main(int argc, char *argv[])
{
Ogre::Root* mRoot;
Ogre::RenderWindow* mWindow;
Ogre::SceneManager* mSceneMgr;
Ogre::Camera* mCamera;
// 创建Root,在调用OGRE任何功能之前必须已经创建了Root
mRoot = new Ogre::Root("plugins.cfg","ogre.cfg","Ogre.log");
// 设定 RenderSystem
Ogre::RenderSystem *rs =
mRoot->getRenderSystemByName("OpenGL Rendering Subsystem");
mRoot->setRenderSystem(rs);
rs->setConfigOption("Full Screen", "No");
rs->setConfigOption("Video Mode", "800x600 @ 32-bit colour");
// 另一种方法是: if(!mRoot->showConfigDialog()) return false;
// 初始化 RenderSystem
mRoot->initialise(false);
// 创建 RenderWindow
int hWnd = 0;
Ogre::NameValuePairList misc;
misc["externalWindowHandle"] = Ogre::StringConverter::toString((int)hWnd);
mWindow = mRoot->createRenderWindow("Win Ogre", 800, 600, false, &misc);
// 上2步的另一种实现是: mWindow = mRoot->initialise(true, "Win Ogre");
// 创建SceneManager,将渲染目标绑定到RenderWindow
mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
// Create one camera
mCamera = mSceneMgr->createCamera("PlayerCam");
mCamera->setNearClipDistance(5);
// Create one viewport, entire window
Ogre::Viewport* vp = mWindow->addViewport(mCamera);
vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
// Alter the camera aspect ratio to match the viewport
mCamera->setAspectRatio(
Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));
// 加载资源,该歩不能早于RenderSystem的初始化和RenderWindow的创建
// 如果使用OverlaySystem,该歩也不能早于OverlaySystem的创建
Ogre::ConfigFile cf; cf.load("resources.cfg");
Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
Ogre::String secName, typeName, archName;
while( seci.hasMoreElements() ){
secName = seci.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
Ogre::ConfigFile::SettingsMultiMap::iterator i;
for( i=settings->begin(); i!=settings->end(); ++i ){
typeName = i->first;
archName = i->second;
Ogre::ResourceGroupManager::getSingleton().
addResourceLocation(archName, typeName, secName);
}
}
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
// 构造及设置场景
mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
mSceneMgr->setAmbientLight(Ogre::ColourValue(0.2f, 0.2f, 0.2f));
Ogre::Entity* entNinja = mSceneMgr->createEntity("entNinja", "ninja.mesh");
Ogre::SceneNode* nodeNinja = mSceneMgr->createSceneNode("nodeNinja");
mSceneMgr->getRootSceneNode()->addChild(nodeNinja);
nodeNinja->attachObject(entNinja);
Ogre::Entity* entSphere = mSceneMgr->createEntity("entSphere", "sphere.mesh");
Ogre::SceneNode* nodeSphere = mSceneMgr->createSceneNode("nodeSphere");
mSceneMgr->getRootSceneNode()->addChild(nodeSphere);
nodeSphere->attachObject(entSphere);
nodeNinja->setPosition(-50,-100,0);
nodeSphere->translate(50,0,100);
Ogre::Light* pointLight1 = mSceneMgr->createLight("pointLight1");
pointLight1->setType(Ogre::Light::LT_POINT);
pointLight1->setDiffuseColour(Ogre::ColourValue::White);
pointLight1->setSpecularColour(Ogre::ColourValue::White);
pointLight1->setPosition(-400,200,-200);
mCamera->setPosition(Ogre::Vector3(0,0,-250));
mCamera->lookAt(Ogre::Vector3(0,0,0));
// 渲染循环
Ogre::LogManager::getSingleton().logMessage(">>Rendering");
mRoot->startRendering();
// 释放资源,目前只需释放Root
delete mRoot;
return 0;
}