• ogre3D学习基础11 -- 交换两个场景管理器


      这一节,练习一下前几次学习的内容,功能很简单,就是建立两个不同的场景管理器,当按下键盘上某个键时切换镜头。

      基本框架不变,这个监听器继承了两个父类,一个是我们的老朋友ExampleFrameListener,另一个我们也刚学过KeyListener。

      好吧,开始。

      首先我们声明一个宏,#define CAMERA_NAME "SceneCamera" ,这是我们要使用的摄像机常量,下面要多次使用。

      然后我们定义两个全局函数,

    void setupViewport(RenderWindow *win, SceneManager *curr)
    {
      win->removeAllViewports();//移除所有视口
      Camera *cam = curr>getCamera(CAMERA_NAME);//获取摄像机
      Viewport *vp = win->addViewport(cam);//绑定视口到摄像机
      vp>setBackgroundColour(ColourValue(0,0,0));//设置背景色
      cam->setAspectRatio(Real(vp>getActualWidth()) / Real(vp->getActualHeight()));//设置纵宽比
    }
    
    void dualViewport(RenderWindow *win, SceneManager *primary,SceneManager *secondary)
    {
      win->removeAllViewports();//移除所有视口
      Viewport *vp = 0;
      Camera *cam = primary->getCamera(CAMERA_NAME);//第一个摄像机
      vp = win->addViewport(cam, 0, 0, 0, 0.5, 1);
      vp>setBackgroundColour(ColourValue(0,0,0));//
      cam->setAspectRatio(Real(vp>getActualWidth()) / Real(vp>getActualHeight()));
      cam = secondary>getCamera(CAMERA_NAME);//第二个摄像机
      vp = win->addViewport(cam, 1, 0.5, 0, 0.5, 1);//
      vp>setBackgroundColour(ColourValue(0,0,0));//
      cam->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));//设置纵宽比
    }

    其中的addViewport的函数定义如下:

      virtual Viewport* addViewport(Camera* cam//摄像机

                     , int ZOrder = 0//窗口重叠的优先级,越大越靠上

                     , float left = 0.0f//左边相对位置

                     , float top = 0.0f//上面相对位置

                     ,float width = 1.0f//宽度

                      , float height = 1.0f);//高度

      最后我们改变类内的函数

      第一,我们把要用到的函数添加进去,在监听器内有

    bool frameStarted(const FrameEvent& evt){}
    bool keyPressed(const OIS::KeyEvent &arg){}
    bool keyReleased(const OIS::KeyEvent &) {}
    static void swap(SceneManager *&first, SceneManager *&second){}//静态成员函数,交换两个场景

      在应用程序类中有

    void chooseSceneManager(void){}//创建场景管理器
    void createCamera(){}//创建摄像机
    void createViewports(){}//创建视口
    void createScene(void){}//创建场景
    void createFrameListener(void){}//创建帧监听器

      第二,我们添加具体代码到函数体中,

      在每一帧的开始我们要捕获键盘状态

    bool frameStarted(const FrameEvent& evt)
    {
      mKeyboard->capture();//捕获键盘
      return mContinue;
    }

      在键盘按下时,我们要响应动作,切换场景,或者切换显示方式,一个场景,还是两个场景

    bool keyPressed(const OIS::KeyEvent &arg)
    {
        switch (arg.key)
        {
            case OIS::KC_ESCAPE://按下esc时退出程序
              mContinue = false;
            break;
         case OIS::KC_V://按下v时,显示两个场景
            mDual = !mDual;//取反
            if (mDual)//
            dualViewport(mWindow, mPrimary, mSecondary);//显示两个视口
            else
            setupViewport(mWindow, mPrimary);//重新设置视口,默认为第一个
          break;
          case OIS::KC_C://按下c时,切换两个场景,并且
            swap(mPrimary, mSecondary);//交换场景管理器
            if (mDual)//
            dualViewport(mWindow, mPrimary,mSecondary);
            else
            setupViewport(mWindow, mPrimary);//
          break;
           default:
            break;
        }
        return true;
    }

       在应用程序类中创建场景,摄像机,视口等...

    void chooseSceneManager(void)
    {
        mPrimary = mRoot>createSceneManager(ST_GENERIC,"primary");
       mSecondary = mRoot>createSceneManager(ST_GENERIC,"secondary");
    }
    void createCamera()
    {
        mPrimary->createCamera(CAMERA_NAME);//摄像机1
        mSecondary->createCamera(CAMERA_NAME);//摄像机2
    }
    void createViewports()
    {
        setupViewport(mWindow, mPrimary);
    }
    void createScene(void)
    {
      // Setup the TerrainSceneManager
      mPrimary->setSkyBox(true,"Examples/SpaceSkyBox");//创建天空盒
      // Setup the Generic SceneManager
      mSecondary->setSkyDome(true,"Examples/CloudySky", 5, 8);//创建天空穹
    }
    void createFrameListener(void)
    {
      //注册帧监听
      mFrameListener = new SMTutorialListener(mWindow, mPrimary,mSecondary);
      mFrameListener->showDebugOverlay(true);
      mRoot->addFrameListener(mFrameListener);
    }

      好了,现在可以运行了,按下c可以在两个场景中随意切换,或者按下V键,显示两个视口在程序中。

  • 相关阅读:
    POJ1064 Cable master(二分 浮点误差)
    Codeforces1113F. Sasha and Interesting Fact from Graph Theory(组合数学 计数 广义Cayley定理)
    Codeforces1100F. Ivan and Burgers(离线+线性基)
    Codeforces1097D. Makoto and a Blackboard(数论+dp+概率期望)
    Codeforces1099F. Cookies(线段树+dp+贪心+博弈)
    python-zx笔记4-文件操作
    python-zx笔记3-函数
    python-zx笔记2-help
    fiddler使用笔记1
    理解OAuth 2.0
  • 原文地址:https://www.cnblogs.com/songliquan/p/3311380.html
Copyright © 2020-2023  润新知