osgfbo(六)从pass的角度考虑,改写fbo(二)

什么是pass,这个问题,看似简单,也让我头疼。看了osgdefered,pass定义为osg::Camera。杨石兴的osg视频教程定义为osg::Group。

我认为一个passRoot可以定义为一个Group,包含三部分:到目前pass为止的所有摄像机,geode,texture。只要通过viewer->setSceneData(passRoot)就可以看到该pass的内容。
1,摄像机。
摄像机分为采样摄像机,中间处理摄像机,以及最后呈现的摄像机。
摄像机之间如何传递,众说纷纭。osg自带例子上只有采样摄像机和最后呈现的摄像机,并没有中间摄像机,忽略了这步。
实际上,应该按采样顺序和处理顺序依次加载摄像机。

2,geode
geode只是一个空板,被camera->addchild()用来呈现物体。在以前的例子里,是将shader写到geode->getorcreateStateset(),是不科学的,实际上,应该写到camera->getOrCreateStateset()
视频教程上,camera->addchild(上个passRoot)这个方法不科学,因为会导致屏幕死掉,还要额外加上eventhandler
3,texture
这个是承上启下的过程。渲染到纹理,最主要的是传递纹理,而不是传递上个passroot

摄像机通过attach()输出纹理,setTextureAttributeAndModes()处理输入纹理。

先简单改写下
osgfbo(二)中的内容,改写不多,但是思路完全不同。

//final
osg::ref_ptr<osg::Camera> finalCamera = new osg::Camera;
{
	osg::ref_ptr<osg::StateSet> ss = finalCamera->getOrCreateStateSet();
	ss->setTextureAttributeAndModes(0, tex);
	ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF); //设置不受光照影响,不然太暗了就看不清楚
	osg::ref_ptr<osg::Geode> panelGeode = createTexturePanelGeode();
	finalCamera->addChild(panelGeode);
	finalCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
}

passRoot->addChild(sampleCamera); //将摄像机加入场景
passRoot->addChild(finalCamera);
viewer->setSceneData(passRoot);

所有代码如下:

#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osg/CoordinateSystemNode>

#include <osg/Switch>
#include <osg/Types>
#include <osgText/Text>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgGA/SphericalManipulator>

#include <osgGA/Device>
#include <osg/Shader>

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<osg::Vec2Array> 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<osg::Geometry> geom = new osg::Geometry;
geom->setVertexArray(vertices);
geom->setTexCoordArray(0, texCoord);
geom->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));

osg::ref_ptr<osg::Geode> geode = new osg::Geode;
geode->addDrawable(geom);
return geode;

}

int main()
{
osg::ref_ptrosgViewer::Viewer viewer = new osgViewer::Viewer;
std::string strFileName = “D:/OpenSceneGraph-master/OpenSceneGraph-Data-master/cow.osg”;
//各个pass的根
osg::ref_ptrosg::Group passRoot = new osg::Group();
//场景根
osg::ref_ptrosg::Group sceneRoot = new osg::Group();
osg::ref_ptrosg::Node node = osgDB::readNodeFile(strFileName);
sceneRoot->addChild(node);

//获取系统分辨率
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<osg::Texture2D> tex = createFloatRectangleTexture(texWidth, texHeight);
//绑定pass1采样摄像机
osg::ref_ptr<osg::Camera> sampleCamera = new osg::Camera;
{
	sampleCamera->addChild(sceneRoot);
	sampleCamera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
	sampleCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); //这句话使内容不渲染到屏幕上
	sampleCamera->attach(osg::Camera::COLOR_BUFFER0, tex); //关联采样贴图
	sampleCamera->setViewport(0, 0, screenWidth, screenHeight);//摄像机关联视口

}

//final
osg::ref_ptr<osg::Camera> finalCamera = new osg::Camera;
{
	osg::ref_ptr<osg::StateSet> ss = finalCamera->getOrCreateStateSet();
	ss->setTextureAttributeAndModes(0, tex);
	ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF); //设置不受光照影响,不然太暗了就看不清楚
	osg::ref_ptr<osg::Geode> panelGeode = createTexturePanelGeode();
	finalCamera->addChild(panelGeode);
	finalCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
}

passRoot->addChild(sampleCamera); //将摄像机加入场景
passRoot->addChild(finalCamera);
viewer->setSceneData(passRoot);
viewer->run();
return 0;

}

猜你喜欢

转载自blog.csdn.net/directx3d_beginner/article/details/129829052