接触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;
}