添加观察者模式的帧监听器,基于时间或者基于帧移动模型
class Example25FrameListener : public Ogre::FrameListener { public: Example25FrameListener(Ogre::SceneNode* node) : m_sceneNode(node){} // the render loop will closed if this function return false bool frameStarted(const FrameEvent& evt) { // 基于帧的移动--每帧渲染之前将模型在x轴上移动0.1个单位, // 在同样的时间内,不同的电脑渲染的帧数不同,导致在相同的时间内移动的距离不同。 //m_sceneNode->translate(Ogre::Vector3(0.1f, 0.0f, 0.0f)); // 基于时间的移动--在相同的时间内移动的距离相同,但是移动的速度不同。 m_sceneNode->translate(Ogre::Vector3(10, 0, 0) * evt.timeSinceLastFrame); return true; } private: Ogre::SceneNode* m_sceneNode; }; class MyApplication :public ExampleApplication { public: MyApplication() : m_listener(NULL){} ~MyApplication() { if (m_listener) delete m_listener; } void createCamera() { mCamera = mSceneMgr->createCamera("mycamera"); mCamera->setPosition(0, 100, 200); mCamera->lookAt(0, 0, 0); mCamera->setNearClipDistance(5); } void createViewports() { // create a viewport Ogre::Viewport* vp = mWindow->addViewport(mCamera); // set viewport's background color vp->setBackgroundColour(Ogre::ColourValue(0.0f, 0.0f, 1.0f)); // set aspect ratio mCamera->setAspectRatio(Real(vp->getActualWidth() / vp->getActualHeight())); } void createFrameListener() { m_listener = new Example25FrameListener(m_sinBadNode); mRoot->addFrameListener(m_listener); } void createScene() { // 先用定义的平面创建一个网格,再用创建的网格构造一个实体 Ogre::Plane plane(Ogre::Vector3::UNIT_Y, -10); Ogre::MeshManager::getSingleton().createPlane("plane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 1500, 1500, 200, 200, true, 1, 5, 5, Vector3::UNIT_Z ); Ogre::Entity* ent = mSceneMgr->createEntity("lightpalneentity", "plane"); Ogre::SceneNode* node = mSceneMgr->createSceneNode("node"); mSceneMgr->getRootSceneNode()->addChild(node); node->attachObject(ent); ent->setMaterialName("Examples/BeachStones"); // 方向光不用设置位置 Ogre::Light* light = mSceneMgr->createLight("light"); light->setType(Ogre::Light::LT_DIRECTIONAL); //light->setDiffuseColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f)); light->setDirection(Ogre::Vector3(1, -1, 0)); Ogre::Entity* sinbad = mSceneMgr->createEntity("sinbad", "Sinbad.mesh"); m_sinBadNode = node->createChildSceneNode("sinbadnode"); m_sinBadNode->setScale(3.0f, 3.0f, 3.0f); m_sinBadNode->setPosition(Ogre::Vector3(0.0f, 4.0f, 0.0f)); m_sinBadNode->attachObject(sinbad); // 设置阴影 mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE); } private: Ogre::SceneNode* m_sinBadNode; Ogre::FrameListener* m_listener; }; int main() { MyApplication app; app.go(); return 0; }
添加键盘响应
class Example25FrameListener : public Ogre::FrameListener { public: Example25FrameListener(Ogre::SceneNode* node, RenderWindow* win) : m_sceneNode(node) { // 获得渲染窗口的句柄,将其转换成字符串; // 将渲染窗口的标识字符串"WINDOW"和渲染窗口的句柄字符串加到一个OIS::ParamList // 用OIS::ParamList创建一个OIS::InputManager // 用OIS::InputManager创建一个OIS::Keyboard // 在frameStarted中用OIS::Keyboard检测键盘事件 size_t winHnd = 0; std::stringstream winHndStr; win->getCustomAttribute("WINDOW", &winHnd); winHndStr << winHnd; OIS::ParamList pl; pl.insert(std::make_pair(std::string("WINDOW"), winHndStr.str())); m_inputMgr = OIS::InputManager::createInputSystem(pl); m_keyBord = static_cast<OIS::Keyboard*>(m_inputMgr->createInputObject(OIS::OISKeyboard, false)); } ~Example25FrameListener() { m_inputMgr->destroyInputObject(m_keyBord); OIS::InputManager::destroyInputSystem(m_inputMgr); } // the render loop will closed if this function return false bool frameStarted(const FrameEvent& evt) { Ogre::Vector3 translateVec(0, 0, 0); m_keyBord->capture(); if (m_keyBord->isKeyDown(OIS::KC_ESCAPE)) return false; if (m_keyBord->isKeyDown(OIS::KC_W)) translateVec += Ogre::Vector3(0, 0, -1); if (m_keyBord->isKeyDown(OIS::KC_S)) translateVec += Ogre::Vector3(0, 0, 1); if (m_keyBord->isKeyDown(OIS::KC_A)) translateVec += Ogre::Vector3(-1, 0, 0); if (m_keyBord->isKeyDown(OIS::KC_D)) translateVec += Ogre::Vector3(1, 0, 0); m_sceneNode->translate(translateVec); return true; } private: Ogre::SceneNode* m_sceneNode; OIS::InputManager* m_inputMgr; OIS::Keyboard* m_keyBord; }; class MyApplication :public ExampleApplication { public: MyApplication() : m_listener(NULL){} ~MyApplication() { if (m_listener) delete m_listener; } void createCamera() { mCamera = mSceneMgr->createCamera("mycamera"); mCamera->setPosition(0, 100, 200); mCamera->lookAt(0, 0, 0); mCamera->setNearClipDistance(5); } void createViewports() { // create a viewport Ogre::Viewport* vp = mWindow->addViewport(mCamera); // set viewport's background color vp->setBackgroundColour(Ogre::ColourValue(0.0f, 0.0f, 1.0f)); // set aspect ratio mCamera->setAspectRatio(Real(vp->getActualWidth() / vp->getActualHeight())); } void createFrameListener() { m_listener = new Example25FrameListener(m_sinBadNode, mWindow); mRoot->addFrameListener(m_listener); } void createScene() { // 先用定义的平面创建一个网格,再用创建的网格构造一个实体 Ogre::Plane plane(Ogre::Vector3::UNIT_Y, -10); Ogre::MeshManager::getSingleton().createPlane("plane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 1500, 1500, 200, 200, true, 1, 5, 5, Vector3::UNIT_Z ); Ogre::Entity* ent = mSceneMgr->createEntity("lightpalneentity", "plane"); Ogre::SceneNode* node = mSceneMgr->createSceneNode("node"); mSceneMgr->getRootSceneNode()->addChild(node); node->attachObject(ent); ent->setMaterialName("Examples/BeachStones"); // 方向光不用设置位置 Ogre::Light* light = mSceneMgr->createLight("light"); light->setType(Ogre::Light::LT_DIRECTIONAL); //light->setDiffuseColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f)); light->setDirection(Ogre::Vector3(1, -1, 0)); Ogre::Entity* sinbad = mSceneMgr->createEntity("sinbad", "Sinbad.mesh"); m_sinBadNode = node->createChildSceneNode("sinbadnode"); m_sinBadNode->setScale(3.0f, 3.0f, 3.0f); m_sinBadNode->setPosition(Ogre::Vector3(0.0f, 4.0f, 0.0f)); m_sinBadNode->attachObject(sinbad); // 设置阴影 mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE); } private: Ogre::SceneNode* m_sinBadNode; Ogre::FrameListener* m_listener; };
添加键盘,鼠标响应
class Example25FrameListener : public Ogre::FrameListener { public: Example25FrameListener(Ogre::SceneNode* node, RenderWindow* win, Camera* cam) : m_sceneNode(node), m_camera(cam) { // 获得渲染窗口的句柄,将其转换成字符串; // 将渲染窗口的标识字符串"WINDOW"和渲染窗口的句柄字符串加到一个OIS::ParamList // 用OIS::ParamList创建一个OIS::InputManager // 用OIS::InputManager创建一个OIS::Keyboard // 在frameStarted中用OIS::Keyboard检测键盘事件 size_t winHnd = 0; std::stringstream winHndStr; win->getCustomAttribute("WINDOW", &winHnd); winHndStr << winHnd; OIS::ParamList pl; pl.insert(std::make_pair(std::string("WINDOW"), winHndStr.str())); m_inputMgr = OIS::InputManager::createInputSystem(pl); m_keyBord = static_cast<OIS::Keyboard*>(m_inputMgr->createInputObject(OIS::OISKeyboard, false)); m_mouse = static_cast<OIS::Mouse*>(m_inputMgr->createInputObject(OIS::OISMouse, false)); m_moveSpeed = 2.0f; } ~Example25FrameListener() { m_inputMgr->destroyInputObject(m_keyBord); m_inputMgr->destroyInputObject(m_mouse); OIS::InputManager::destroyInputSystem(m_inputMgr); } // the render loop will closed if this function return false bool frameStarted(const FrameEvent& evt) { Ogre::Vector3 translateVec(0, 0, 0); m_keyBord->capture(); if (m_keyBord->isKeyDown(OIS::KC_ESCAPE)) return false; if (m_keyBord->isKeyDown(OIS::KC_W)) translateVec += Ogre::Vector3(0, 0, -10); if (m_keyBord->isKeyDown(OIS::KC_S)) translateVec += Ogre::Vector3(0, 0, 10); if (m_keyBord->isKeyDown(OIS::KC_A)) translateVec += Ogre::Vector3(-10, 0, 0); if (m_keyBord->isKeyDown(OIS::KC_D)) translateVec += Ogre::Vector3(10, 0, 0); //m_sceneNode->translate(translateVec); m_sceneNode->translate(translateVec * evt.timeSinceLastFrame * m_moveSpeed); m_mouse->capture(); float rot_x = m_mouse->getMouseState().X.rel * evt.timeSinceLastFrame * (- 1); float rot_y = m_mouse->getMouseState().Y.rel * evt.timeSinceLastFrame * (- 1); m_camera->yaw(Ogre::Radian(rot_x)); m_camera->pitch(Ogre::Radian(rot_y)); m_camera->moveRelative(translateVec * evt.timeSinceLastFrame * m_moveSpeed); return true; } private: Ogre::SceneNode* m_sceneNode; OIS::InputManager* m_inputMgr; OIS::Keyboard* m_keyBord; OIS::Mouse* m_mouse; Ogre::Camera* m_camera; double m_moveSpeed; }; class MyApplication :public ExampleApplication { public: MyApplication() : m_listener(NULL){} ~MyApplication() { if (m_listener) delete m_listener; } void createCamera() { mCamera = mSceneMgr->createCamera("mycamera"); mCamera->setPosition(0, 100, 200); mCamera->lookAt(0, 0, 0); mCamera->setNearClipDistance(5); } void createViewports() { // create a viewport Ogre::Viewport* vp = mWindow->addViewport(mCamera); // set viewport's background color vp->setBackgroundColour(Ogre::ColourValue(0.0f, 0.0f, 1.0f)); // set aspect ratio mCamera->setAspectRatio(Real(vp->getActualWidth() / vp->getActualHeight())); } void createFrameListener() { m_listener = new Example25FrameListener(m_sinBadNode, mWindow, mCamera); mRoot->addFrameListener(m_listener); } void createScene() { // 先用定义的平面创建一个网格,再用创建的网格构造一个实体 Ogre::Plane plane(Ogre::Vector3::UNIT_Y, -10); Ogre::MeshManager::getSingleton().createPlane("plane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 1500, 1500, 200, 200, true, 1, 5, 5, Vector3::UNIT_Z ); Ogre::Entity* ent = mSceneMgr->createEntity("lightpalneentity", "plane"); Ogre::SceneNode* node = mSceneMgr->createSceneNode("node"); mSceneMgr->getRootSceneNode()->addChild(node); node->attachObject(ent); ent->setMaterialName("Examples/BeachStones"); // 方向光不用设置位置 Ogre::Light* light = mSceneMgr->createLight("light"); light->setType(Ogre::Light::LT_DIRECTIONAL); //light->setDiffuseColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f)); light->setDirection(Ogre::Vector3(1, -1, 0)); Ogre::Entity* sinbad = mSceneMgr->createEntity("sinbad", "Sinbad.mesh"); m_sinBadNode = node->createChildSceneNode("sinbadnode"); m_sinBadNode->setScale(3.0f, 3.0f, 3.0f); m_sinBadNode->setPosition(Ogre::Vector3(0.0f, 4.0f, 0.0f)); m_sinBadNode->attachObject(sinbad); // 设置阴影 mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE); } private: Ogre::SceneNode* m_sinBadNode; Ogre::FrameListener* m_listener; };
键盘相应+鼠标相应+定时器和R键改变多边形绘制模式+移动模型同时移动摄像机
class Example25FrameListener : public Ogre::FrameListener { public: Example25FrameListener(Ogre::SceneNode* node, RenderWindow* win, Camera* cam) : m_sceneNode(node), m_camera(cam) { // 获得渲染窗口的句柄,将其转换成字符串; // 将渲染窗口的标识字符串"WINDOW"和渲染窗口的句柄字符串加到一个OIS::ParamList // 用OIS::ParamList创建一个OIS::InputManager // 用OIS::InputManager创建一个OIS::Keyboard // 在frameStarted中用OIS::Keyboard检测键盘事件 size_t winHnd = 0; std::stringstream winHndStr; win->getCustomAttribute("WINDOW", &winHnd); winHndStr << winHnd; OIS::ParamList pl; pl.insert(std::make_pair(std::string("WINDOW"), winHndStr.str())); m_inputMgr = OIS::InputManager::createInputSystem(pl); m_keyBord = static_cast<OIS::Keyboard*>(m_inputMgr->createInputObject(OIS::OISKeyboard, false)); m_mouse = static_cast<OIS::Mouse*>(m_inputMgr->createInputObject(OIS::OISMouse, false)); m_moveSpeed = 2.0f; m_polygonMode = Ogre::PolygonMode::PM_SOLID; m_timer.reset(); } ~Example25FrameListener() { m_inputMgr->destroyInputObject(m_keyBord); m_inputMgr->destroyInputObject(m_mouse); OIS::InputManager::destroyInputSystem(m_inputMgr); } // the render loop will closed if this function return false bool frameStarted(const FrameEvent& evt) { Ogre::Vector3 translateVec(0, 0, 0); m_keyBord->capture(); if (m_keyBord->isKeyDown(OIS::KC_ESCAPE)) return false; if (m_keyBord->isKeyDown(OIS::KC_W)) translateVec += Ogre::Vector3(0, 0, -10); if (m_keyBord->isKeyDown(OIS::KC_S)) translateVec += Ogre::Vector3(0, 0, 10); if (m_keyBord->isKeyDown(OIS::KC_A)) translateVec += Ogre::Vector3(-10, 0, 0); if (m_keyBord->isKeyDown(OIS::KC_D)) translateVec += Ogre::Vector3(10, 0, 0); // 利用定时器和R键更改绘制多边形模式 if (m_keyBord->isKeyDown(OIS::KC_R) && m_timer.getMilliseconds() > 250) { if (m_polygonMode == Ogre::PolygonMode::PM_SOLID) m_polygonMode = Ogre::PolygonMode::PM_WIREFRAME; else if (m_polygonMode == Ogre::PolygonMode::PM_WIREFRAME) m_polygonMode = Ogre::PolygonMode::PM_POINTS; else if (m_polygonMode == Ogre::PolygonMode::PM_POINTS) m_polygonMode = Ogre::PolygonMode::PM_SOLID; m_camera->setPolygonMode(m_polygonMode); m_timer.reset(); } //m_sceneNode->translate(translateVec); m_sceneNode->translate(translateVec * evt.timeSinceLastFrame * m_moveSpeed); m_mouse->capture(); float rot_x = m_mouse->getMouseState().X.rel * evt.timeSinceLastFrame * (- 1); float rot_y = m_mouse->getMouseState().Y.rel * evt.timeSinceLastFrame * (- 1); m_camera->yaw(Ogre::Radian(rot_x)); m_camera->pitch(Ogre::Radian(rot_y)); // Moves the camera's position by the vector offset provided // along it's own axes (relative to orientation). // 使摄像机跟随场景节点(模型)一起动 m_camera->moveRelative(translateVec * evt.timeSinceLastFrame * m_moveSpeed); return true; } private: Ogre::SceneNode* m_sceneNode; OIS::InputManager* m_inputMgr; OIS::Keyboard* m_keyBord; OIS::Mouse* m_mouse; Ogre::Camera* m_camera; double m_moveSpeed; Ogre::PolygonMode m_polygonMode; Ogre::Timer m_timer; }; class MyApplication :public ExampleApplication { public: MyApplication() : m_listener(NULL){} ~MyApplication() { if (m_listener) delete m_listener; } void createCamera() { mCamera = mSceneMgr->createCamera("mycamera"); mCamera->setPosition(0, 100, 200); mCamera->lookAt(0, 0, 0); mCamera->setNearClipDistance(5); } void createViewports() { // create a viewport Ogre::Viewport* vp = mWindow->addViewport(mCamera); // set viewport's background color vp->setBackgroundColour(Ogre::ColourValue(0.0f, 0.0f, 1.0f)); // set aspect ratio mCamera->setAspectRatio(Real(vp->getActualWidth() / vp->getActualHeight())); } void createFrameListener() { m_listener = new Example25FrameListener(m_sinBadNode, mWindow, mCamera); mRoot->addFrameListener(m_listener); } void createScene() { // 先用定义的平面创建一个网格,再用创建的网格构造一个实体 Ogre::Plane plane(Ogre::Vector3::UNIT_Y, -10); Ogre::MeshManager::getSingleton().createPlane("plane", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane, 1500, 1500, 200, 200, true, 1, 5, 5, Vector3::UNIT_Z ); Ogre::Entity* ent = mSceneMgr->createEntity("lightpalneentity", "plane"); Ogre::SceneNode* node = mSceneMgr->createSceneNode("node"); mSceneMgr->getRootSceneNode()->addChild(node); node->attachObject(ent); ent->setMaterialName("Examples/BeachStones"); // 方向光不用设置位置 Ogre::Light* light = mSceneMgr->createLight("light"); light->setType(Ogre::Light::LT_DIRECTIONAL); //light->setDiffuseColour(Ogre::ColourValue(1.0f, 1.0f, 1.0f)); light->setDirection(Ogre::Vector3(1, -1, 0)); Ogre::Entity* sinbad = mSceneMgr->createEntity("sinbad", "Sinbad.mesh"); m_sinBadNode = node->createChildSceneNode("sinbadnode"); m_sinBadNode->setScale(3.0f, 3.0f, 3.0f); m_sinBadNode->setPosition(Ogre::Vector3(0.0f, 4.0f, 0.0f)); m_sinBadNode->attachObject(sinbad); // 设置阴影 mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE); } private: Ogre::SceneNode* m_sinBadNode; Ogre::FrameListener* m_listener; };