ogre研究之第一个程序
来源:互联网 发布:淘宝超级会员 iphone 编辑:程序博客网 时间:2024/04/27 17:03
这里我们主要是实现在程序中装载一个简单的模型并显示出来。
首先看一下效果吧,(模型就是ogre例子中的robot.mesh),如下:
例子很简单,代码页不多,就4行。我们还是一步一步来分析吧。
首先我们上一个项目中的OgreDemo1类继承自ExampleApplication类,我们之所以什么都没有做就能创建一个窗口,就是因为ExampleApplication为我们实现了。
首先我们打开ExampleApplication类,可以看到包含了如下几个成员变量(下乳了少许注释)
- //ogre的程序"根"任何ogre程序都会有改对象
- Root *mRoot;
- //摄像机镜头
- Camera* mCamera;
- //场景管理器
- SceneManager* mSceneMgr;
- //对于每一帧进行处理的类
- ExampleFrameListener* mFrameListener;
- //渲染窗口
- RenderWindow* mWindow;
- //资源文件的路径字符串
- Ogre::String mResourcePath;
这里的ExampleFrameListener类,如果你暂时还不清楚是做什么的,不要紧,后面我们慢慢介绍。
知道了这些成员变量,我们在返回OgreDemo1.c文件中看看入口函数WinMain中是如何书写的呢?很简单就一句话:
- app.go();
先将源代码贴出来,加了详细注意:
ExampleApplication.h
- #ifndef __ExampleApplication_H__
- #define __ExampleApplication_H__
- #include "Ogre.h"
- #include "OgreConfigFile.h"
- #include "ExampleFrameListener.h"
- #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
- #include <CoreFoundation/CoreFoundation.h>
- std::string macBundlePath()
- {
- char path[1024];
- CFBundleRef mainBundle = CFBundleGetMainBundle();
- assert(mainBundle);
- CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
- assert(mainBundleURL);
- CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);
- assert(cfStringRef);
- CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII);
- CFRelease(mainBundleURL);
- CFRelease(cfStringRef);
- return std::string(path);
- }
- #endif
- using 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:
- ExampleApplication()
- {
- mFrameListener = 0;
- mRoot = 0;
- #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
- mResourcePath = macBundlePath() + "/Contents/Resources/";
- #else
- mResourcePath = "";
- #endif
- }
- /// Standard destructor
- virtual ~ExampleApplication()
- {
- if (mFrameListener)
- delete mFrameListener;
- if (mRoot)
- OGRE_DELETE mRoot;
- }
- /// 程序的入口
- virtual void go(void)
- {
- //进行初始化工作
- if (!setup())
- return;
- //开始渲染
- mRoot->startRendering();
- // 清理屏幕
- destroyScene();
- }
- protected:
- //ogre的程序"根"任何ogre程序都会有改对象
- Root *mRoot;
- //摄像机镜头
- Camera* mCamera;
- //场景管理器
- SceneManager* mSceneMgr;
- //对于每一帧进行处理的类
- ExampleFrameListener* mFrameListener;
- //渲染窗口
- RenderWindow* mWindow;
- //资源文件的路径字符串
- Ogre::String mResourcePath;
- //初始化应用程序
- virtual bool setup(void)
- {
- String pluginsPath;
- #ifndef OGRE_STATIC_LIB
- pluginsPath = mResourcePath + "plugins.cfg";
- #endif
- //构建Root对象
- mRoot = OGRE_NEW Root(pluginsPath,
- mResourcePath + "ogre.cfg", mResourcePath + "Ogre.log");
- //配置资源文件相关
- setupResources();
- //配置,主要用于初始化渲染窗口
- bool carryOn = configure();
- if (!carryOn) return false;
- //创建场景管理器
- chooseSceneManager();
- //创建摄像机
- createCamera();
- //创建视口
- createViewports();
- TextureManager::getSingleton().setDefaultNumMipmaps(5);
- //创建资源监听
- createResourceListener();
- //床在资源
- loadResources();
- //创建屏幕,必须重写,也就是我们OgreDemo1类中(我们现实模型需要实现的)
- createScene();
- //创建帧监听
- createFrameListener();
- return true;
- }
- /** 是否配置完成,完成则初始化系统 */
- virtual bool configure(void)
- {
- //判断是否进入(即运行过了配置窗口,进入demo窗口)
- if(mRoot->showConfigDialog())
- {
- //初始化系统,得到一个渲染窗口对象
- mWindow = mRoot->initialise(true);
- return true;
- }
- else
- {
- return false;
- }
- }
- virtual void chooseSceneManager(void)
- {
- // 创建一个场景管理器(场景类型,窗口标题)
- mSceneMgr = mRoot->createSceneManager(ST_GENERIC, "ExampleSMInstance");
- }
- virtual void createCamera(void)
- {
- // 创建一个摄像机
- mCamera = mSceneMgr->createCamera("PlayerCam");
- // 设置摄像机的位置
- mCamera->setPosition(Vector3(0,0,500));
- // 设置观察点
- mCamera->lookAt(Vector3(0,0,-300));
- // 设置最近裁剪距离,如果超出则不显示
- mCamera->setNearClipDistance(5);
- //同样还有设置最远裁剪距离
- //mCamera->setFarClipDistance(1000);
- }
- //创建帧监听
- virtual void createFrameListener(void)
- {
- //实例化帧监听,(渲染窗口,摄像机)
- mFrameListener= new ExampleFrameListener(mWindow, mCamera);
- //设置是否显示调试信息(比如:fps...)
- mFrameListener->showDebugOverlay(true);
- //添加帧监听到root中
- mRoot->addFrameListener(mFrameListener);
- }
- //创建屏幕
- virtual void createScene(void) = 0;
- //清屏
- virtual void destroyScene(void){}
- /* 创建视口并初始化 */
- virtual void createViewports(void)
- {
- // 创建一个“视口”
- Viewport* vp = mWindow->addViewport(mCamera);
- //设置背景颜色
- vp->setBackgroundColour(ColourValue(0,0,0));
- //设置屏幕的长宽比(视口的宽度和高度比,目前的宽屏电脑)
- mCamera->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
- }
- /// 初始化资源,比如:模型、贴图等资源
- virtual void setupResources(void)
- {
- ConfigFile cf;
- //读取配置文件
- cf.load(mResourcePath + "resources.cfg");
- ConfigFile::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
- ResourceGroupManager::getSingleton().addResourceLocation(
- String(macBundlePath() + "/" + archName), typeName, secName);
- #else
- ResourceGroupManager::getSingleton().addResourceLocation(
- archName, typeName, secName);
- #endif
- }
- }
- }
- //创建资源监听,比如(正在装载资源,请稍等界面)
- virtual void createResourceListener(void)
- {
- }
- //装载资源
- virtual void loadResources(void)
- {
- ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
- }
- };
- #endif
ExampleFrameListener.h
- #ifndef __ExampleFrameListener_H__
- #define __ExampleFrameListener_H__
- #include "Ogre.h"
- #include "OgreStringConverter.h"
- #include "OgreException.h"
- #define OIS_DYNAMIC_LIB
- #include <OIS/OIS.h>
- using namespace Ogre;
- class ExampleFrameListener: public FrameListener, public WindowEventListener
- {
- protected:
- virtual void updateStats(void)
- {
- static String currFps = "Current FPS: ";
- static String avgFps = "Average FPS: ";
- static String bestFps = "Best FPS: ";
- static String worstFps = "Worst FPS: ";
- static String tris = "Triangle Count: ";
- static String batches = "Batch Count: ";
- // 需要更新debug信息时更新
- try {
- OverlayElement* guiAvg = OverlayManager::getSingleton().getOverlayElement("Core/AverageFps");
- OverlayElement* guiCurr = OverlayManager::getSingleton().getOverlayElement("Core/CurrFps");
- OverlayElement* guiBest = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
- OverlayElement* guiWorst = OverlayManager::getSingleton().getOverlayElement("Core/WorstFps");
- const RenderTarget::FrameStats& stats = mWindow->getStatistics();
- guiAvg->setCaption(avgFps + StringConverter::toString(stats.avgFPS));
- guiCurr->setCaption(currFps + StringConverter::toString(stats.lastFPS));
- guiBest->setCaption(bestFps + StringConverter::toString(stats.bestFPS)
- +" "+StringConverter::toString(stats.bestFrameTime)+" ms");
- guiWorst->setCaption(worstFps + StringConverter::toString(stats.worstFPS)
- +" "+StringConverter::toString(stats.worstFrameTime)+" ms");
- OverlayElement* guiTris = OverlayManager::getSingleton().getOverlayElement("Core/NumTris");
- guiTris->setCaption(tris + StringConverter::toString(stats.triangleCount));
- OverlayElement* guiBatches = OverlayManager::getSingleton().getOverlayElement("Core/NumBatches");
- guiBatches->setCaption(batches + StringConverter::toString(stats.batchCount));
- OverlayElement* guiDbg = OverlayManager::getSingleton().getOverlayElement("Core/DebugText");
- guiDbg->setCaption(mDebugText);
- }
- catch(...) { /* ignore */ }
- }
- public:
- // 构造函数,初始化成员变量
- ExampleFrameListener(RenderWindow* win, Camera* cam, bool bufferedKeys = false, bool bufferedMouse = false,
- bool bufferedJoy = false ) :
- mCamera(cam), mTranslateVector(Vector3::ZERO), mCurrentSpeed(0), mWindow(win), mStatsOn(true), mNumScreenShots(0),
- mMoveScale(0.0f), mRotScale(0.0f), mTimeUntilNextToggle(0), mFiltering(TFO_BILINEAR),
- mAniso(1), mSceneDetailIndex(0), mMoveSpeed(100), mRotateSpeed(36), mDebugOverlay(0),
- mInputManager(0), mMouse(0), mKeyboard(0), mJoy(0)
- {
- //得到debug视图
- mDebugOverlay = OverlayManager::getSingleton().getByName("Core/DebugOverlay");
- //日志管理器
- LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
- OIS::ParamList pl;
- size_t windowHnd = 0;
- std::ostringstream windowHndStr;
- //取得自定义的属性
- win->getCustomAttribute("WINDOW", &windowHnd);
- windowHndStr << windowHnd;
- pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
- //创建输入管理器
- mInputManager = OIS::InputManager::createInputSystem( pl );
- //创建输入设备、鼠标、键盘、摇杆
- mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, bufferedKeys ));
- mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, bufferedMouse ));
- try {
- mJoy = static_cast<OIS::JoyStick*>(mInputManager->createInputObject( OIS::OISJoyStick, bufferedJoy ));
- }
- catch(...) {
- mJoy = 0;
- }
- //根据窗口的大小来设置鼠标的初始裁剪区域
- windowResized(mWindow);
- //显示debug信息
- showDebugOverlay(true);
- //注册一个windows窗口事件监听
- WindowEventUtilities::addWindowEventListener(mWindow, this);
- }
- //调整鼠标裁剪区域
- virtual void windowResized(RenderWindow* rw)
- {
- unsigned int width, height, depth;
- int left, top;
- //取得窗口矩阵
- rw->getMetrics(width, height, depth, left, top);
- //得到鼠标
- const OIS::MouseState &ms = mMouse->getMouseState();
- ms.width = width;
- ms.height = height;
- }
- //关闭窗口之前进行的处理
- virtual void windowClosed(RenderWindow* rw)
- {
- //检测是否关闭了我们的渲染窗口
- if( rw == mWindow )
- {
- if( mInputManager )
- {
- //清除输入设备
- mInputManager->destroyInputObject( mMouse );
- mInputManager->destroyInputObject( mKeyboard );
- mInputManager->destroyInputObject( mJoy );
- //销毁输入管理器
- OIS::InputManager::destroyInputSystem(mInputManager);
- mInputManager = 0;
- }
- }
- }
- virtual ~ExampleFrameListener()
- {
- //移除所有的窗口事件监听
- WindowEventUtilities::removeWindowEventListener(mWindow, this);
- //关闭窗口
- windowClosed(mWindow);
- }
- //按键事件处理
- virtual bool processUnbufferedKeyInput(const FrameEvent& evt)
- {
- if(mKeyboard->isKeyDown(OIS::KC_A))
- mTranslateVector.x = -mMoveScale; // 向左移动摄像头矩阵
- if(mKeyboard->isKeyDown(OIS::KC_D))
- mTranslateVector.x = mMoveScale; // Move camera RIGHT
- if(mKeyboard->isKeyDown(OIS::KC_UP) || mKeyboard->isKeyDown(OIS::KC_W) )
- mTranslateVector.z = -mMoveScale; // Move camera forward
- if(mKeyboard->isKeyDown(OIS::KC_DOWN) || mKeyboard->isKeyDown(OIS::KC_S) )
- mTranslateVector.z = mMoveScale; // Move camera backward
- if(mKeyboard->isKeyDown(OIS::KC_PGUP))
- mTranslateVector.y = mMoveScale; // Move camera up
- if(mKeyboard->isKeyDown(OIS::KC_PGDOWN))
- mTranslateVector.y = -mMoveScale; // Move camera down
- if(mKeyboard->isKeyDown(OIS::KC_RIGHT))
- mCamera->yaw(-mRotScale);
- if(mKeyboard->isKeyDown(OIS::KC_LEFT))
- mCamera->yaw(mRotScale);
- if( mKeyboard->isKeyDown(OIS::KC_ESCAPE) || mKeyboard->isKeyDown(OIS::KC_Q) )
- return false;
- if( mKeyboard->isKeyDown(OIS::KC_F) && mTimeUntilNextToggle <= 0 )
- {
- mStatsOn = !mStatsOn;
- showDebugOverlay(mStatsOn);
- mTimeUntilNextToggle = 1;
- }
- if( mKeyboard->isKeyDown(OIS::KC_T) && mTimeUntilNextToggle <= 0 )
- {
- switch(mFiltering)
- {
- case TFO_BILINEAR:
- mFiltering = TFO_TRILINEAR;
- mAniso = 1;
- break;
- case TFO_TRILINEAR:
- mFiltering = TFO_ANISOTROPIC;
- mAniso = 8;
- break;
- case TFO_ANISOTROPIC:
- mFiltering = TFO_BILINEAR;
- mAniso = 1;
- break;
- default: break;
- }
- MaterialManager::getSingleton().setDefaultTextureFiltering(mFiltering);
- MaterialManager::getSingleton().setDefaultAnisotropy(mAniso);
- showDebugOverlay(mStatsOn);
- mTimeUntilNextToggle = 1;
- }
- if(mKeyboard->isKeyDown(OIS::KC_SYSRQ) && mTimeUntilNextToggle <= 0)
- {
- std::ostringstream ss;
- ss << "screenshot_" << ++mNumScreenShots << ".png";
- mWindow->writeContentsToFile(ss.str());
- mTimeUntilNextToggle = 0.5;
- mDebugText = "Saved: " + ss.str();
- }
- if(mKeyboard->isKeyDown(OIS::KC_R) && mTimeUntilNextToggle <=0)
- {
- mSceneDetailIndex = (mSceneDetailIndex+1)%3 ;
- switch(mSceneDetailIndex) {
- case 0 : mCamera->setPolygonMode(PM_SOLID); break;//设置多边形的模式
- case 1 : mCamera->setPolygonMode(PM_WIREFRAME); break;
- case 2 : mCamera->setPolygonMode(PM_POINTS); break;
- }
- mTimeUntilNextToggle = 0.5;
- }
- static bool displayCameraDetails = false;
- if(mKeyboard->isKeyDown(OIS::KC_P) && mTimeUntilNextToggle <= 0)
- {
- displayCameraDetails = !displayCameraDetails;
- mTimeUntilNextToggle = 0.5;
- if (!displayCameraDetails)
- mDebugText = "";
- }
- if(displayCameraDetails)
- mDebugText = "P: " + StringConverter::toString(mCamera->getDerivedPosition()) +
- " " + "O: " + StringConverter::toString(mCamera->getDerivedOrientation());
- return true;
- }
- //鼠标事件处理
- virtual bool processUnbufferedMouseInput(const FrameEvent& evt)
- {
- // Rotation factors, may not be used if the second mouse button is pressed
- // 2nd mouse button - slide, otherwise rotate
- const OIS::MouseState &ms = mMouse->getMouseState();
- if( ms.buttonDown( OIS::MB_Right ) )
- {
- mTranslateVector.x += ms.X.rel * 0.13;
- mTranslateVector.y -= ms.Y.rel * 0.13;
- }
- else
- {
- mRotX = Degree(-ms.X.rel * 0.13);
- mRotY = Degree(-ms.Y.rel * 0.13);
- }
- return true;
- }
- //移动摄像头
- virtual void moveCamera()
- {
- //偏移
- mCamera->yaw(mRotX);
- //倾斜
- mCamera->pitch(mRotY);
- //移动摄像机到指定位置
- mCamera->moveRelative(mTranslateVector);
- }
- //显示debug信息
- virtual void showDebugOverlay(bool show)
- {
- if (mDebugOverlay)
- {
- if (show)
- mDebugOverlay->show();
- else
- mDebugOverlay->hide();
- }
- }
- // 渲染队列
- bool frameRenderingQueued(const FrameEvent& evt)
- {
- if(mWindow->isClosed()) return false;
- mSpeedLimit = mMoveScale * evt.timeSinceLastFrame;
- //捕获、更新设备
- mKeyboard->capture();
- mMouse->capture();
- if( mJoy ) mJoy->capture();
- bool buffJ = (mJoy) ? mJoy->buffered() : true;
- Ogre::Vector3 lastMotion = mTranslateVector;
- if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
- {
- // one of the input modes is immediate, so setup what is needed for immediate movement
- if (mTimeUntilNextToggle >= 0)
- mTimeUntilNextToggle -= evt.timeSinceLastFrame;
- // Move about 100 units per second
- mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
- // Take about 10 seconds for full rotation
- mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
- mRotX = 0;
- mRotY = 0;
- mTranslateVector = Ogre::Vector3::ZERO;
- }
- //Check to see which device is not buffered, and handle it
- if( !mKeyboard->buffered() )
- if( processUnbufferedKeyInput(evt) == false )
- return false;
- if( !mMouse->buffered() )
- if( processUnbufferedMouseInput(evt) == false )
- return false;
- // ramp up / ramp down speed
- if (mTranslateVector == Ogre::Vector3::ZERO)
- {
- // decay (one third speed)
- mCurrentSpeed -= evt.timeSinceLastFrame * 0.3;
- mTranslateVector = lastMotion;
- }
- else
- {
- // ramp up
- mCurrentSpeed += evt.timeSinceLastFrame;
- }
- // Limit motion speed
- if (mCurrentSpeed > 1.0)
- mCurrentSpeed = 1.0;
- if (mCurrentSpeed < 0.0)
- mCurrentSpeed = 0.0;
- mTranslateVector *= mCurrentSpeed;
- if( !mMouse->buffered() || !mKeyboard->buffered() || !buffJ )
- moveCamera();
- return true;
- }
- //帧结束,更新状态
- bool frameEnded(const FrameEvent& evt)
- {
- updateStats();
- return true;
- }
- protected:
- //指向摄像机的指针
- Camera* mCamera;
- //一个3维向量,用于摄像机的位置变换
- Vector3 mTranslateVector;
- Real mCurrentSpeed;
- //指向渲染窗口的指针
- RenderWindow* mWindow;
- //是否显示调试信息
- bool mStatsOn;
- //debug信息
- std::string mDebugText;
- //主要用于截图
- unsigned int mNumScreenShots;
- //该demo中,摄像机会旋转
- float mMoveScale;
- //速度限制
- float mSpeedLimit;
- //同样用于摄像机变换
- Degree mRotScale;
- //延时
- Real mTimeUntilNextToggle ;
- //鼠标旋转的角度,用于摄像机的更新
- Radian mRotX, mRotY;
- //纹理差值的类型,枚举类型
- TextureFilterOptions mFiltering;
- int mAniso;
- int mSceneDetailIndex ;
- //移动速度
- Real mMoveSpeed;
- //旋转速度
- Degree mRotateSpeed;
- //debug视图
- Overlay* mDebugOverlay;
- //一些输入设备(输入设备管理器)
- OIS::InputManager* mInputManager;
- //鼠标
- OIS::Mouse* mMouse;
- //键盘
- OIS::Keyboard* mKeyboard;
- //摇杆
- OIS::JoyStick* mJoy;
- };
- #endif
首先,我们要分析的就是Root类,使用Ogre的程序所需要作的第一件事情就是实例化一个Root对象。如果没有这个对象,你就无法调用(除了日志管理以外)的任何一个功能。Root类的构造函数接受一些符串对象的参数,这些字符代表着不同作用的文件名称。
- 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("", "");
上面列出了一些不同的方法来创建Root实例,这里面任何的方法都能单独的正确执行。参数也是系统所默认的值(“plugins.cfg”, “ogre.cfg”, “ogre.log”——当你没有填写参数的时候,系统就认为采用了默认的这些值)。
plugins.cfg:插件,Ogre中所谓的插件就是符合Ogre插件接口的代码模块,比如场景管理(SceneManager)插件和渲染系统(RenderSystem)插件等。在启动的Ogre时候,他会载入plugins.cfg配置文件来查看有哪些插件可以被使用。下面是一个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用于定义这些插件存在的位置(路径), 这里使用“.”,表示需要在“/”或者“/”(即根目录)。在某些平台上可以不使用“.”直接使用""(空白),ogre照样会在“/”或者“/”中去找。
而Plugin则说明了有哪些插件可以使用,但是需要注意,这些插件都没有后缀名。
这里需要注意:在“=”两边不能加入空格或者 Tab字符。
ogre.cfg则是一个属性配置文件,主要保存用户自定义的一些属性,即下图所示的界面的一些属性。
文件如下:
- Render System=Direct3D9 Rendering Subsystem
- [Direct3D9 Rendering Subsystem]
- Allow NVPerfHUD=No
- Anti aliasing=None
- Floating-point mode=Fastest
- Full Screen=No
- Rendering Device=Mobile Intel(R) 945 Express Chipset Family
- VSync=No
- Video Mode=800 x 600 @ 32-bit colour
- sRGB Gamma Conversion=No
- [OpenGL Rendering Subsystem]
- Colour Depth=32
- Display Frequency=N/A
- FSAA=0
- Full Screen=No
- RTT Preferred Mode=FBO
- VSync=No
- Video Mode=1024 x 768
- sRGB Gamma Conversion=No
相信这里就不用多解释,大家都明白了。
Ogre.log :日志文件,用于输出一些调试信息等,比如下代码:
- LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***")
就会在 Ogre.log文件中输出"*** Initializing OIS ***"信息。
另外需要说明得就是FrameListener接口了,当Ogre渲染每一帧的开始和结束的时候会回调FrameListener接口的方法,其中主要包括如下两个渲染方法。
- class ExampleFrameListener : public FrameListener{
- public:
- bool frameStarted (const FrameEvent &evt);
- bool frameEnded (const FrameEvent &evt );
- };
- bool ExampleFrameListener::frameStarted (const FrameEvent &evt){
- //在每一帧画面渲染前
- return true;
- }
- bool ExampleFrameListener::frameEnded (const FrameEvent &evt ){
- //在每一帧画面渲染后
- return true;
- }
所以我们就可以根据需要来实现这两个方式,实现渲染。
注意:在新的版本中frameRenderingQueued方法基本上取代了frameStarted,所以本例中我们就是用了frameRenderingQueued,一般在这个函数中都需要检测各种输入设备的情况,以进行相应的处理。
最后,当我们在程序中调用mRoot->startRendering();方法时,就告诉ogre,我们需要开始渲染了。ogre就会开始渲染。也正是ExampleApplication类中的go方法,所做的,初始化(setup)完成之后就开始渲染(mRoot->startRendering())。
之所以有了这两个类,上一篇中我们才可以不写任何代码就可以构建一个窗口,那么本节内容,我们要显示模型当然就很简单了。
直接在OgreDemo1类的createScene方法中来实现,
1:设置环境光,首先需要为整个场景设置环境光,这样才可以看到要显示的内容,通过调用setAmbientLight函数并指定环境光的颜色就可以做到这些。指定的颜色由红、绿、蓝三种颜色组成,且每种色数值范围在 0 到 1 之间。
- //设置环境光
- mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) )
2:创建一个 Entity (物体),通过调用 SceneManager 的 createEntity 方法来创建
- //创建一个物体
- Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );
变量 mSceneMgr 是当前场景管理器的一个对象,createEntity 方法的第一个参数是为所创建的实体指定一个唯一的标识,第二个参数 "robot.mesh" 指明要使用的网格实体,"robot.mesh" 网格实体在 ExampleApplication 类中被装载。这样,就已经创建了一个实体。
3:还需要创建一个场景节点来与它绑定在一起。既然每个场景管理器都有一个根节点,那我们就在根节点下创建一个场景节点。
- //创建该物体对应的场景节点
- SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );
首先调用场景管理器的 getRootSceneNode 方法来获取根节点,再使用根节点的 createChildSceneNode 方法创建一个名为 "RobotNode" 的场景节点。与实体一样,场景节点的名字也是唯一的。
4:最后,将实体与场景节点绑定在一起,这样机器人(Robot)就会在指定的位置被渲染:
- //将该物体和场景节点关联起来
- node1->attachObject( ent1 );
ok,现在编译运行你的程序,就可以看到我们伟大的机器人界面了。
最后说一下,在创建Root对象时的文件一般会和程序最后的可执行文件在同一目录(因为有人说找不到这些文件)。祝你成功!
- ogre研究之第一个程序
- ogre研究之第一个程序(一)
- ogre研究之第一个程序(二)
- OGRE之第一个程序
- OGRE: Ogre第一个程序
- Ogre学习教程:Ogre第一个程序
- 【Ogre开发】之二:创建自己的第一个Ogre程序
- OGRE 1.9 的第一个程序(OGRE HelloWorld程序)
- 用Ogre写的第一个程序
- 菜鸟也学Ogre-第一个Ogre程序
- Ogre学习笔记(二)创建第一个OGRE程序
- Ogre 第一个原程序
- Castle研究-第一个Castle程序
- 编程语言小传之 零.第一个研究写程序的女人
- 第一章 第一个OGRE应用程序
- Spring研究 (1) 第一个Spring MVC程序
- 第一个IronPython程序(之二)
- 初学汇编之第一个程序
- 信息化是减少碳排放的重要工具
- 罗志威
- excel 单元格的锁定 以及 JXL的实现方式
- 刚开通了博客
- 进价移动加权核算体系
- ogre研究之第一个程序
- 好无聊啊。。
- 用esc键来提高操作速度
- .NET面试题整理-基础篇
- C++转换构造技术
- Oracle 服务名与实例名
- Matlab中Runtime Error问题
- GDB用法(zz)
- 超级搞笑。。。。