osg 导航图 HUD RTT

本文详细介绍了如何将HUD(Heads-Up Display)和RTT(Real-Time Texture)相结合,实现实时图像处理的功能。通过创建纹理、设置相机参数、烘焙纹理等步骤,实现了图像的实时渲染和展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/*HUD 和 RTT 的结合*/
#include <osg/Group>
#include <osg/Camera>
#include <osgDB/ReadFile>
#include <osg/Geometry>
#include <osg/Image>
#include <osg/ShapeDrawable>
#include <osg/Texture2D>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osg/MatrixTransform>
#include <osgGA/DriveManipulator>
#include <iostream>
using namespace std;


class CameraUpdateCallBack:public osg::NodeCallback
{
public:
  CameraUpdateCallBack(osg::MatrixTransform*mat): _eye(0.0f,0,0)
    {
      _mat=mat;
    }

  virtual ~CameraUpdateCallBack(){
    
  }
  virtual void operator()(osg::Node*node,osg::NodeVisitor*nv){
  osg::Camera*camera = dynamic_cast<osg::Camera*>(node);
    if(camera){
//      if(camera->getName().compare("MasterCamera")==0){
        osg::Vec3 eye,center,up;
        double left,right,bottom,top,znear,zfar;
        camera->getViewMatrixAsLookAt(eye, center, up);
        camera->getProjectionMatrixAsOrtho(left, right, bottom, top, znear, zfar);

        _eye=eye;//记录相机坐标
//可以通过这种方法为烘培相机找到合适的视点
        cout<<"eye= "<<eye.x()<<" , "<<eye.y()<<" , "<<eye.z()<<endl;
        cout<<"up= "<<up.x()<<" , "<<up.y()<<" , "<<up.z()<<endl;
        cout<<"center= "<<center.x()<<" , "<<center.y()<<" , "<<center.z()<<endl;
        cout<< left<<","<<right<<" , "<<bottom<<" , "<<top<<" , "<<znear<<" , "<<zfar<<endl;

        //    }
    }
//    osg::MatrixTransform*mat=dynamic_cast<osg::MatrixTransform*>(node);
    if(_mat){
      osg::Matrix mm=_mat->getMatrix();
      osg::Vec3 _eyeTmp=mm.getTrans();
      mm.makeTranslate(_eyeTmp);
     _mat->setMatrix(mm);
      cout<<"-------------------"<<endl;
      osg::Matrix m;
      m.makeTranslate(_eye);
      _mat->setMatrix(m);
    }
    traverse(node, nv);
  }
private:
  osg::Vec3 _eye;
  osg::MatrixTransform *_mat;

};

