/*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();
}