您的位置:首页 > 其它

OGRE自定义场景中控制摄像机的实现

2012-09-11 16:27 501 查看
#include "Ogre/Ogre.h"
#include "OIS/OIS.h"//引入OIS头文件来使用OIS

//创建一个新的称为MyFrameListener,并列出三个公有的事件响应函数
class MyFrameListener:public Ogre::FrameListener
{
//私有成员来存储InputManager和Keyboard
private:
OIS::InputManager *_InputManager;
OIS::Keyboard *_Keyboard;
//为控制摄像机我们需要一个鼠标的指针,一个摄像机的指针和一个定义摄像机移动速度的变量
OIS::Mouse *_mouse;
Ogre::Camera *_cam;
float _movementspeed;
public:
//FrameListener需要一个指向RenderWindow类的指针来初始化OIS,
//所以需要一个以窗口指针作为参数的构造函数
//修改构造函数并添加摄像机指针作为一个新的参数并设置移动的速度为50
MyFrameListener(Ogre::RenderWindow *win,Ogre::Camera *cam)
{
_cam = cam;
_movementspeed = 50.0f;

//OIS使用参数列表来初始化,同样需要一个字符串形式的窗口句柄来构建参数列表;
//创建三个必要的变量来保存数据
OIS::ParamList parameters;
unsigned int windowHandle = 0;
std::ostringstream windowHandleString;
//获得RenderWindow的句柄并转换它为一个字符串
win->getCustomAttribute("WINDOW",&windowHandle);//得到当前渲染窗口在系统中的句柄
windowHandleString<<windowHandle;
//使用键值"WINDOW"来添加字符串类型的句柄到参数表
parameters.insert(std::make_pair("WINDOW",windowHandleString.str()));
//使用参数表来创建InputManager
_InputManager = OIS::InputManager::createInputSystem(parameters);
//用InputManager来创建keyboard
_Keyboard = static_cast<OIS::Keyboard *>(_InputManager->createInputObject(OIS::OISKeyboard,false));
//使用InputManager初始化mouse指针
_mouse = static_cast<OIS::Mouse *>(_InputManager->createInputObject(OIS::OISMouse,false));
}
~MyFrameListener()
{
_InputManager->destroyInputObject(_Keyboard);
_InputManager->destroyInputObject(_mouse);
OIS::InputManager::destroyInputSystem(_InputManager);
}
//创建一个新的frameStarted函数,来获取当前键盘状态,如果按下了Escape,返回false,反之,返回true
bool frameStarted(const Ogre::FrameEvent &evt)
{
_Keyboard->capture();
//添加WASD键来移动摄像机和其速度
Ogre::Vector3 translate(0.0f,0.0f,0.0f);
if(_Keyboard->isKeyDown(OIS::KC_W))
{
translate += Ogre::Vector3(0.0f,0.0f,-1.0f);
}
if(_Keyboard->isKeyDown(OIS::KC_S))
{
translate += Ogre::Vector3(0.0f,0.0f,1.0f);
}
if(_Keyboard->isKeyDown(OIS::KC_A))
{
translate += Ogre::Vector3(-1.0f,0.0f,0.0f);
}
if(_Keyboard->isKeyDown(OIS::KC_D))
{
translate += Ogre::Vector3(1.0f,0.0f,0.0f);
}
_cam->moveRelative(translate*evt.timeSinceLastFrame*_movementspeed);
//鼠标控制
_mouse->capture();
float rotX = _mouse->getMouseState().X.rel*evt.timeSinceLastFrame*(-1);
float rotY = _mouse->getMouseState().Y.rel*evt.timeSinceLastFrame*(-1);
_cam->yaw(Ogre::Radian(rotX));
_cam->pitch(Ogre::Radian(rotY));
if(_Keyboard->isKeyDown(OIS::KC_ESCAPE))
{
return false;
}
return true;
}
};

