查看: 1395|回复: 4

请教两视口程序

[复制链接]

该用户从未签到

发表于 2010-12-30 11:32:59 | 显示全部楼层 |阅读模式
本帖最后由 zhoujiajun2010 于 2010-12-30 11:41 编辑

#include <osgViewer/Viewer>
#include <osgViewer/View>
#include <osgViewer/ViewerEventHandlers>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Geometry>
#include <osg/MatrixTransform>
#include <osg/PositionAttitudeTransform>
#include <osg/Camera>
#include <osgViewer/CompositeViewer>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgUtil/Optimizer>
#include <osgGA/TrackballManipulator>
#include <iostream>

       struct updateAccumlatedMatrix : public osg::NodeCallback
     {
        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
        {
           matrix = osg::computeWorldToLocal(nv->getNodePath() );
           traverse(node,nv);
        }
        osg::Matrix matrix;
     };     
  struct transformAccumulator
     {
     public:   
        transformAccumulator();
        bool attachToGroup(osg::Group* g);
        osg::Matrix getMatrix();
     protected:
        osg::ref_ptr<osg::Group> parent;
        osg::Node* node;
        updateAccumlatedMatrix* mpcb;
     };

    // 类的实现代码如下所示:

     transformAccumulator::transformAccumulator()
     {
        parent = NULL;
        node = new osg::Node;
        mpcb = new updateAccumlatedMatrix();
        node->setUpdateCallback(mpcb);
     }

     osg::Matrix transformAccumulator::getMatrix()
     {
        return mpcb->matrix;
     }
    bool transformAccumulator::attachToGroup(osg::Group* g)
       //  注意不要在回调中调用这个函数。
     {
        bool success = false;
        if (parent != NULL)
        {
           int n = parent->getNumChildren();
           for (int i = 0; i < n; i++)
           {
              if (node == parent->getChild(i) )
              {
                 parent->removeChild(i,1);
                 success = true;
              }
           }
           if (! success)
           {
              return success;
           }
        }
        g->addChild(node);
        return true;
     };

      class followNodeMatrixManipulator : public osgGA::MatrixManipulator
     {
     public:
        followNodeMatrixManipulator( transformAccumulator* ta);   
        bool handle (const osgGA::GUIEventAdapter&ea, osgGA::GUIActionAdapter&aa);
        void updateTheMatrix();
        virtual void setByMatrix(const osg::Matrixd& mat) {theMatrix = mat;}
        virtual void setByInverseMatrix(const osg::Matrixd&mat) {}
        virtual osg::Matrixd getInverseMatrix() const;
        virtual osg::Matrixd getMatrix() const;
     protected:
        ~followNodeMatrixManipulator() {}
        transformAccumulator* worldCoordinatesOfNode;
        osg::Matrixd theMatrix;
     };

     followNodeMatrixManipulator::followNodeMatrixManipulator( transformAccumulator* ta)
     {
        worldCoordinatesOfNode = ta; theMatrix = osg::Matrixd::identity();
     }
     void followNodeMatrixManipulator::updateTheMatrix()
     {
        theMatrix = worldCoordinatesOfNode->getMatrix();
     }
     osg::Matrixd followNodeMatrixManipulator::getMatrix() const
     {
        return theMatrix;
     }
     osg::Matrixd followNodeMatrixManipulator::getInverseMatrix() const
     {
     //  将矩阵从 Y轴向上旋转到Z 轴向上
        osg::Matrixd m;
        m = theMatrix * osg::Matrixd::rotate(-3.1415926/2.0, osg::Vec3(1,0,0) );
        return m;
     }
      
     bool followNodeMatrixManipulator::handle
     (const osgGA::GUIEventAdapter&ea, osgGA::GUIActionAdapter&aa)
     {
        switch(ea.getEventType())
        {
           case (osgGA::GUIEventAdapter::FRAME):
           {
              updateTheMatrix();
              return false;
           }
        }
        return false;
     }


void createView (osgViewer::CompositeViewer *viewer,

   osg::ref_ptr<osg::Group> scene,

    osg::ref_ptr<osg::GraphicsContext> gc,

   osgGA::TrackballManipulator* Tman,

   int x, int y, int width, int height)

   {
     
   double left,right,top,bottom,near,far, aspectratio;

   double frusht, fruswid, fudge;

   bool gotfrustum = true;

   

   //  向最终的组合视口添加一个新的视口,并设置其操控方式。
    osgViewer::View* view = new osgViewer::View;

   viewer->addView(view);

   view->setCameraManipulator(Tman);

  //  设置视口的场景数据,并设置摄像机的截锥坐标。

   view->setSceneData(scene.get());

   view->getCamera()->setViewport(new osg::Viewport(x,y, width,height));

   view->getCamera()-> getProjectionMatrixAsFrustum(left,right,

   bottom,top,
   
   near,far);

   if (gotfrustum)   

   {

   aspectratio = (double) width/ (double) height;

   frusht = top - bottom;

   fruswid = right - left;

   fudge = frusht*aspectratio/fruswid;
   
   right = right*fudge;

   left = left*fudge;

   view->getCamera()-> setProjectionMatrixAsFrustum(left,right,bottom,top,near,far);

   }

   view->getCamera()->setGraphicsContext(gc.get());

  //  添加渲染状态控制器
   osg::ref_ptr<osg::StateSet> statesetManipulator = new osg::StateSet();
   statesetManipulator=view->getCamera()->getOrCreateStateSet();
  // statesetManipulator->setStateSet(view->getCamera()->getOrCreateStateSet());

   //view->addEventHandler( statesetManipulator.get() );

   }
