osgFBO(十一):深度图

类似于颜色缓冲区采样纹理,深度缓冲区也可以通过采样摄像机进行
一,设置深度图纹理

osg::ref_ptrosg::Texture2D makeDepthTexture(int width, int height)
{
osg::ref_ptrosg::Texture2D depthTex = new osg::Texture2D;
depthTex->setTextureSize(width, height);
depthTex->setSourceFormat(GL_DEPTH_COMPONENT);
depthTex->setSourceType(GL_FLOAT);
depthTex->setInternalFormat(GL_DEPTH_COMPONENT24);
depthTex->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
depthTex->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
depthTex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
depthTex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
return depthTex;
}
//采样深度
osg::ref_ptrosg::Texture2D texDepth = makeDepthTexture(texWidth, texHeight);
二,将深度图纹理关联到深度缓冲区

	sampleCamera0->attach(osg::Camera::DEPTH_BUFFER, texDepth); //关联深度贴图

三,将深度图纹理传递到pass1Camera

	osg::ref_ptr<osg::StateSet> stateset = pass1Camera->getOrCreateStateSet();
	{
		stateset->setTextureAttributeAndModes(0, texDepth);
	}
四,从shader中采样深度图
osg::ref_ptr<osg::Uniform> texDepthUniform = new osg::Uniform("texDepth", 0); 
stateset->addUniform(texDepthUniform);

static const char* psShader =
{
“varying vec2 outTexCoord;”
“uniform sampler2D texDepth;”
“void main(void)\n”
“{\n”
“gl_FragColor = texture2D(texDepth,outTexCoord);”
“}\n”
};

运行结果

在这里插入图片描述

完整代码如下

#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>

#include <osg/Geometry>
#include <osg/Array>
#include <osg/primitiveset>

#include<osg/Geode>
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->setVertexAttribArray(1, texCoord, osg::Array::BIND_PER_VERTEX);
//geom->setTexCoordArray(0, texCoord);
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));

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

}

osg::ref_ptrosg::Texture2D makeDepthTexture(int width, int height)
{
osg::ref_ptrosg::Texture2D depthTex = new osg::Texture2D;
depthTex->setTextureSize(width, height);
depthTex->setSourceFormat(GL_DEPTH_COMPONENT);
depthTex->setSourceType(GL_FLOAT);
depthTex->setInternalFormat(GL_DEPTH_COMPONENT24);
depthTex->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
depthTex->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
depthTex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
depthTex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
return depthTex;
}
static const char* vertexShader =
{
“in vec2 texCoord;\n”
“varying vec2 outTexCoord;”
“void main(void)\n”
“{\n”
“outTexCoord = texCoord;\n”
" gl_Position = ftransform();\n"
“}\n”
};
#if 0
static const char* psShader =
{
“varying vec2 outTexCoord;”
“uniform sampler2D tex0;”
“uniform sampler2D texDepth;”
“void main(void)\n”
“{\n”
“gl_FragColor = texture2D(tex0,outTexCoord) + texture2D(texDepth,outTexCoord);”
“}\n”
};
#endif

static const char* psShader =
{
“varying vec2 outTexCoord;”
“uniform sampler2D texDepth;”
“void main(void)\n”
“{\n”
“gl_FragColor = texture2D(texDepth,outTexCoord);”
“}\n”
};

int main()
{
osg::ref_ptrosgViewer::Viewer viewer = new osgViewer::Viewer;
//场景根
osg::ref_ptrosg::Group sceneRoot = new osg::Group();
std::string strFileName = “D:/tutorial/OpenSceneGraph-Data-3.0.0/cow.osg”;
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_ptrosg::Texture2D tex0 = createFloatRectangleTexture(texWidth, texHeight);
//采样深度
osg::ref_ptrosg::Texture2D texDepth = makeDepthTexture(texWidth, texHeight);
//绑定采样摄像机1
osg::ref_ptrosg::Camera sampleCamera0 = new osg::Camera;
//pass1Camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
//sampleCamera0->setRenderOrder(osg::Camera::RenderOrder::PRE_RENDER);
{
sampleCamera0->addChild(sceneRoot);
sampleCamera0->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
sampleCamera0->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); //这句话使内容不渲染到屏幕上
sampleCamera0->attach(osg::Camera::COLOR_BUFFER0, tex0); //关联采样贴图
sampleCamera0->attach(osg::Camera::DEPTH_BUFFER, texDepth); //关联深度贴图
sampleCamera0->setViewport(0, 0, texWidth, texHeight);//摄像机视口投影到纹理大小

}

//pass1摄像机
osg::ref_ptr<osg::Camera> pass1Camera = new osg::Camera;
pass1Camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
//pass1Camera->setRenderOrder(osg::Camera::RenderOrder::PRE_RENDER);
{
	{
		osg::ref_ptr<osg::Geode> panelGeode_pass1 = createTexturePanelGeode();
		pass1Camera->addChild(panelGeode_pass1);

	}

	osg::ref_ptr<osg::StateSet> stateset = pass1Camera->getOrCreateStateSet();
	{
		//stateset->setTextureAttributeAndModes(0, tex0);
		//stateset->setTextureAttributeAndModes(1, texDepth);
		stateset->setTextureAttributeAndModes(0, texDepth);
	}

	{
		//对场景进行处理
		osg::ref_ptr<osg::Shader> vs1 = new osg::Shader(osg::Shader::VERTEX, vertexShader);
		osg::ref_ptr<osg::Shader> ps1 = new osg::Shader(osg::Shader::FRAGMENT, psShader);
		osg::ref_ptr<osg::Program> program1 = new osg::Program;
		program1->addShader(vs1);
		program1->addShader(ps1);
		program1->addBindAttribLocation("texCoord", 1);
		//osg::ref_ptr<osg::Uniform> tex0Uniform = new osg::Uniform("tex0", 0);
		//osg::ref_ptr<osg::Uniform> texDepthUniform = new osg::Uniform("texDepth", 1);
		//stateset->addUniform(tex0Uniform);
		//stateset->addUniform(texDepthUniform);

		osg::ref_ptr<osg::Uniform> texDepthUniform = new osg::Uniform("texDepth", 0); 
		stateset->addUniform(texDepthUniform);
		stateset->setAttribute(program1, osg::StateAttribute::ON);
	}
}


osg::ref_ptr<osg::Group> pass1Root = new osg::Group;
pass1Root->addChild(sampleCamera0);
pass1Root->addChild(pass1Camera);

viewer->setSceneData(pass1Root);
viewer->run();
return 0;

}

猜你喜欢

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