//创建有两个私有的指针的MyApplication类,一个指向Ogre 3D SceneManager,另一个指向Root类
class MyApplication
{
private:
Ogre::SceneManager *_sceneManager;
Ogre::Root *_root;
//类的主体需要一个指针来存储FrameListener
MyFrameListener *_listener;
//程序需要知道是否要一直循环下去,所以添加一个bool类型的私有成员变量以记录成员的状态
bool _keepRunning;
public:
//创建一个loadResources()函数,这个函数加载resources_d.cfg配置文件
void loadResources()
{
Ogre::ConfigFile cf;
cf.load("resources_d.cfg");
//遍历配置文件的所有区段
Ogre::ConfigFile::SectionIterator sectionIter = cf.getSectionIterator();
Ogre::String sectionName,typeName,dataname;
while(sectionIter.hasMoreElements())
{
//获取区段名称和设置迭代器
sectionName = sectionIter.peekNextKey();
Ogre::ConfigFile::SettingsMultiMap *settings = sectionIter.getNext();
Ogre::ConfigFile::SettingsMultiMap::iterator i;
//迭代所有的设置并添加每个资源
for(i = settings->begin(); i != settings->end(); ++i)
{
typeName = i->first;
dataname = i->second;
Ogre::ResourceGroupManager::getSingleton().addResourceLocation(dataname,typeName,sectionName);
}
Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
}
}
void createScene()
{
Ogre::Entity *ent = _sceneManager->createEntity("Sinbad.mesh");
_sceneManager->getRootSceneNode()->attachObject(ent);
}
//创建一个startup()函数,使用plugins.cfg创建一个Ogre 3D Root类的实现
int startup()
{
_root = new Ogre::Root("plugins_d.cfg");
//显示配置窗口当用户退出时,返回-1并关闭程序
if(!_root->showConfigDialog())
{
return -1;
}
//创建RenderWindow和SceneManager
Ogre::RenderWindow *window = _root->initialise(true,"Ogre 3D Beginners Guide");
_sceneManager = _root->createSceneManager(Ogre::ST_GENERIC);
//创建一个摄像机和视口
Ogre::Camera *camera = _sceneManager->createCamera("Camera");
camera->setPosition(Ogre::Vector3(0.0f,0.0f,50.0f));
camera->lookAt(Ogre::Vector3(0.0f,0.0f,0.0f));
camera->setNearClipDistance(5);
Ogre::Viewport *viewport = window->addViewport(camera);
camera->setAspectRatio(Ogre::Real(viewport->getActualWidth())/Ogre::Real(viewport->getActualHeight()));
//调用函数来加载资源并创建一个场景,最后,Ogre3D可以开始渲染了
loadResources();
createScene();
_listener = new MyFrameListener(window,camera);
_root->addFrameListener(_listener);
//_root->startRendering();
return 0;
}
MyApplication()
{
_sceneManager = NULL;
_root = NULL;
_listener = NULL;
}
~MyApplication()
{
delete _root;
delete _listener;
}
//添加一个新的称为renderOneFrame的函数,这个函数调用了root实例的renderOneFrame函数,
//并且可以把返回值保存在_keepRunning成员变量中。在调用这个之前,添加一个函数在处理
//所有的窗口事件
void renderOneFrame()
{
Ogre::WindowEventUtilities::messagePump();//外部事件的响应,用来接收系统事件,
//比如激活当前窗口,关闭,窗口变化等等,处理程序之间的消息事件
_keepRunning = _root->renderOneFrame();
}
//添加一个获取_keepRunning成员变量的函数
bool keepRunning()
{
return _keepRunning;
}
};

int main(void)
{
MyApplication app;
app.startup();
//添加一个while循环到主函数中,只要keepRunning函数返回true,循环将一直进行下去。再循环体里,
//调用程序的renderOneFrame函数
while(app.keepRunning())
{
app.renderOneFrame();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: