1。设置背景
#include <osg/Group>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osg/Camera>
#include <osg/Texture2D>
#include <iostream>
/*
方法:
HUD中的相机设置渲染顺序为PRE_RENDER,主相机清除深度缓存.
*/
osg::Camera* createHUDBg(std::string imagePath){
osg::ref_ptr<osg::Camera>camera=new osg::Camera;
camera->setProjectionMatrixAsOrtho2D(0, 800, 0, 600);
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setRenderOrder(osg::Camera::PRE_RENDER);
camera->setViewport(0,0,1300,800);
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
camera->setAllowEventFocus(false);
camera->setViewMatrix(osg::Matrix::identity());
osg::ref_ptr<osg::Geode>geode=new osg::Geode;
geode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
osg::ref_ptr<osg::Geometry>gm=new osg::Geometry;
//亚入顶点
osg::ref_ptr<osg::Vec3Array>vertex=new osg::Vec3Array;
vertex->push_back(osg::Vec3(0,0,0));
vertex->push_back(osg::Vec3(800,0,0));
vertex->push_back(osg::Vec3(800,600,0));
vertex->push_back(osg::Vec3(0,600,0));
gm->setVertexArray(vertex);
//压入法线
//纹理坐标
osg::ref_ptr<osg::Vec2Array>coord=new osg::Vec2Array;
coord->push_back(osg::Vec2(0,0));
coord->push_back(osg::Vec2(1,0));
coord->push_back(osg::Vec2(1,1));
coord->push_back(osg::Vec2(0,1));
gm->setTexCoordArray(0, coord);
gm->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
osg::ref_ptr<osg::Image>image=osgDB::readImageFile(imagePath);
if(!image.valid()){
// std::cout<"read image faild "<<std::endl;
return camera.release();
}
// osg::ref_ptr<osg::Texture2D>t2d=new osg::Texture2D;
osg::Texture2D*t2d=new osg::Texture2D;
t2d->setImage(0,image);
gm->getOrCreateStateSet()->setTextureAttributeAndModes(0, t2d,osg::StateAttribute::ON);
geode->addDrawable(gm);
camera->addChild(geode);
return camera.release();
}
int main(int argc, char *argv[])
{
osg::ref_ptr<osgViewer::Viewer>viewer=new osgViewer::Viewer;
viewer->getCamera()->setClearMask(GL_DEPTH_BUFFER_BIT);
osg::ref_ptr<osg::Group>root=new osg::Group;
root->addChild(osgDB::readNodeFile("cow.osg"));
root->addChild(createHUDBg("Images/skymap.jpg"));
viewer->setSceneData(root.get());
return viewer->run();
}
这个不能随着屏幕的缩放而缩放,当然解决办法有很多
前景,挺玄的,呵呵
#include <osg/Group>
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osg/Camera>
#include <osg/Texture2D>
#include <iostream>
/*
前景方法:
HUD中的相机设置渲染顺序为POST_RENDER,主相机不清除深度缓存.
*/
osg::Camera* createHUDBg(std::string imagePath){
osg::ref_ptr<osg::Camera>camera=new osg::Camera;
camera->setProjectionMatrixAsOrtho2D(0, 800, 0, 600);
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setRenderOrder(osg::Camera::POST_RENDER);
camera->setViewport(0,0,1300,800);
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
camera->setAllowEventFocus(false);
camera->setViewMatrix(osg::Matrix::identity());
osg::ref_ptr<osg::Geode>geode=new osg::Geode;
geode->getOrCreateStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
geode->getOrCreateStateSet()->setMode(GL_BLEND,osg::StateAttribute::ON);
osg::ref_ptr<osg::Geometry>gm=new osg::Geometry;
//亚入顶点
osg::ref_ptr<osg::Vec3Array>vertex=new osg::Vec3Array;
vertex->push_back(osg::Vec3(0,0,0));
vertex->push_back(osg::Vec3(800,0,0));
vertex->push_back(osg::Vec3(800,600,0));
vertex->push_back(osg::Vec3(0,600,0));
gm->setVertexArray(vertex);
//压入法线
//纹理坐标
osg::ref_ptr<osg::Vec2Array>coord=new osg::Vec2Array;
coord->push_back(osg::Vec2(0,0));
coord->push_back(osg::Vec2(1,0));
coord->push_back(osg::Vec2(1,1));
coord->push_back(osg::Vec2(0,1));
gm->setTexCoordArray(0, coord);
gm->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4));
osg::ref_ptr<osg::Image>image=osgDB::readImageFile(imagePath);
if(!image.valid()){
// std::cout<"read image faild "<<std::endl;
return camera.release();
}
// osg::ref_ptr<osg::Texture2D>t2d=new osg::Texture2D;
osg::Texture2D*t2d=new osg::Texture2D;
t2d->setImage(0,image);
gm->getOrCreateStateSet()->setTextureAttributeAndModes(0, t2d,osg::StateAttribute::ON);
geode->addDrawable(gm);
camera->addChild(geode);
return camera.release();
}
int main(int argc, char *argv[])
{
osg::ref_ptr<osgViewer::Viewer>viewer=new osgViewer::Viewer;
// viewer->getCamera()->setClearMask(GL_DEPTH_BUFFER_BIT);
osg::ref_ptr<osg::Group>root=new osg::Group;
root->addChild(osgDB::readNodeFile("cow.osg"));
root->addChild(createHUDBg("Images/smoke.rgb"));
viewer->setSceneData(root.get());
return viewer->run();
}
OSG 背景设置 (摘自王锐的cookbook)
#include <osg/Geometry>
#include <osg/Geode>
#include <osg/Depth>
#include <osg/Texture2D>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
int main( int argc, char** argv )
{
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
osg::ref_ptr<osg::Image> image = osgDB::readImageFile( "D:/background1.png" );
texture->setImage( image.get() );
osg::ref_ptr<osg::Drawable> quad = osg::createTexturedQuadGeometry(osg::Vec3(), osg::Vec3(1.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 1.0f, 0.0f) );
quad->getOrCreateStateSet()->setTextureAttributeAndModes( 0,texture.get());
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable( quad.get() );
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setClearMask( 0 );
camera->setCullingActive( false );
camera->setAllowEventFocus( false );
camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
camera->setRenderOrder( osg::Camera::POST_RENDER );
camera->setProjectionMatrix( osg::Matrix::ortho2D(0.0, 1.0, 0.0, 1.0) );
camera->addChild( geode.get() );
osg::StateSet* ss = camera->getOrCreateStateSet();
ss->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
ss->setAttributeAndModes( new osg::Depth(osg::Depth::LEQUAL, 1.0, 1.0) );
osg::ref_ptr<osg::Group> root = new osg::Group;
root->addChild( camera.get() );
root->addChild( osgDB::readNodeFile("cessna.osg") );
osgViewer::Viewer viewer;
viewer.setSceneData( root.get() );
return viewer.run();
}
上面的关键地方 就在
setAttributeAndModes( new osg::Depth(osg::Depth::LEQUAL,1.0, 1.0) ); 这句话,
重新映射背景节点的深度值为1-1 ,这样就确保了每个后渲染(post-rendered)背景的深度值是1,osg::Depth::LEQUAL 确保除非原始深度缓存的值为1才会渲染上背景,否则此地方背景不会被渲染。
那么什么时候,原始缓存的深度值为1 ? 答案是:深度缓存在初始化的时候都是1,当有像素绘制后,此像素对应的深度缓存就不为1,也就是说所有没有被渲染的地方都是1. 这样没被渲染的地方,在post-rendered 的时候就渲染了背景色。确保原有模型像素点不被覆盖。