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键,显示两个视口在程序中。

原文地址:https://www.cnblogs.com/songliquan/p/3311380.html