已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
天龙八部制作教程及源码第一辑一步一步来吧. 把OGRE嵌入到MFC里面,并实现了OIS缓冲输入和鼠标显示,看图: 具体实现方法:一 最好抛弃示例框架,实现一个自己的框架,因为有些东西需要修改,有些东西要自己实现,我自己写了一个框架demo来嵌入MFC,看简洁不少 / 我的帧监听类class MyFrameListener : public FrameListener, public OIS:MouseListener, public OIS:KeyListenerpublic: MyFrameListener(OgreDemo* app, HWND hMainWnd); MyFrameListener(); bool frameStarted(const FrameEvent &evt); bool mouseMoved(const OIS:MouseEvent &e); bool mousePressed(const OIS:MouseEvent &e, OIS:MouseButtonID id); bool mouseReleased(const OIS:MouseEvent &e, OIS:MouseButtonID id); bool keyPressed(const OIS:KeyEvent &e); bool keyReleased(const OIS:KeyEvent &e); protected: SceneManager *mSceneMgr; SceneNode* mCamNode; OIS:Keyboard* mKeyboard; OIS:Mouse* mMouse; OIS:InputManager* mInputManager; Real mRotate; / 旋转常量 Real mMove; / 运动常量 bool mContinue; / 是否要继续渲染 Vector3 mDirection; / 指向正确的移动方向;class OgreDemopublic: OgreDemo():mRoot(0), mWindow(0), mListener(0), mCamera(0), mSceneMgr(0),mCamNode(0) OgreDemo(); void setup(HWND m_hWnd, int width, int height, HWND hMainWnd); / 获得成员变量 Root* getRoot(void) const return mRoot; Camera* getCamera(void) const return mCamera; SceneNode* getCamNode(void) const return mCamNode; SceneManager* getSceneManager(void) const return mSceneMgr; RenderWindow* getRenderWindow(void) const return mWindow; private: Root* mRoot; RenderWindow* mWindow; SceneManager* mSceneMgr; Camera* mCamera; SceneNode* mCamNode; MyFrameListener* mListener; void createRoot(); void defineResources(); void setupRenderSystem(); void createRenderWindow(HWND m_hWnd, int width, int height); void initializeResourceGroups(); void setupScene(); void createFrameListener(HWND hMainWnd); 二, 具体过程分析首先,因为用MFC打开,我们要去掉弹出的配置框,自己把渲染系统参数设置好:void OgreDemo:setupRenderSystem() / 自己设置 RenderSystem *rs = mRoot-getRenderSystemByName(Direct3D9 Rendering Subsystem); mRoot-setRenderSystem(rs); rs-setConfigOption(Full Screen, No); rs-setConfigOption(Video Mode, 800 x 600 32-bit colour); 其次,要嵌入到MFC,那么就要用view视图来作为OGRE的窗口,那么就要在生成OGRE窗口的时候把vire窗口句柄传入,幸好,OGRE不但支持自动产生窗口,还支持外部窗口,具体生产方法: / 传入外部窗口句柄,这里是view类的句柄void OgreDemo:createRenderWindow(HWND m_hWnd, int width, int height) / root初始化的时候,我们可以传入一个false值来告知Root不用给我们自动创建渲染窗口 / 这样我们可以用外部窗口来作为MFC窗口 mRoot-initialise(false); NameValuePairList miscParams; / 参数列表, 作为createRenderWindow函数的最后一个参数 miscParamsexternalWindowHandle = StringConverter:toString(long)m_hWnd); mWindow = mRoot-createRenderWindow(OgreRenderWindow, width, height, false, &miscParams); 现在我们就是用外部程序的窗口来作为OGRE的窗口了. 接着的问题是渲染循环!当你使用startRendering()的时候,因为渲染循环交给了系统,所以没有办法把Ogre结合到窗口系统的消息循环中去.那么WINDOWS的消息循环和startRendering()的这2个独立的循环就会产生冲突,比如WM_PAINT和OGRE一起渲染.解决办法就是做到一个循环中来,正好OGRE有提供只渲染一帧的方法renderOneFrame(); 我把循环做到view视图类的OnDraw函数里面,用时间函数来控制循环void CTLBBView:OnDraw(CDC* /*pDC*/) CTLBBDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; / TODO: 在此处为本机数据添加绘制代码 / 创建OGRE程序/ 程序只初始化一次 if(m_isFirstDraw) m_isFirstDraw = false; CRect rect; GetClientRect(&rect); app.setup(m_hWnd,rect.Width(),rect.Height(),AfxGetApp()-GetMainWnd()-GetSafeHwnd(); / setup后root才被new出来,这时候才可以获得root root = app.getRoot(); / 10ms触发一次 SetTimer(1, 10, NULL); if(m_isStart) root-renderOneFrame(); else/ void CTLBBView:OnTimer(UINT nIDEvent) if(m_isStart) root -renderOneFrame(); 这里有个setTimer,不设置回调函数以后(NULL),就会调OnTimer这个函数,每隔10ms OnTimer收到WM_TIMER消息就会绘制一次10ms fps就是100啊,这里不要递归OnTimer,小心栈溢出哦 既然OnTimer要收到WM_TIMER消息,就要代码中加上消息映射BEGIN_MESSAGE_MAP(CTLBBView, CView) ON_WM_TIMER()END_MESSAGE_MAP() 这样,循环渲染的问题我们用2个timer就解决了, 这下应该OK了吧,但是还有个键盘鼠标的问题,我们用OIS,但是OIS在创建输入系统的时候,他要控制的窗口必须是顶层窗口,就是说你传view视图的窗口句柄给他不行,必须要MFC程序的主窗口,所以又要多传一个参数了哇,算起来我们传了2个窗口参数了,一个MFC主窗口给OIS,一个view视图窗口作为渲染窗口看看我传的参数:app.setup(m_hWnd,rect.Width(),rect.Height(),AfxGetApp()-GetMainWnd()-GetSafeHwnd();第4个参数就是MFC主窗口 参数有了,我们就需要把主窗口句柄传给OIS的OIS:InputManager / 获得输入系统 size_t windowHnd = 0; std:ostringstream windowHndStr; OIS:ParamList pl; app-getRenderWindow()-getCustomAttribute(WINDOW, &windowHnd); windowHnd = (size_t )hMainWnd; / 这里这个窗口句柄就是我们传入的MFC主窗口 windowHndStr windowHnd; / OIS的窗口必须要顶层窗口,所以只有传MFC的主窗口给他,传view就不行 pl.insert(std:make_pair(std:string(WINDOW), windowHndStr.str(); / 设置鼠标显示和非游戏独占,这样鼠标可以显示在屏幕上并可以移动到窗口外 pl.insert(std:make_pair(std:string(w32_mouse), std:string(DISCL_FOREGROUND ); pl.insert(std:make_pair(std:string(w32_mouse), std:string(DISCL_NONEXCLUSIVE); / 键盘非游戏独占 /pl.insert(std:make_pair(std:string(w32_keyboard), std:string(DISCL_FOREGROUND); /pl.insert(std:make_pair(std:string(w32_keyboard), std:string(DISCL_NONEXCLUSIVE); mInputManager = OIS:InputManager:createInputSystem(pl); / 这样InputManager就建好了,但为了从键盘、鼠标、或是手柄中获得输入,你还必须创建这些对象: try mKeyboard = static_cast(mInputManager-createInputObject(OIS:OISKeyboard, true); mMouse = static_cast(mInputManager-createInputObject(OIS:OISMouse, true); /mJoy = static_cast(mInputManager-createInputObject(OIS:OISJoyStick, false); catch (const OIS:Exception &e) throw Exception(42, e.eText, OgreDemo:setupInputSystem); 上面代码还有一个重要的地方,就是 / 设置鼠标显示和非游戏独占,这样鼠标可以显示在屏幕上并可以移动到窗口外 pl.insert(std:make_pair(std:string(w32_mouse), std:string(DISCL_FOREGROUND ); pl.insert(std:make_pair(std:string(w32_mouse), std:string(DISCL_NONEXCLUSIVE);这样的话,你就可以看到鼠标了,还可以移出窗口外面任何地方,就像地图编辑器一样!还可以用来关闭MFC,这样你退出按键都不用写了,如果你还要用鼠标控制视角,可以这样写:bool MyFrameListener:mouseMoved(const OIS:MouseEvent &e) if (e.state.buttonDown(OIS:MB_Left) mCamNode-yaw(Degree(-mRotate * e.state.X.rel), Node:TS_PARENT); mCamNode-pitch(Degree(-mRotate * e.state.Y.rel), Node:TS_LOCAL); return true; 这样你左键按下,就可以控制视角
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025 小学二年级数学下册推理 实践 猜教师礼物 课件
- 厨师职业发展规划及技能提升路径
- 快速掌握财务分析技巧财务报告解读与制作
- 基建工程索赔管理人员索赔争议解决机制
- 教育集团面试实战模拟提高面试通过率的技巧
- 影视剧本创作与导演技巧培训资料
- 广告策划师工作计划与广告创意方案
- TIGIT抑制剂耐药机制及应对策略
- 幼儿园教师班级管理总结
- 小说创作技巧与出版流程详解
- 八省八校2024届高三第一次学业质量评价(T8联考)英语试题
- GB/T 9799-2024金属及其他无机覆盖层钢铁上经过处理的锌电镀层
- DL-T5190.1-2022电力建设施工技术规范第1部分:土建结构工程
- 电大财务大数据分析编程作业3
- MOOC 大数据技术原理与应用-厦门大学 中国大学慕课答案
- 人教版七年级地理上册期中考试大题提分训练(附含参考答案)
- 烤肠工艺流程图
- 《宠物疫病与公共卫生》期终考试试卷及参考答案
- 新版氨水安全技术说明书
- 青海省基本医疗保险门诊特殊病慢性病病种待遇认定表
- 幼儿园数字练习帖10
评论
0/150
提交评论