接触Ogre十多天了,coding的蛋疼,回头整理了下这几天学的东西,综合成了个小例子,录了个视频陶冶一下情操
效果是这样的:
这是解决方案 项目共包含5个文件2个类 ,类MyWorld继承于ExampleApplication,类MyFrameListener继承于FrameListener。
地面、“太阳”、和两个Sinbad还有光照的创建都在MyWorld::createScene()中,摄像机的创建在MyWorld::createCamera()中
实体的运动控制都在MyFrameListener::frameStarted(Ogre::FrameEvent& evt)中,还有MyFrameListener类的带参构造函数也比较重要。
代码如下:
main.cpp:
#include "MyWorld.h" int main() { MyWorld app; app.go(); return 0; }
MyWorld.h:
#pragma once #include "Ogre\ExampleApplication.h" class MyWorld : public ExampleApplication { public: MyWorld(void); ~MyWorld(void); void createScene(); void createCamera(); void createFrameListener(); private: Ogre::Entity* _entSinbadLittle; Ogre::Entity* _entSinbadBig; Ogre::SceneNode* _nodeSinbadLittle; Ogre::SceneNode* _nodeSinbadBig; Ogre::SceneNode* _nodeSun; //FrameListener Ogre::FrameListener* _frameListener; };
MyFrameListener.h
#pragma once #include "Ogre\ExampleFrameListener.h" #include "MyWorld.h" class MyFrameListener : public Ogre::FrameListener { public: MyFrameListener(void); ~MyFrameListener(void); MyFrameListener( Ogre::SceneNode* nodeSinbadLittle, Ogre::SceneNode* nodeSinbadBig, Ogre::SceneNode* nodeSun, Ogre::Entity* entSinbadLittle, Ogre::Entity* entSinbadBig, Ogre::Camera* cam, Ogre::RenderWindow* win ); bool frameStarted(const Ogre::FrameEvent& evt); private: Ogre::Entity* _entSinbadLittle; Ogre::Entity* _entSinbadBig; Ogre::SceneNode* _nodeSinbadLittle; Ogre::SceneNode* _nodeSinbadBig; Ogre::SceneNode* _nodeSun; Ogre::Camera* _cam; Ogre::AnimationState* _aniSinbadLittle; Ogre::AnimationState* _aniSinbadBigBase; Ogre::AnimationState* _aniSinbadBigTop; OIS::InputManager* _man; OIS::Keyboard* _key; OIS::Mouse* _mouse; enum CtrlObject{SinbadLittleCtrl,SinbadBigCtrl,CamCtrl}; CtrlObject _ctrlobject; float _movementSpeed; Ogre::Timer _timer; Ogre::PolygonMode _polyMode; float _walkSpeed; float _rotate; };
MyWorld.cpp
#include "MyWorld.h" #include "MyFrameListener.h" MyWorld::MyWorld(void) { _frameListener = NULL; } MyWorld::~MyWorld(void) { if(_frameListener) delete _frameListener; } void MyWorld::createScene() { using namespace Ogre; //Floor Plane floor(Vector3::UNIT_Y,-20); MeshManager::getSingleton().createPlane( "floor", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, floor,2000,2000,200,200,true,1,6,6,Vector3::UNIT_Z ); Entity* entFloor = mSceneMgr->createEntity("entFloor","floor"); entFloor->setMaterialName("Examples/BeachStones");//贴图 SceneNode* sn = mSceneMgr->getRootSceneNode(); SceneNode* node = sn->createChildSceneNode("nodeGod"); node->attachObject(entFloor); //Light _nodeSun = node->createChildSceneNode("nodeSun"); Light* ltPoint = mSceneMgr->createLight("lightPoint"); ltPoint->setType(Light::LT_POINT); ltPoint->setDiffuseColour(ColourValue(1.f,1.f,1.f)); ltPoint->setPowerScale(3.f);//设置光照强度 Entity* entSun = mSceneMgr->createEntity("entSun","Sphere.mesh"); _nodeSun->attachObject(entSun); _nodeSun->attachObject(ltPoint); _nodeSun->scale(3.f,3.f,3.f); _nodeSun->setPosition(700,800,-700); //Sinbad _entSinbadLittle = mSceneMgr->createEntity("entSinbadLittle","Sinbad.mesh"); _nodeSinbadLittle = node->createChildSceneNode("nodeSInbadLittle"); _nodeSinbadLittle->attachObject(_entSinbadLittle); _nodeSinbadLittle->scale(5.f,5.f,5.f); _nodeSinbadLittle->setPosition(30.f,4.2f,0.f); _entSinbadBig = mSceneMgr->createEntity("entSinbadBig","Sinbad.mesh"); _nodeSinbadBig = node->createChildSceneNode("nodeSInbadBig"); _nodeSinbadBig->attachObject(_entSinbadBig); _nodeSinbadBig->scale(10.f,10.f,10.f); _nodeSinbadBig->setPosition(-30,29,0); //Sword Ogre::Entity* swordL = mSceneMgr->createEntity("swordL","Sword.mesh"); Ogre::Entity* swordR = mSceneMgr->createEntity("swordR","Sword.mesh"); _entSinbadBig->attachObjectToBone("Handle.L",swordL); _entSinbadBig->attachObjectToBone("Handle.R",swordR); //Shadow mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE); //Get all animation /* Ogre::AnimationStateSet* set = _entSinbadBig->getAllAnimationStates(); Ogre::AnimationStateIterator it = set->getAnimationStateIterator(); while(it.hasMoreElements()) { std::cout << it.getNext()->getAnimationName() << std::endl; } */ } void MyWorld::createCamera() { mCamera = mSceneMgr->createCamera("MyCam"); mCamera->setPosition(0,300,400); mCamera->lookAt(0,0,0); mCamera->setNearClipDistance(5); } void MyWorld::createFrameListener() { _frameListener = new MyFrameListener( _nodeSinbadLittle, _nodeSinbadBig, _nodeSun, _entSinbadLittle, _entSinbadBig, mCamera, mWindow); mRoot->addFrameListener(_frameListener); } MyFrameListener.cpp #include "MyFrameListener.h" MyFrameListener::MyFrameListener(void) { } MyFrameListener::~MyFrameListener(void) { _man->destroyInputObject(_key); _man->destroyInputObject(_mouse); OIS::InputManager::destroyInputSystem(_man); } MyFrameListener::MyFrameListener( Ogre::SceneNode* nodeSinbadLittle, Ogre::SceneNode* nodeSinbadBig, Ogre::SceneNode* nodeSun, Ogre::Entity* entSinbadLittle, Ogre::Entity* entSinbadBig, Ogre::Camera* cam, Ogre::RenderWindow* win ) { _entSinbadLittle = entSinbadLittle; _entSinbadBig = entSinbadBig; _nodeSinbadLittle = nodeSinbadLittle; _nodeSinbadBig = nodeSinbadBig; _nodeSun = nodeSun; _cam = cam; //InputSystem size_t windowHnd = 0; std::stringstream windowHndStr; win->getCustomAttribute("WINDOW",&windowHnd); windowHndStr << windowHnd; OIS::ParamList pl; pl.insert(std::make_pair(std::string("WINDOW"),windowHndStr.str())); _man = OIS::InputManager::createInputSystem(pl); _key = static_cast<OIS::Keyboard*>(_man->createInputObject(OIS::OISKeyboard,false)); _mouse = static_cast<OIS::Mouse*>(_man->createInputObject(OIS::OISMouse,false)); //Default Control Object _ctrlobject = CamCtrl; _movementSpeed = 150.f; _walkSpeed = 70.f; _rotate = 0.f; //Animation _aniSinbadLittle = entSinbadLittle->getAnimationState("Dance"); _aniSinbadLittle->setEnabled(true); _aniSinbadLittle->setLoop(true); _aniSinbadBigBase = entSinbadBig->getAnimationState("RunBase"); _aniSinbadBigBase->setLoop(false); _aniSinbadBigTop = entSinbadBig->getAnimationState("RunTop"); _aniSinbadBigTop->setLoop(false); _timer.reset(); _polyMode = PolygonMode::PM_SOLID; //Sunmove _nodeSun->yaw(Radian(180.f)); } bool MyFrameListener::frameStarted(const Ogre::FrameEvent& evt) { using namespace OIS; #pragma region KeyAndMouseControl bool Walked = false; Ogre::Vector3 tr(0.f,0.f,0.f); _key->capture(); if(_key->isKeyDown(KC_Q) && _timer.getMilliseconds() > 250) { _timer.reset(); if(_ctrlobject == SinbadBigCtrl) _ctrlobject = CamCtrl; else if(_ctrlobject == CamCtrl) _ctrlobject = SinbadBigCtrl; } if(_key->isKeyDown(KC_W)) { tr += Ogre::Vector3(0,0,-1); _rotate = 3.1415926f; Walked = true; } if(_key->isKeyDown(KC_S)) { tr += Ogre::Vector3(0,0,1); _rotate = 0.0f; Walked = true; } if(_key->isKeyDown(KC_A)) { tr += Ogre::Vector3(-1,0,0); _rotate = -1.57f; Walked = true; } if(_key->isKeyDown(KC_D)) { tr += Ogre::Vector3(1,0,0); _rotate = 1.57f; Walked = true; } if(_key->isKeyDown(KC_ESCAPE)) return false; if(_key->isKeyDown(KC_R) && _timer.getMilliseconds() > 250) { _timer.reset(); if(_polyMode == PM_SOLID) _polyMode = PM_WIREFRAME; else if(_polyMode == PM_WIREFRAME) _polyMode = PM_POINTS; else if(_polyMode == PM_POINTS) _polyMode = PM_SOLID; _cam->setPolygonMode(_polyMode); } _mouse->capture(); float rotX = _mouse->getMouseState().X.rel * evt.timeSinceLastFrame * -0.1; float rotY = _mouse->getMouseState().Y.rel * evt.timeSinceLastFrame * -0.1; if(_ctrlobject == SinbadBigCtrl) { if(Walked) { _aniSinbadBigBase->setEnabled(true); _aniSinbadBigTop->setEnabled(true); if(_aniSinbadBigBase->hasEnded()) { _aniSinbadBigBase->setTimePosition(0.f); } if(_aniSinbadBigTop->hasEnded()) { _aniSinbadBigTop->setTimePosition(0.f); } //这一块不太懂 _nodeSinbadBig->translate(tr * evt.timeSinceLastFrame * _walkSpeed); _nodeSinbadBig->resetOrientation(); _nodeSinbadBig->yaw(Ogre::Radian(_rotate)); } } else if(_ctrlobject == CamCtrl) { _cam->yaw(Ogre::Radian(rotX)); _cam->pitch(Ogre::Radian(rotY)); _cam->moveRelative(tr * evt.timeSinceLastFrame * _movementSpeed); } if(!Walked) { _aniSinbadBigBase->setTimePosition(0.f); _aniSinbadBigBase->setEnabled(false); _aniSinbadBigTop->setTimePosition(0.f); _aniSinbadBigTop->setEnabled(false); } #pragma endregion //Animation _aniSinbadLittle->addTime(evt.timeSinceLastFrame * 2.f); _aniSinbadBigBase->addTime(evt.timeSinceLastFrame * 0.8f); _aniSinbadBigTop->addTime(evt.timeSinceLastFrame * 0.8f); //Sun move _nodeSun->pitch(Radian(1.f) * evt.timeSinceLastFrame); _nodeSun->translate(Ogre::Vector3(0.f,0.f,10.f) * evt.timeSinceLastFrame * _movementSpeed,Ogre::Node::TS_LOCAL); return true; }