osg::Node *createNode(osg::Texture2D*t2d){
  osg::ref_ptr<osg::Geode>geode=new osg::Geode;
  osg::StateSet *ss=geode->getOrCreateStateSet();
  ss->setMode(GL_BLEND,osg::StateAttribute::ON);
  ss->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
  ss->setTextureAttributeAndModes(0, t2d,osg::StateAttribute::ON);

  osg::ref_ptr<osg::ShapeDrawable>sd=new osg::ShapeDrawable(new osg::Box(osg::Vec3(200,200,0),400,400,0.1));
  sd->setColor(osg::Vec4(0.5,0.5,0.5,0.8));
  geode->addDrawable(sd);

  return geode.release();
}
osg::Node *createRedPoint(){
  osg::ref_ptr<osg::Geode>geode=new osg::Geode;
  geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
  osg::TessellationHints *hints=new osg::TessellationHints;
  hints->setDetailRatio(1.0);
  osg::ref_ptr<osg::ShapeDrawable>sd=new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(0,0,0),10,10),hints);
  sd->setColor(osg::Vec4(1,0,0,1));
  geode->addDrawable(sd.get());
  return geode.release();
}
//创建HUD
osg::Camera*createHUD(osg::Texture2D*t2d){
  osg::ref_ptr<osg::Camera>camera=new osg::Camera;
  camera->setViewMatrix(osg::Matrix::identity());
  camera->setAllowEventFocus(false);
  camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
//设置视口,就是相机投影到你显示器的哪个位置
  camera->setViewport(00, 00, 1366, 768);
//投影变换就是定义一个可视空间,可视空间以外的物体不会被绘制到屏幕上
//setProjectionMatrixAsOrtho2主要用于二维图像到二维屏幕上的投影,它负责把三维空间的XY平面投射到屏幕上
  camera->setProjectionMatrixAsOrtho2D(0, 1366, 0, 768);
  camera->setClearMask(GL_DEPTH_BUFFER_BIT);
  camera->setRenderOrder(osg::Camera::POST_RENDER);

  camera->addChild(createNode(t2d));//设置HUD的内容
  return camera.release();
}
//烘培纹理
void createRtt(osgViewer::Viewer*viewer){
  osg::ref_ptr<osg::Group>gp = new osg::Group;
  osg::ref_ptr<osg::Node>ceep=osgDB::readNodeFile("ceep.ive");
  gp->addChild(ceep);

  if(!viewer){
    return ;
  }
  osg::GraphicsContext::WindowingSystemInterface* wsi=osg::GraphicsContext::getWindowingSystemInterface();
  if(!wsi){
    cout<<"wsi is NULL"<<endl;
    return;
  }
  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=0;
  traits->y=0;
  traits->width=width;
  traits->height=height;
  traits->windowDecoration=false;
  traits->doubleBuffer=true;
  traits->sharedContext=0;

  osg::ref_ptr<osg::GraphicsContext>gc=osg::GraphicsContext::createGraphicsContext(traits);
  if(!gc.valid()){
    return;
  }
//创建主相机
  osg::ref_ptr<osg::Camera>master=new osg::Camera;
  master->setGraphicsContext(gc);
  master->setViewport(00, 0, width,height);
  master->setName("MasterCamera");
//找出合适的视点
//  master->setUpdateCallback(new CameraUpdateCallBack);

  viewer->addSlave(master);

//创建烘培相机
  osg::ref_ptr<osg::Camera>rttCamera=new osg::Camera;
  //  rttCamera->setProjectionMatrixAsOrtho(4.45625e-310,4.27284e-311 , -1.41226e-44 , 7.897e-314 , -1.4067e-44 , 6.74853e-260);
  rttCamera->setProjectionMatrixAsOrtho(-160,160,-100,100,500,500);
  
  osg::Vec3 eye(-34.9553 , 445.227 , 1970.24);
  osg::Vec3 center (-34.9516 , 445 , 1969.26);
  osg::Vec3 up(0,1,0);
  rttCamera->setViewMatrixAsLookAt(eye, center, up);
  rttCamera->setRenderOrder(osg::Camera::PRE_RENDER);
  rttCamera->setClearMask(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT);
  rttCamera->setAllowEventFocus(false);
  rttCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);

  rttCamera->addChild(ceep);//增加场景

  osg::ref_ptr<osg::MatrixTransform>mat=new osg::MatrixTransform;
  mat->addChild(createRedPoint());
  rttCamera->addChild(mat.get());//增加红点(只有烘培相机需要红点)

//把红点传进去--时时更新红点位置
  master->setUpdateCallback(new CameraUpdateCallBack(mat.get()));

  osg::Texture2D*t2d=new osg::Texture2D;
  t2d->setInternalFormat(GL_RGBA);
  rttCamera->attach(osg::Camera::COLOR_BUFFER, t2d);
//  viewer->addSlave(rttCamera);
  gp->addChild(rttCamera);
  gp->addChild(createHUD(t2d));

  viewer->setSceneData(gp);
  return;
}

int main(int argc, char *argv[])
{
  osg::ref_ptr<osgViewer::Viewer>viewer=new osgViewer::Viewer;
  createRtt(viewer);
  viewer->addEventHandler(new osgViewer::ScreenCaptureHandler);
//添加个漫游器
  viewer->setCameraManipulator(new osgGA::DriveManipulator());
  return viewer->run();
}


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值