OGRE: Ogre第一个程序
1. 已經(jīng)安裝了Ogre工程向?qū)?#xff0c;VS2010?新建項(xiàng)目就可以看得OGRE的工程模版了,建立一個(gè)空項(xiàng)目,由于安裝了Orge工程助手,所以免去了麻煩的配置過(guò)程(安裝Orge工程助手步驟可以參考?Ogre1.8.1+VS2010環(huán)境配置):
2.?首先在項(xiàng)目中建立一個(gè)OgreDemo1.c和OgreDemo1.h文件。分別填入如下代碼:
OgreDemo1.h:
#ifndef _TutorialApplication_ #define _TutorialApplication_ #include "ExampleApplication.h" class OgreDemo1 : public ExampleApplication { protected: public: OgreDemo1() { } ~OgreDemo1() { } protected: void createScene(void) { } }; #endifOgreDemo1.c
#include "OgreDemo1.h"#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 #define WIN32_LEAN_AND_MEAN #include "windows.h"INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) #else int main(int argc, char **argv) #endif {// Create application objectOgreDemo1 app;try {app.go();} catch( Exception& e ) { #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 MessageBoxA( NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL); #elsefprintf(stderr, "An exception has occurred: %s ",e.getFullDescription().c_str()); #endif}return 0; }編譯,運(yùn)行,會(huì)出現(xiàn)一個(gè)黑窗口,啥都木有!
3. 往窗口添加一個(gè)對(duì)象
直接在OgreDemo1類的createScene方法中來(lái)實(shí)現(xiàn),
(1):設(shè)置環(huán)境光,首先需要為整個(gè)場(chǎng)景設(shè)置環(huán)境光,這樣才可以看到要顯示的內(nèi)容,通過(guò)調(diào)用setAmbientLight函數(shù)并指定環(huán)境光的顏色就可以做到這些。指定的顏色由紅、綠、藍(lán)三種顏色組成,且每種色數(shù)值范圍在 0 到 1 之間。
//設(shè)置環(huán)境光 mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) )??
(2):創(chuàng)建一個(gè) Entity (物體),通過(guò)調(diào)用 SceneManager 的 createEntity 方法來(lái)創(chuàng)建
//創(chuàng)建一個(gè)物體 Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );變量 mSceneMgr 是當(dāng)前場(chǎng)景管理器的一個(gè)對(duì)象,createEntity 方法的第一個(gè)參數(shù)是為所創(chuàng)建的實(shí)體指定一個(gè)唯一的標(biāo)識(shí),第二個(gè)參數(shù) "robot.mesh" 指明要使用的網(wǎng)格實(shí)體,"robot.mesh" 網(wǎng)格實(shí)體在 ExampleApplication 類中被裝載。這樣,就已經(jīng)創(chuàng)建了一個(gè)實(shí)體。
(3):還需要?jiǎng)?chuàng)建一個(gè)場(chǎng)景節(jié)點(diǎn)來(lái)與它綁定在一起。既然每個(gè)場(chǎng)景管理器都有一個(gè)根節(jié)點(diǎn),那我們就在根節(jié)點(diǎn)下創(chuàng)建一個(gè)場(chǎng)景節(jié)點(diǎn)。
//創(chuàng)建該物體對(duì)應(yīng)的場(chǎng)景節(jié)點(diǎn) SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );?首先調(diào)用場(chǎng)景管理器的 getRootSceneNode 方法來(lái)獲取根節(jié)點(diǎn),再使用根節(jié)點(diǎn)的 createChildSceneNode 方法創(chuàng)建一個(gè)名為 "RobotNode" 的場(chǎng)景節(jié)點(diǎn)。與實(shí)體一樣,場(chǎng)景節(jié)點(diǎn)的名字也是唯一的。
(4):最后,將實(shí)體與場(chǎng)景節(jié)點(diǎn)綁定在一起,這樣機(jī)器人(Robot)就會(huì)在指定的位置被渲染:
//將該物體和場(chǎng)景節(jié)點(diǎn)關(guān)聯(lián)起來(lái) node1->attachObject( ent1 );ok,現(xiàn)在編譯運(yùn)行你的程序,就可以看到我們偉大的機(jī)器人界面了。?
例子很簡(jiǎn)單,代碼頁(yè)不多,就4行。我們還是一步一步來(lái)分析吧。
首先我們上一個(gè)項(xiàng)目中的OgreDemo1類繼承自ExampleApplication類,我們之所以什么都沒(méi)有做就能創(chuàng)建一個(gè)窗口,就是因?yàn)镋xampleApplication為我們實(shí)現(xiàn)了。
首先我們打開(kāi)ExampleApplication類,可以看到包含了如下幾個(gè)成員變量(加入少許注釋)
//ogre的程序"根"任何ogre程序都會(huì)有改對(duì)象 Root *mRoot; //攝像機(jī)鏡頭 Camera* mCamera; //場(chǎng)景管理器 SceneManager* mSceneMgr; //對(duì)于每一幀進(jìn)行處理的類 ExampleFrameListener* mFrameListener; //渲染窗口 RenderWindow* mWindow; //資源文件的路徑字符串 Ogre::String mResourcePath;這里的ExampleFrameListener類,如果你暫時(shí)還不清楚是做什么的,不要緊,后面我們慢慢介紹。
?
知道了這些成員變量,我們?cè)诜祷豋greDemo1.c文件中看看入口函數(shù)WinMain中是如何書(shū)寫(xiě)的呢?很簡(jiǎn)單就一句話:
app.go();先將源代碼貼出來(lái),加了詳細(xì)注釋:
ExampleApplication.h
/* ----------------------------------------------------------------------------- This source file is part of OGRE (Object-oriented Graphics Rendering Engine) For the latest info, see http://www.ogre3d.org/Copyright (c) 2000-2012 Torus Knot Software Ltd Also see acknowledgements in Readme.htmlYou may use this sample code for anything you like, it is not covered by the same license as the rest of the engine. ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- Filename: ExampleApplication.h Description: Base class for all the OGRE examples ----------------------------------------------------------------------------- */#ifndef __ExampleApplication_H__ #define __ExampleApplication_H__#include "Ogre.h" #include "OgreConfigFile.h" #include "ExampleFrameListener.h" // Static plugins declaration section // Note that every entry in here adds an extra header / library dependency #ifdef OGRE_STATIC_LIB # define OGRE_STATIC_GL # if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 # define OGRE_STATIC_Direct3D9// dx11 will only work on vista, so be careful about statically linking # if OGRE_USE_D3D11 # define OGRE_STATIC_Direct3D11 # endif # endif # define OGRE_STATIC_BSPSceneManager # define OGRE_STATIC_ParticleFX # define OGRE_STATIC_CgProgramManager # ifdef OGRE_USE_PCZ # define OGRE_STATIC_PCZSceneManager # define OGRE_STATIC_OctreeZone # else # define OGRE_STATIC_OctreeSceneManager # endif # if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS # undef OGRE_STATIC_CgProgramManager # undef OGRE_STATIC_GL # define OGRE_STATIC_GLES 1 # ifdef __OBJC__ # import <UIKit/UIKit.h> # endif # endif # include "OgreStaticPluginLoader.h" #endif#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS # include "macUtils.h" #endif#ifdef USE_RTSHADER_SYSTEM/** This class simply demonstrates basic usage of the CRTShader system. It sub class the material manager listener class and when a target scheme callback is invoked with the shader generator scheme it tries to create an equvialent shader based technique based on the default technique of the given material. */ class ShaderGeneratorTechniqueResolverListener : public MaterialManager::Listener { public:ShaderGeneratorTechniqueResolverListener(RTShader::ShaderGenerator* pShaderGenerator){mShaderGenerator = pShaderGenerator;}virtual Technique* handleSchemeNotFound(unsigned short schemeIndex, const String& schemeName, Material* originalMaterial, unsigned short lodIndex, const Renderable* rend){ // Case this is the default shader generator scheme.if (schemeName == RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME){MaterialRegisterIterator itFind = mRegisteredMaterials.find(originalMaterial);bool techniqueCreated = false;// This material was not registered before.if (itFind == mRegisteredMaterials.end()){techniqueCreated = mShaderGenerator->createShaderBasedTechnique(originalMaterial->getName(), MaterialManager::DEFAULT_SCHEME_NAME, schemeName); }mRegisteredMaterials[originalMaterial] = techniqueCreated;}return NULL;}protected:typedef std::map<Material*, bool> MaterialRegisterMap;typedef MaterialRegisterMap::iterator MaterialRegisterIterator;protected:MaterialRegisterMap mRegisteredMaterials; // Registered material map.RTShader::ShaderGenerator* mShaderGenerator; // The shader generator instance. }; #endifusing namespace Ogre;/** Base class which manages the standard startup of an Ogre application.Designed to be subclassed for specific examples if required. */ class ExampleApplication { public:/// Standard constructorExampleApplication(){mFrameListener = 0;mRoot = 0;// Provide a nice cross platform solution for locating the configuration files// On windows files are searched for in the current working directory, on OS X however// you must provide the full path, the helper function macBundlePath does this for us. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLEmResourcePath = macBundlePath() + "/Contents/Resources/";mConfigPath = mResourcePath; #elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOSmResourcePath = macBundlePath() + "/";mConfigPath = mResourcePath; #elsemResourcePath = "";mConfigPath = mResourcePath; #endif#ifdef USE_RTSHADER_SYSTEMmShaderGenerator = NULL; mMaterialMgrListener = NULL; #endif}/// Standard destructorvirtual ~ExampleApplication(){if (mFrameListener)delete mFrameListener;if (mRoot)OGRE_DELETE mRoot;#ifdef OGRE_STATIC_LIBmStaticPluginLoader.unload(); #endif}/// Start the example 程序入口;virtual void go(void){//進(jìn)行初始化工作;if (!setup())return;//開(kāi)始渲染;mRoot->startRendering();// clean up//清理屏幕;destroyScene(); #ifdef USE_RTSHADER_SYSTEM// Finalize shader generator.finalizeShaderGenerator(); #endif}protected://ogre程序的root,任何ogre程序都有該對(duì)象;Root *mRoot; #ifdef OGRE_STATIC_LIBStaticPluginLoader mStaticPluginLoader; #endif//攝像機(jī)鏡頭;Camera* mCamera;//場(chǎng)景管理器;SceneManager* mSceneMgr;//對(duì)每一幀進(jìn)行處理的類;ExampleFrameListener* mFrameListener;//渲染窗口;RenderWindow* mWindow;//資源文件的路徑字符串;Ogre::String mResourcePath;Ogre::String mConfigPath; #ifdef USE_RTSHADER_SYSTEMRTShader::ShaderGenerator* mShaderGenerator; // The Shader generator instance.ShaderGeneratorTechniqueResolverListener* mMaterialMgrListener; // Material manager listener. #endif// These internal methods package up the stages in the startup process/** Sets up the application - returns false if the user chooses to abandon configuration. *///初始化應(yīng)用程序;virtual bool setup(void){String pluginsPath;// only use plugins.cfg if not static #ifndef OGRE_STATIC_LIB #if OGRE_DEBUG_MODEpluginsPath = mResourcePath + "plugins_d.cfg"; #elsepluginsPath = mResourcePath + "plugins.cfg"; #endif #endif//構(gòu)建Root對(duì)象;mRoot = OGRE_NEW Root(pluginsPath, mConfigPath + "ogre.cfg", mResourcePath + "Ogre.log"); #ifdef OGRE_STATIC_LIBmStaticPluginLoader.load(); #endif//配置資源文件相關(guān); setupResources();//配置,主要用于初始化渲染窗口;bool carryOn = configure();if (!carryOn) return false;//創(chuàng)建場(chǎng)景管理器;chooseSceneManager();//創(chuàng)建攝像機(jī);createCamera();//創(chuàng)建視口;createViewports(); #ifdef USE_RTSHADER_SYSTEM// Initialize shader generator.carryOn = initializeShaderGenerator(mSceneMgr);if (!carryOn) return false; #endif// Set default mipmap level (NB some APIs ignore this)TextureManager::getSingleton().setDefaultNumMipmaps(5);// Create any resource listeners (for loading screens)//創(chuàng)建資源監(jiān)聽(tīng);createResourceListener();// Load resources//裝載資源;loadResources();// Create the scene//創(chuàng)建屏幕,必須重寫(xiě),也就是我們OgreDemo1類中(我們現(xiàn)實(shí)模型需要實(shí)現(xiàn)的);createScene();//創(chuàng)建幀監(jiān)聽(tīng);createFrameListener();return true;} #ifdef USE_RTSHADER_SYSTEMvirtual bool initializeShaderGenerator(SceneManager* sceneMgr){ if (RTShader::ShaderGenerator::initialize()){mShaderGenerator = RTShader::ShaderGenerator::getSingletonPtr();// Set the scene manager.mShaderGenerator->addSceneManager(sceneMgr);// Setup core libraries and shader cache path.ResourceGroupManager::LocationList resLocationsList = ResourceGroupManager::getSingleton().getResourceLocationList("Popular");ResourceGroupManager::LocationList::iterator it = resLocationsList.begin();ResourceGroupManager::LocationList::iterator itEnd = resLocationsList.end();String shaderCoreLibsPath;String shaderCachePath;// Default cache path is current directory;shaderCachePath = "./";// Try to find the location of the core shader lib functions and use it// as shader cache path as well - this will reduce the number of generated files// when running from different directories.for (; it != itEnd; ++it){if ((*it)->archive->getName().find("RTShaderLib") != String::npos){shaderCoreLibsPath = (*it)->archive->getName() + "/";shaderCachePath = shaderCoreLibsPath;break;}}// Core shader libs not found -> shader generating will fail.if (shaderCoreLibsPath.empty()) return false; // Add resource location for the core shader libs. ResourceGroupManager::getSingleton().addResourceLocation(shaderCoreLibsPath , "FileSystem");// Set shader cache path.mShaderGenerator->setShaderCachePath(shaderCachePath); // Create and register the material manager listener.mMaterialMgrListener = new ShaderGeneratorTechniqueResolverListener(mShaderGenerator); MaterialManager::getSingleton().addListener(mMaterialMgrListener);}return true;}virtual void finalizeShaderGenerator(){// Unregister the material manager listener.if (mMaterialMgrListener != NULL){ MaterialManager::getSingleton().removeListener(mMaterialMgrListener);delete mMaterialMgrListener;mMaterialMgrListener = NULL;}// Finalize CRTShader system.if (mShaderGenerator != NULL){RTShader::ShaderGenerator::finalize();mShaderGenerator = NULL;}} #endif/** Configures the application - returns false if the user chooses to abandon configuration. *//** 是否配置完成,完成則初始化系統(tǒng) */ virtual bool configure(void){// Show the configuration dialog and initialise the system// You can skip this and use root.restoreConfig() to load configuration// settings if you were sure there are valid ones saved in ogre.cfg//判斷是否進(jìn)入(即運(yùn)行過(guò)了配置窗口,進(jìn)入demo窗口);if(mRoot->showConfigDialog()){// If returned true, user clicked OK so initialise// Here we choose to let the system create a default rendering window by passing 'true'//初始化系統(tǒng),得到一個(gè)渲染窗口對(duì)象;mWindow = mRoot->initialise(true);return true;}else{return false;}}virtual void chooseSceneManager(void){// Create the SceneManager, in this case a generic one// 創(chuàng)建一個(gè)場(chǎng)景管理器(場(chǎng)景類型,窗口標(biāo)題) ;mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "ExampleSMInstance");}virtual void createCamera(void){// Create the camera// 創(chuàng)建一個(gè)攝像機(jī) ;mCamera = mSceneMgr->createCamera("PlayerCam");// Position it at 500 in Z direction// 設(shè)置攝像機(jī)的位置;mCamera->setPosition(Vector3(0,0,500));// Look back along -Z// 設(shè)置觀察點(diǎn);mCamera->lookAt(Vector3(0,0,-300));// 設(shè)置最近裁剪距離,如果超出則不顯示;mCamera->setNearClipDistance(5);//同樣還有設(shè)置最遠(yuǎn)裁剪距離 ;//mCamera->setFarClipDistance(1000); }virtual void createFrameListener(void){//實(shí)例化幀監(jiān)聽(tīng),(渲染窗口,攝像機(jī)); #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOSmFrameListener= new ExampleFrameListener(mWindow, mCamera, true, true, true); #elsemFrameListener= new ExampleFrameListener(mWindow, mCamera); #endif//設(shè)置是否顯示調(diào)試信息(比如:fps...) ;mFrameListener->showDebugOverlay(true);//添加幀監(jiān)聽(tīng)到root中;mRoot->addFrameListener(mFrameListener);}//創(chuàng)建屏幕;virtual void createScene(void) = 0; // pure virtual - this has to be overridden//清屏;virtual void destroyScene(void){} // Optional to override this/* 創(chuàng)建視口并初始化 */ virtual void createViewports(void){// Create one viewport, entire window// 創(chuàng)建一個(gè)“視口” ;Viewport* vp = mWindow->addViewport(mCamera);//設(shè)置背景顏色 ;vp->setBackgroundColour(ColourValue(0,0,0));// Alter the camera aspect ratio to match the viewport//設(shè)置屏幕的長(zhǎng)寬比(視口的寬度和高度比,目前的寬屏電腦);mCamera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));}/// Method which will define the source of resources (other than current folder)/// 初始化資源,比如:模型、貼圖等資源;virtual void setupResources(void){// Load resource paths from config fileConfigFile cf;//讀取配置文件 ; #if OGRE_DEBUG_MODEcf.load(mResourcePath + "resources_d.cfg"); #elsecf.load(mResourcePath + "resources.cfg"); #endif// Go through all sections & settings in the fileConfigFile::SectionIterator seci = cf.getSectionIterator();String secName, typeName, archName;while (seci.hasMoreElements()){secName = seci.peekNextKey();ConfigFile::SettingsMultiMap *settings = seci.getNext();ConfigFile::SettingsMultiMap::iterator i;for (i = settings->begin(); i != settings->end(); ++i){//取得并添加資源文件;typeName = i->first;archName = i->second; #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE || OGRE_PLATFORM == OGRE_PLATFORM_APPLE_IOS// OS X does not set the working directory relative to the app,// In order to make things portable on OS X we need to provide// the loading with it's own bundle path locationif (!StringUtil::startsWith(archName, "/", false)) // only adjust relative dirsarchName = String(macBundlePath() + "/" + archName); #endifResourceGroupManager::getSingleton().addResourceLocation(archName, typeName, secName);}}}/// Optional override method where you can create resource listeners (e.g. for loading screens)//創(chuàng)建資源監(jiān)聽(tīng),比如(正在裝載資源,請(qǐng)稍等界面);virtual void createResourceListener(void){}/// Optional override method where you can perform resource group loading/// Must at least do ResourceGroupManager::getSingleton().initialiseAllResourceGroups();//裝載資源;virtual void loadResources(void){// Initialise, parse scripts etcResourceGroupManager::getSingleton().initialiseAllResourceGroups();}};#endifExampleFrameListener.h
?
首先,我們要分析的就是Root類,使用Ogre的程序所需要作的第一件事情就是實(shí)例化一個(gè)Root對(duì)象。如果沒(méi)有這個(gè)對(duì)象,你就無(wú)法調(diào)用(除了日志管理以外)的任何一個(gè)功能。Root類的構(gòu)造函數(shù)接受一些符串對(duì)象的參數(shù),這些字符代表著不同作用的文件名稱。
Root * root = new Root(); Root * root = new Root("plugins.cfg"); Root * root = new Root("plugins.cfg", "ogre.cfg"); Root * root = new Root("plugins.cfg", "ogre.cfg", "ogre.log"); Root * root = new Root("", "");上面列出了一些不同的方法來(lái)創(chuàng)建Root實(shí)例,這里面任何的方法都能單獨(dú)的正確執(zhí)行。參數(shù)也是系統(tǒng)所默認(rèn)的值(“plugins.cfg”, “ogre.cfg”, “ogre.log”——當(dāng)你沒(méi)有填寫(xiě)參數(shù)的時(shí)候,系統(tǒng)就認(rèn)為采用了默認(rèn)的這些值)。?
plugins.cfg:插件,Ogre中所謂的插件就是符合Ogre插件接口的代碼模塊,比如場(chǎng)景管理(SceneManager)插件和渲染系統(tǒng)(RenderSystem)插件等。在啟動(dòng)的Ogre時(shí)候,他會(huì)載入plugins.cfg配置文件來(lái)查看有哪些插件可以被使用。下面是一個(gè)plugins.cfg文件例子
# Defines plugins to load# Define plugin folder PluginFolder=.# Define plugins Plugin=RenderSystem_Direct3D9_d Plugin=RenderSystem_GL_d Plugin=Plugin_ParticleFX_d Plugin=Plugin_BSPSceneManager_d Plugin=Plugin_CgProgramManager_d Plugin=Plugin_PCZSceneManager_d.dll Plugin=Plugin_OctreeZone_d.dll Plugin=Plugin_OctreeSceneManager_d?
其中PluginFolder用于定義這些插件存在的位置(路徑),??這里使用“.”,表示需要在“\”或者“/”(即根目錄)。在某些平臺(tái)上可以不使用“.”直接使用""(空白),ogre照樣會(huì)在“\”或者“/”中去找。
而Plugin則說(shuō)明了有哪些插件可以使用,但是需要注意,這些插件都沒(méi)有后綴名。
這里需要注意:在“=”兩邊不能加入空格或者?Tab字符。
?
ogre.cfg則是一個(gè)屬性配置文件,主要保存用戶自定義的一些屬性,即下圖所示的界面的一些屬性。
文件如下:
相信這里就不用多解釋,大家都明白了。
?
4. Reference:
http://yarin.iteye.com/blog/561474
http://yarin.iteye.com/blog/561477
http://blog.163.com/cp7618@yeah/blog/static/70234777201141143014386/
http://blog.csdn.net/yangtrees/article/details/8765490
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的OGRE: Ogre第一个程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2020年9月程序员工资最新统计
- 下一篇: 如何顺心地使用github搜索自己想要的