从osg的例子上,可以看到,文字一般是写入hud的,那么,能不能写入fbo呢?
答案是肯定的。
回想一下hud文字,无非是把文字当作场景根,再加了一个正交投影的摄像机罢了。所以,只要把postRender改为prerender即可。
废话不多说,上代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
osg::ref_ptrosg::Texture2D createFloatRectangleTexture(int width, int height)
{
osg::ref_ptrosg::Texture2D tex2D = new osg::Texture2D;
tex2D->setTextureSize(width, height);
tex2D->setInternalFormat(GL_RGBA16F_ARB);
tex2D->setSourceFormat(GL_RGBA);
tex2D->setSourceType(GL_FLOAT);
return tex2D.release();
}
osg::ref_ptrosg::Geode createTexturePanelGeode()
{
osg::ref_ptrosg::Vec3Array vertices = new osg::Vec3Array;
vertices->push_back(osg::Vec3(-1.0f, -1.0f, 0.0f));
vertices->push_back(osg::Vec3(1.0f, -1.0f, 0.0f));
vertices->push_back(osg::Vec3(1.0f, 1.0f, 0.0f));
vertices->push_back(osg::Vec3(-1.0f, 1.0f, 0.0f));
osg::ref_ptr texCoord = new osg::Vec2Array;
texCoord->push_back(osg::Vec2(0.0, 0.0));
texCoord->push_back(osg::Vec2(1.0, 0.0));
texCoord->push_back(osg::Vec2(1.0, 1.0));
texCoord->push_back(osg::Vec2(0.0, 1.0));
osg::ref_ptr geom = new osg::Geometry;
geom->setVertexArray(vertices);
geom->setTexCoordArray(0, texCoord);
geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
osg::ref_ptr geode = new osg::Geode;
geode->addDrawable(geom);
return geode;
}
osg::ref_ptrosg::Geode CreateTextGeode()
{
osg::ref_ptrosg::Geode geode = new osg::Geode;
std::string strFont(“fonts/arial.ttf”);
osg::ref_ptrosgText::Text hudText = new osgText::Text;
geode->addDrawable(hudText);
hudText->setDataVariance(osg::Object::DYNAMIC);
//hudText->setFont(strFont);
hudText->setText(“Head up position”);
hudText->setCharacterSize(20.0);
hudText->setPosition(osg::Vec3(500, 300, 0));
hudText->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0));
return geode;
}
osg::Camera* CreateHUDCamera(double left, double right, double bottom, double top)
{
osg::ref_ptrosg::Camera camera = new osg::Camera;
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
//camera->setRenderOrder(osg::Camera::POST_RENDER);
camera->setAllowEventFocus(false);
camera->setProjectionMatrix(osg::Matrix::ortho2D(left, right, bottom, top));
camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
return camera.release();
}
int main()
{
//获取系统分辨率
unsigned int screenWidth, screenHeight;
osg::GraphicsContext::WindowingSystemInterface * wsInterface = osg::GraphicsContext::getWindowingSystemInterface();
if (!wsInterface)
{
return -1;
}
wsInterface->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), screenWidth, screenHeight);
int texWidth = screenWidth;
int texHeight = screenHeight;
osg::ref_ptr viewer = new osgViewer::Viewer;
osg::ref_ptr hudCamera = CreateHUDCamera(0, screenWidth, 0, screenHeight);
osg::ref_ptr tex0 = createFloatRectangleTexture(texWidth, texHeight);
{
osg::ref_ptr textGeode = CreateTextGeode();
hudCamera->setClearColor(osg::Vec4(0, 1, 0, 1));
hudCamera->addChild(textGeode);
hudCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); //这句话使内容不渲染到屏幕上
hudCamera->attach(osg::Camera::COLOR_BUFFER0, tex0); //关联采样贴图
hudCamera->setViewport(0, 0, screenWidth, screenHeight);//摄像机关联视口
}
//各个pass的根
osg::ref_ptr passRoot = new osg::Group();
osg::ref_ptr tex = createFloatRectangleTexture(texWidth, texHeight);
//绑定pass1采样摄像机
osg::ref_ptr sampleCamera = new osg::Camera;
{
osg::ref_ptr ss = sampleCamera->getOrCreateStateSet();
ss->setTextureAttributeAndModes(0, tex0);
ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF); //设置不受光照影响,不然太暗了就看不清楚
osg::ref_ptr panelGeode = createTexturePanelGeode();
sampleCamera->addChild(panelGeode);
sampleCamera->attach(osg::Camera::COLOR_BUFFER0, tex); //关联采样贴图
sampleCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
}
//final
osg::ref_ptr finalCamera = new osg::Camera;
//finalCamera->setRenderOrder(osg::Camera::PRE_RENDER, 8);
{
osg::ref_ptr ss = finalCamera->getOrCreateStateSet();
ss->setTextureAttributeAndModes(0, tex);
ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF); //设置不受光照影响,不然太暗了就看不清楚
osg::ref_ptr panelGeode = createTexturePanelGeode();
finalCamera->addChild(panelGeode);
finalCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
}
passRoot->addChild(hudCamera); //将摄像机加入场景
passRoot->addChild(sampleCamera); //将摄像机加入场景
passRoot->addChild(finalCamera);
viewer->setSceneData(passRoot);
viewer->run();
return 0;
}