Osgearth后期处理+多窗口显示

一、效果

左下角是原始画面,右上角是处理成灰度效果的画面。

二、实现思路

先将地球节点渲染到帧缓存FBO,自定义几何矩形面并绑定FBO中的纹理,然后添加正交投影相机并将视口对准几何矩形进行渲染,大致过程如下:

三、关键代码

1.将场景节点渲染到帧缓存(FBO)
cpp 复制代码
osg::Node* RenderNode2FBO(App& app, osg::Node* sceneGraph)
{
	osg::Camera* rtt = new osg::Camera();
	rtt->setRenderOrder(osg::Camera::PRE_RENDER);
	rtt->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
	rtt->setViewport(0, 0, app.gcolor->getTextureWidth(), app.gcolor->getTextureHeight());
	rtt->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	rtt->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0), app.gcolor);
	rtt->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER1), app.gnormal);
	rtt->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER2), app.gdepth);
	rtt->setCullingMode(rtt->getCullingMode() & ~osg::CullSettings::SMALL_FEATURE_CULLING);

	static const char* vertSource = R"(
        #version 330
        out float mrt_depth;
        void oe_mrt_vertex(inout vec4 vertexClip)
        {
            mrt_depth = (vertexClip.z/vertexClip.w)*0.5+0.5;
        }
    )";

	static const char* fragSource = R"(
        #version 330
        in float mrt_depth;
        in vec3 vp_Normal;
        layout(location=0) out vec4 gcolor;
        layout(location=1) out vec4 gnormal;
        layout(location=2) out vec4 gdepth;
        void oe_mrt_fragment(inout vec4 color)
        {	
            gcolor = color;
            gnormal = vec4((vp_Normal+1.0)/2.0, 1.0);
            gdepth = vec4(mrt_depth, mrt_depth, mrt_depth, 1.0);
        }
    )";

	VirtualProgram* vp = VirtualProgram::getOrCreate(rtt->getOrCreateStateSet());
	vp->setFunction("oe_mrt_vertex", vertSource, ShaderComp::LOCATION_VERTEX_CLIP);
	vp->setFunction("oe_mrt_fragment", fragSource, ShaderComp::LOCATION_FRAGMENT_OUTPUT);

	rtt->addChild(sceneGraph);
	return rtt;
}
2.创建正交相机,创建自定义矩形面并从FBO读取纹理并绑定
cpp 复制代码
osg::Node* createFramebufferPass(App& app)
{
	osg::Camera* camera = new osg::Camera();
	float w = app.gcolor->getTextureWidth();
	float h = app.gcolor->getTextureHeight();

	camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
	camera->setViewMatrix(osg::Matrix::identity());
	camera->setProjectionMatrixAsOrtho2D(-w / 2, (-w / 2) + w, -h / 2, (-h / 2) + h);
	{
		osg::Node* quad = createFramebufferQuadLeft(app);

		osg::StateSet* stateset = quad->getOrCreateStateSet();

		static const char* vertSource = R"(
	        #version 130
	        out vec4 texcoord;
	        void effect_vert(inout vec4 vertexView)
	        {
	            texcoord = gl_MultiTexCoord0;
	        }
	    )";

		// fragment shader that performs edge detection and tints edges red.
		static const char* fragSource = R"(
	        #version 330
	        #extension GL_ARB_texture_rectangle : enable
	        uniform sampler2DRect gcolor;
	        in vec4 texcoord;
	
	        void effect_frag(inout vec4 color)
	        {
	          color = texture(gcolor, texcoord.st);
	        }
	    )";

		VirtualProgram* vp = VirtualProgram::getOrCreate(stateset);
		vp->setFunction("effect_vert", vertSource, ShaderComp::LOCATION_VERTEX_VIEW);
		vp->setFunction("effect_frag", fragSource, ShaderComp::LOCATION_FRAGMENT_COLORING);

		stateset->setTextureAttributeAndModes(0, app.gcolor, 1);
		stateset->addUniform(new osg::Uniform("gcolor", 0));
		GLUtils::setLineWidth(stateset, 2.0f, 1);

		camera->addChild(quad);
	}
	{
		osg::Node* quad = createFramebufferQuadRight(app);

		osg::StateSet* stateset = quad->getOrCreateStateSet();

		static const char* vertSource = R"(
	        #version 130
	        out vec4 texcoord;
	        void effect_vert(inout vec4 vertexView)
	        {
	            texcoord = gl_MultiTexCoord0;
	        }
	    )";

		// fragment shader that performs edge detection and tints edges red.
		static const char* fragSource = R"(
	        #version 330
	        uniform sampler2DRect gcolor;
	        in vec4 texcoord;
	
	        void effect_frag(inout vec4 color)
	        {
				//简单效果:灰度处理
	            vec4 colorTexture = texture(gcolor, texcoord.st);
				float gray = (colorTexture.r+colorTexture.g+colorTexture.b)/3.0;
				color = vec4(gray,gray,gray,colorTexture.a);
	        }
	    )";

		VirtualProgram* vp = VirtualProgram::getOrCreate(stateset);
		vp->setFunction("effect_vert", vertSource, ShaderComp::LOCATION_VERTEX_VIEW);
		vp->setFunction("effect_frag", fragSource, ShaderComp::LOCATION_FRAGMENT_COLORING);

		stateset->setTextureAttributeAndModes(0, app.gcolor, 1);
		stateset->addUniform(new osg::Uniform("gcolor", 0));
		GLUtils::setLineWidth(stateset, 2.0f, 1);

		camera->addChild(quad);
	}
	return camera;
}

原创不易,记得点赞加关注哦,我会持续分享实用的功能(:-

相关推荐
妙为2 个月前
osgEarth中文显示乱码
中文乱码·osgearth·osg
WALL-EC6 个月前
Qt工具栏中图标槽函数没有响应的问题分析
开发语言·qt·osgearth
幽迷狂6 个月前
AFSIM入门教程03.03:更新所有依赖库版本
c++·qt·仿真·osgearth·osg·军事·afsim
little_fat_sheep7 个月前
【OpenGL ES】手撕一个mini版的Android native渲染框架
opengl es·egl·fbo·vbo·vao·渲染框架·ibo
星火撩猿10 个月前
如何配置osg编译使支持png图标加载显示
osgearth·osg·地图图标添加
slntJy10 个月前
ubantu&windows搭建gis开发环境(qt+osg+osgearth+osgqt)
gis·win11·osgearth·ubantu·osg·osgqt
读万卷书不如行万里路呀1 年前
实时飞行粒子尾迹(十二)
osgearth·osg·实时飞行粒子尾迹
闲暇部落1 年前
android openGL ES详解——缓冲区VBO/VAO/EBO/FBO
kotlin·opengl·缓冲区·fbo·vbo·vao·ebo
仙魁XAN1 年前
Unity 之 【Android Unity FBO渲染】之 [Unity 渲染 Android 端播放的视频] 的一种方法简单整理
android·unity·共享纹理·fbo·视频渲染