zoukankan      html  css  js  c++  java
  • ogre3D学习基础17 --- 如何手动创建ogre程序

    建立自己的Ogre程序

    一直以来都是使用ExampleApplication.h来写程序,现在来看看它到底有什么神奇的地方。

      首先,我们新建一个win32空项目

      然后配置环境

      最后新建define.cppdefine.hmain.cpp

     具体过程如下

    第一,define.h中包含头文件,这里需要Orge.h文件,然后添加如下代码

    #include "Ogre.h"
    
    class MyApplication
    
    {
    
    public:
    
    MyApplication();
    
    ~MyApplication();
    
    void go();
    
    protected:
    
    bool setup();//设置环境
    
    void setupResources();//设置资源
    
    bool configure();//配置窗口
    
    void chooseSceneManager();//选择场景
    
    void createCamera();//创建摄像机
    
    void createViewports();//创建视口
    
    void loadResources();//加载资源
    
    void createScene();//创建场景
    
    void renderOneFrame();
    
    private:
    
    Ogre::Root*mRoot;//根节点
    
    Ogre::RenderWindow*mWindow;//渲染窗口
    
    Ogre::SceneManager*mSceneMgr;//场景管理器指针
    
    Ogre::Camera*mCamera;//摄像机
    
    bool mShutDowm;
    
    };

    第二,在define.cpp文件中定义函数,代码如下

     1 #include "define.h"
     2 
     3 
     4 MyApplication::MyApplication()//构造函数
     5 {
     6     mRoot = NULL;
     7     mWindow = NULL;
     8     mSceneMgr = NULL;
     9     mCamera = NULL;
    10     mWindow = NULL;
    11     mShutDowm = false;
    12 }
    13 MyApplication::~MyApplication()//析构函数
    14 {
    15     if (mRoot)
    16     {
    17         delete mRoot;
    18     }
    19 }
    20 bool MyApplication::setup()
    21 {
    22     mRoot = new Ogre::Root("plugins_d.cfg");
    23     setupResources();
    24     if (!configure())
    25     {
    26         return false;
    27     }
    28     chooseSceneManager();
    29     createCamera();
    30     createViewports();
    31     loadResources();
    32     createScene();
    33     return true;
    34 }
    35 void MyApplication::setupResources()
    36 {
    37     // 加载资源,ConfigFile类是Ogre中用来读取和解析脚本使用的格式的
    38     Ogre::ConfigFile cf;
    39     cf.load("resources_d.cfg");
    40     //循环遍历资源
    41     Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();//  获取迭代器
    42     Ogre::String secName, typeName,archName;
    43     while (seci.hasMoreElements())//组名
    44     {
    45         secName = seci.peekNextKey();
    46         Ogre::ConfigFile::SettingsMultiMap *settings =seci.getNext();
    47         Ogre::ConfigFile::SettingsMultiMap::iterator i;
    48         for (i =settings->begin();i != settings->end(); ++i)
    49         {
    50             typeName = i->first;//键名
    51             archName = i->second;//键值
    52             Ogre::ResourceGroupManager::getSingleton().addResourceLocation(archName,typeName, secName);
    53         }
    54     }
    55 }
    56 bool MyApplication::configure()
    57 {
    58     if (!mRoot->showConfigDialog())//是否显示配置窗口
    59     {
    60         return false;
    61     }
    62     mWindow = mRoot->initialise(true,"IMedia Project");
    63     return true;
    64 }
    65 void MyApplication::chooseSceneManager()
    66 {
    67     mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
    68 }
    69 void MyApplication::createCamera()
    70 {
    71     mCamera = mSceneMgr->createCamera("MyCamera");
    72     mCamera->setPosition(Ogre::Vector3(0,0,80));
    73     mCamera->lookAt(Ogre::Vector3(0,0,-300));
    74     mCamera->setNearClipDistance(5);
    75 }
    76 void MyApplication::createViewports()
    77 {
    78     Ogre::Viewport*vp = mWindow->addViewport(mCamera);
    79     vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
    80     mCamera->setAspectRatio(Ogre::Real(vp->getActualWidth())/Ogre::Real(vp->getActualHeight()));
    81 }
    82 void MyApplication::loadResources()
    83 {
    84     Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
    85 }
    86 void MyApplication::createScene()
    87 {
    88      Ogre::Entity*ent = mSceneMgr->createEntity("Sinbad.mesh");
    89      mSceneMgr->getRootSceneNode()->attachObject(ent);    
    90 }
    91 void MyApplication::go()
    92 {
    93     if (!setup())
    94         return;
    95     mRoot->startRendering();
    96 }

      在setup函数中完成了一系列的初始化操作,其中的setupResource()函数解释一下,ConfigFile类是Ogre中用来读取和解析脚本使用的格式的,我们用它来加载资源脚本,load函数定义如下:

        void load(const String& filename, const String& separators = " :=", bool trimWhitespace = true);//使用文件名加载文件

      接下来的while循环是循环,while循环负责组名的遍历,内部的for循环负责键名与键值的读取。

     

    第三,我们在main.cpp文件中添加WinMain函数

    1 #include <windows.h>
    2 #include "define.h"
    3 
    4 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
    5 {
    6     MyApplication app;
    7     app.go();
    8     return 0;
    9 }

    这里是我们所需要的最少的代码。如此就可以保证程序跑起来,但还需要继续改进。运行就可以看到结果。

     

    现在我们试试把鼠标和键盘监听添加进去

    第一添加新的父类,包含头文件OIS.h

    class MyApplication:public Ogre::FrameListener,public OIS::KeyListener,public OIS::MouseListener

    {

    .......................

    }

    第二,添加成员函数以及成员变量

     1 Public:
     2 
     3 void createFrameListener(void);//创建帧监听器
     4 
     5 virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);//OGRE
     6 
     7 virtual bool keyPressed(const OIS::KeyEvent &arg);//ois key
     8 
     9 virtual bool keyReleased(const OIS::KeyEvent &arg);//key
    10 
    11 virtual bool mouseMoved( const OIS::MouseEvent &arg );//mouse
    12 
    13 virtual bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
    14 
    15 virtual bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id );
    16 
    17 Private:
    18 
    19 OIS::InputManager *minputManager;//输入管理器
    20 
    21 OIS::Mouse *mMouse;//鼠标
    22 
    23 OIS::Keyboard *mKeyboard;//键盘

    第三,函数定义,虚函数并没有添加其他代码,你可以直接添加需要的动作

     1 void MyApplication::createFrameListener()
     2 {
     3     OIS::ParamList pl;
     4     size_t windowHnd = 0;
     5     std::ostringstream windowHndStr;
     6     mWindow->getCustomAttribute("WINDOW", &windowHnd);//获取自己定义的属性
     7     windowHndStr << windowHnd;
     8     pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
     9     minputManager = OIS::InputManager::createInputSystem( pl );//依照系统环境创建一个合适的输入系统
    10     mKeyboard=static_cast<OIS::Keyboard*>(minputManager->createInputObject( OIS::OISKeyboard, true ));//创建输入对象
    11     mMouse = static_cast<OIS::Mouse*>(minputManager->createInputObject( OIS::OISMouse, true ));
    12 
    13     mMouse->setEventCallback(this);
    14     mKeyboard->setEventCallback(this);
    15     mRoot->addFrameListener(this);
    16 
    17 }
    18 bool MyApplication::frameRenderingQueued(const Ogre::FrameEvent& evt)
    19 {
    20     if (mWindow->isClosed())
    21     {
    22         return false;
    23     }
    24     if (mShutDowm)
    25     {
    26         return false;
    27     }
    28     mKeyboard->capture();
    29     mMouse->capture();
    30     return true;
    31 }
    32 bool MyApplication::keyPressed(const OIS::KeyEvent &arg)
    33 {
    34     if (arg.key == OIS::KC_ESCAPE)
    35     {
    36         mShutDowm = true;
    37     }
    38     return true;
    39 }
    40 bool MyApplication::keyReleased(const OIS::KeyEvent &arg)
    41 {
    42     return true;
    43 }
    44 bool MyApplication::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
    45 {
    46     return true;
    47 }
    48 bool MyApplication::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id )
    49 {
    50     return true;
    51 }
    52 bool MyApplication::mouseMoved( const OIS::MouseEvent &arg )
    53 {
    54     
    55     return true;
    56 }

    代码解释:

    这里看一下createFrameListener()函数,其中 ParamList是一个map类型,定义如下:

      typedef std::multimap<std::string, std::string> ParamList;

    然后是创建输入对象,第一个参数指出了对象的类型

      Object* createInputObject( Type iType, bool bufferMode, const std::string &vendor = "");

     第四,记得在析构函数中清空对象

    1     if (minputManager)
    2     {
    3         minputManager->destroyInputObject(mKeyboard);
    4         minputManager->destroyInputObject(mMouse);
    5         OIS::InputManager::destroyInputSystem(minputManager);
    6         minputManager = 0;
    7     }

      并在setup()函数中调用createFrameListener()函数

    bool MyApplication::setup()
    {
      .........
        createFrameListener();//
        return true;
    }

     

     现在可以实现我们以前用ExampleApplication.h才能实现的功能了,ogre程序的运行过程就是这样。

     

     

     

     

     

     

  • 相关阅读:
    实验 6:OpenDaylight 实验——OpenDaylight 及 Postman 实现流表下发
    实验 4:Open vSwitch 实验——Mininet 中使用 OVS 命令
    实验 3:Mininet 实验——测量路径的损耗率
    第一次个人编程作业
    实验 2:Mininet 实验——拓扑的命令脚本生成
    实验 1:Mininet 源码安装和可视化拓扑工具
    第一次博客作业
    第一次个人编程作业
    第一次博客作业
    需求分析报告
  • 原文地址:https://www.cnblogs.com/songliquan/p/3335230.html
Copyright © 2011-2022 走看看