int main( int argc, char **argv )

   {

   //  场景根节点和坦克模型节点指针。

   osg::ref_ptr<osg::Group> rootNode;   

   osg::ref_ptr<osg::Group> ownTank;

   

   osgGA::TrackballManipulator *Tman1 = new osgGA::TrackballManipulator();

   osgGA::TrackballManipulator *Tman2 = new osgGA::TrackballManipulator();
   
  //  建立场景和坦克。

  // if (!setupScene(rootNode, ownTank))

//  {

  // std::cout<< "problem setting up scene" << std::endl;

  // return -1;

  // }

  //  声明一个位于坦克偏后上方的位移变换节点。将其添加到坦克节点。
    osg:ositionAttitudeTransform * followerOffset = new osg::PositionAttitudeTransform();
   followerOffset->setPosition( osg::Vec3(0.0,-25.0,10) );

   followerOffset->setAttitude( osg:uat( osg:egreesToRadians(-15.0), osg::Vec3(1,0,0) ) );

   ownTank.get()->addChild(followerOffset);

  //  声明一个自定义的位移累加器类,以便放置相机。将其关联给上面的变换节点。
//
   transformAccumulator*tankFollowerWorldCoords = new transformAccumulator();

   tankFollowerWorldCoords->attachToGroup(followerOffset);

  //  构建视口类,以及与其相关的图形设备类。

   osgViewer::CompositeViewer viewer;
   
   osg::GraphicsContext::WindowingSystemInterface* wsi =osg::GraphicsContext::getWindowingSystemInterface();

   if (!wsi)   

   {

   osg::notify(osg::NOTICE)

   <<"Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
   
   return 1;

   }

  unsigned int width, height;

   wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height);

  osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;

   traits->x = 100;

   traits->y = 100;

   traits->width = width;
   traits->height = height;

   traits->windowDecoration = true;

   traits->doubleBuffer = true;

   traits->sharedContext = 0;

  osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());

   if (gc.valid())

   {

   osg::notify(osg::INFO)<<"GraphicsWindow has been created successfully."<<std::endl;

  gc->setClearColor(osg::Vec4f(0.2f,0.2f,0.6f,1.0f));
   gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   }

   else

   {

   osg::notify(osg::NOTICE)<<"    GraphicsWindow has not been created successfully."<<std::endl;

   }

   

   //  第一个视口

   createView (&viewer,rootNode,gc,Tman1,0, 0, traits->width/2, traits->height);
     //  第二个视口

   createView (&viewer,rootNode,gc,Tman2,traits->width/2, 0, traits->width/2, traits->height);

   viewer.setThreadingModel(osgViewer::CompositeViewer::SingleThreaded);
     while( !viewer.done() )

   //{

   //  获取跟踪摄像机的句柄。使用相应的方法设置坦克跟踪相机的世界坐标位置矩阵。

   //  注意该矩阵需要从 Y轴向上旋转到Z 轴向上的坐标系。

   Tman2->setByInverseMatrix(tankFollowerWorldCoords->getMatrix() *osg::Matrix::rotate( osg::PI_2*3, osg::Vec3(1.0, 0.0, 0.0 )));

  viewer.frame();

   //}

  return 0;

   }




不知什么原因,编译可以,但是老是执行不了,请高手指点,非常感谢

该用户从未签到

发表于 2010-12-30 15:52:21 | 显示全部楼层
请您参考osgwindow这个示例程序~~~~

该用户从未签到

发表于 2011-3-4 15:35:27 | 显示全部楼层


  1.     bool transformAccumulator::attachToGroup(osg::Group* g)
  2.     // 注意不要在回调中调用这个函数。
  3.     {
  4.        bool success = false;
  5.        if (parent != NULL)
  6.        {
  7.           int n = parent->getNumChildren();
  8.           for (int i = 0; i < n; i++)
  9.           {
  10.              if (node == parent->getChild(i) )
  11.              {
  12.                 parent->removeChild(i,1);
  13.                 success = true;
  14.              }
  15.           }
  16.           if (! success)
  17.           {
  18.              return success;
  19.           }
  20.        }
  21.        g->addChild(node);
  22.        return true;
  23.     }

复制代码
这里的parent是不是没起到什么作用啊?没有赋值,一直就是NULL

该用户从未签到

发表于 2011-3-5 18:31:17 | 显示全部楼层
自己顶一个

该用户从未签到

发表于 2011-3-7 08:49:53 | 显示全部楼层
我认为您应该更详细地自己调试之后再在这里提问,现在您只是给出一大段程序然后说执行不了……这样很难让人有深入研究和讨论问题的欲望……
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表