- 浏览: 174312 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
maimode:
今天试了一下,支持中文(sdk 4.1),但是需要网络支持。很 ...
Android教程之Android自带的语音识别例子初探 -
YuanYe24:
我用我的华为8810和moto defy525+都不行啊,按钮 ...
Android教程之Android自带的语音识别例子初探 -
山脚下的农民:
楼主的书哥看完了,写的不错,能够抛砖引玉,是本不错的入门书籍。 ...
Android2.0 中读取联系人——ContactsContract -
JACKDG2010:
楼主,android没有image这个类咋办???
使用BinCompiler将资源文件打包成二进制文件 -
Simdanfeg:
不得不承认我很喜欢这个类
J2ME卡马克算法案例--地图滚屏(附源码)
版权申明:http://yarin.iteye.com/blog/453262
上一篇我们介绍了如何搭建开发环境,并创建了一个空白的窗口程序。
这里我们主要是实现在程序中装载一个简单的模型并显示出来。
首先看一下效果吧,(模型就是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引擎中构建并显示一个简单的3D模型。Ogre是一个开源的3D图形渲染引擎,广泛用于游戏开发和其他需要高质量3D图形的应用。在这个过程中,我们将了解到几个关键的...
1. **OGRE 3D基础知识**:包括OGRE的安装与配置,理解其基本架构,以及如何设置第一个3D场景。 2. **资源管理**:学习如何加载模型、纹理、材质和动画,理解OGRE的资源管理系统,以高效地管理项目中的各种资源。 3...
"ZombieIsland_bug_camera"程序专注于相机系统的调试,可能包含了各种相机运动模式的实现,如自由视角、第一人称视角、第三人称视角等。开发者可能通过这个程序来检查相机在不同场景、运动状态下的表现,找出并修复...
"ogre_source file" 是一个与 Ogre 3D 渲染引擎相关的压缩包,它包含了用于学习和开发基于 Ogre 的应用程序的源代码示例。Ogre 是一款强大的开源图形渲染引擎,广泛应用于游戏开发、虚拟现实和可视化应用等领域。这...
- 创建第一个项目:编写简单的“Hello World”程序,展示3D立方体。 - 进阶学习:研究光照、材质、动画和脚本,尝试创建更复杂的场景。 7. **社区与资源** - OGRE官方论坛:遇到问题时,可以在官方论坛提问,...
总之,“Havok动画渲染Demo(使用Ogre) 测试程序和源代码”为我们提供了一个学习和实践Havok物理引擎与Ogre渲染引擎结合应用的宝贵机会。掌握这两个工具的结合使用,对于提升3D游戏或实时仿真应用的品质具有重要意义...
这个"CEGUI-0.5.0-RC2.zip"压缩包包含了CEGUI 0.5.0的第二个候选发布版本,用于与Ogre 3D渲染引擎集成,提供强大的界面创建能力。 CEGUI库的核心特点在于其可扩展性和灵活性,允许开发者根据需求定制各种控件和布局...
- **第一个项目**:通过创建简单的“Hello World”项目来熟悉Ogre 3D的工作流程。 ##### 3.3 基础教程 - **基本概念**:介绍了Ogre 3D中的关键概念,如节点(Node)、实体(Entity)、场景(Scene)等。 - **场景构建**...
1. **Ogre入门**:介绍如何安装Ogre SDK,设置项目环境,并编写基本的“Hello World”程序,展示如何创建一个窗口并加载Ogre渲染场景。 2. **场景管理**:讲解Ogre的Scene Manager,它是如何组织和管理3D场景的,...
在你的第一个OGRE程序中,你会看到一个简单的`TutorialApplication`类,它是`ExampleApplication`的子类。`createScene`函数是添加和设置场景内容的地方。虽然初始代码可能只包含框架,但随着教程的深入,你将逐步...
它涵盖了从安装到创建第一个项目的整个过程,并且包含了一些常见问题的解答,帮助用户迅速上手。 "OGRE使用指南v0[1].01a.doc"可能是OGRE早期版本的一个用户指南,尽管版本较旧,但对于理解OGRE的基本工作原理仍然...
- 快速入门:搭建开发环境,创建第一个3D应用。 - GUI系统:使用Ogre的Overlay系统创建用户界面。 - 动画系统:角色动画、骨骼动画以及动画状态机。 - 摄像机控制:视角切换、视锥体剪裁等。 - AI与行为树:在...
在实际应用中,OgreBullet可用于创建各种类型的游戏,例如赛车游戏中的车辆碰撞、第一人称射击游戏中的弹道模拟,或者建筑模拟器中的结构稳定性测试。此外,它也适用于非游戏领域的3D应用,如模拟仿真、可视化工具等...
### 在游戏中使用CEGUI——第一章(底层) #### 一、引言 随着游戏行业的不断发展,游戏界面设计变得越来越重要。良好的用户界面不仅能够提升玩家的游戏体验,还能提高游戏的市场竞争力。CEGUI(Crazy Eddie's GUI...
总之,基于OGRE的三维渲染引擎编辑器是一个强大的工具,它为三维开发人员提供了一个功能丰富、使用便捷的环境。通过这样的编辑器,可以更高效地制作出高质量的三维应用程序,无论是游戏开发、虚拟现实还是可视化模拟...
CEGUI,全称为“Crazy Eddie's GUI System”,是一个开源的、跨平台的图形用户界面(GUI)库,专门设计用于游戏开发和其他实时应用程序。它提供了丰富的组件和自定义功能,使得开发者能够创建出复杂的、高性能的用户...
TelaMitto是一款开源的第一人称射击(FPS)游戏,采用角色扮演的元素,为玩家提供丰富的游戏体验。它不仅是一个娱乐项目,更是技术爱好者和开发者研究、学习和改进游戏开发技术的宝贵资源。这款游戏的核心特性包括...