OSG中背景的设置

尝试了两种不同的方式设置背景。

创建HUD相机

图片背景

主要是通过osg::Iamge读取图片文件后渲染到Texture2D,关联到hud相机中子节点上,重点还是hud相机的设置:

	osg::ref_ptr<osg::Group> group = new osg::Group;

    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
    group->addChild(node);

    //创建hud相机
    osg::ref_ptr<osg::Camera> hudCamera = new osg::Camera;

	osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
	osg::ref_ptr<osg::Image> image = osgDB::readImageFile("E:/wallpaper/road.jpg");
	texture->setImage(image.get());
	osg::ref_ptr<osg::Drawable> quad = osg::createTexturedQuadGeometry(
		osg::Vec3(0.f, 0.f, 0.f), 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());
	geode->setNodeMask(1024);
	hudCamera->setClearMask(0);
	hudCamera->setCullingActive(false);
	hudCamera->setAllowEventFocus(false);
	hudCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
	hudCamera->setRenderOrder(osg::Camera::POST_RENDER);
	hudCamera->setProjectionMatrix(osg::Matrix::ortho2D(0.0, 1.0, 0.0, 1.0));
	hudCamera->setViewport(0, 0, 800, 600);
	hudCamera->addChild(geode.get());

	osg::StateSet* ss = hudCamera->getOrCreateStateSet();
	ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
	ss->setAttributeAndModes(new osg::Depth(osg::Depth::LEQUAL, 1.0, 1.0));

	group->addChild(hudCamera);

	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
	viewer->setSceneData(group);
	viewer->setUpViewInWindow(500, 500, 800, 600);
	return viewer->run();

渐变色背景

渐变色背景的实现中hud的创建是一致的。颜色显示也可以通过第一种方式去实现,比如使用qt的qimage自定义填充后当成一张图片被osg读入,也可以使用设置顶点数组和颜色数组的方式,如:


	osg::ref_ptr<osg::Group> group = new osg::Group;

    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
    group->addChild(node);

    //创建hud相机
    osg::ref_ptr<osg::Camera> hudCamera = new osg::Camera;

	osg::ref_ptr<osg::Geometry> quad = new osg::Geometry;
	osg::ref_ptr<osg::Vec3Array> vertex = new osg::Vec3Array;
	vertex->push_back(osg::Vec3(0.0, 0.0, 0.0));
	vertex->push_back(osg::Vec3(1.0, 0.0, 0.0));
	vertex->push_back(osg::Vec3(1.0, 1.0, 0.0));
	vertex->push_back(osg::Vec3(0.0, 1.0, 0.0));
	quad->setVertexArray(vertex);

	osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array;
	color->push_back(osg::Vec4(0.0, 1.0, 1.0, 1.0));
	color->push_back(osg::Vec4(0.0, 1.0, 1.0, 1.0));
	color->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0));
	color->push_back(osg::Vec4(0.0, 0.0, 1.0, 1.0));
	quad->setColorArray(color, osg::Array::BIND_PER_VERTEX);

	quad->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));

	...节点的添加与hud相机的设置同上...

shader

渐变色背景

通过使用shader创建一个全屏的三角形来充当背景,原理是从opengl渐变背景这篇文章中看到的。

#define SHADER_HEADER "#version 330 core\n"
#define SHADER_STR(x) #x

int main()
{
	osg::ref_ptr<osg::Geometry> geo = new osg::Geometry;

	const char* vs_src = (const char*)SHADER_HEADER SHADER_STR
	(
		out vec2 v_uv;
	    void main()
	    {
		    uint idx = uint(gl_VertexID);
		    gl_Position = vec4(idx & 1U, idx >> 1U, 0.0, 0.5) * 4.0 - 1.0;
		    v_uv = vec2(gl_Position.xy * 0.5 + 0.5);
	    }
	);

	const char* fs_src = (const char*)SHADER_HEADER SHADER_STR
	(
		uniform vec4 top_color = vec4(0.0, 1.0, 1.0, 1.0);
	    uniform vec4 bot_color = vec4(0.0, 0.0, 1.0, 1.0);
	    in vec2 v_uv;
	    out vec4 frag_color;

	    void main()
	    {
		    frag_color = bot_color * (1 - v_uv.y) + top_color * v_uv.y;
	    }
	);

	osg::ref_ptr<osg::Shader> vertexShader = new osg::Shader(osg::Shader::VERTEX, vs_src);
	osg::ref_ptr<osg::Shader> fragmentShader = new osg::Shader(osg::Shader::FRAGMENT, fs_src);

	osg::ref_ptr<osg::Program> m_program = new osg::Program;
	m_program->addShader(vertexShader);
	m_program->addShader(fragmentShader);

	geo->getOrCreateStateSet()->setAttributeAndModes(m_program, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);

	//osg中还是需要传递顶点,不然画不出来
    osg::Vec3Array* vertices = new osg::Vec3Array;
	vertices->push_back(osg::Vec3(0.0f, 0.0f, 0.0f));
	vertices->push_back(osg::Vec3(1.0f, 0.0f, 0.0f));
	vertices->push_back(osg::Vec3(1.0f, 0.0f, 1.0f));
    geo->setVertexArray(vertices);
	geo->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, 3));
	
    geo->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
    //小于0表示优先绘制,处于底层
    geo->getOrCreateStateSet()->setRenderBinDetails(-2, "RenderBin");

    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("cow.osg");
	
    osg::ref_ptr<osg::Group> group = new osg::Group;
    group->addChild(node);
    group->addChild(geo);

    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
    viewer->setSceneData(group);
    viewer->setUpViewInWindow(500, 500, 800, 600);
    return viewer->run();
}

图片背景

大体和上面一致,修改了shader来对纹理采样:

#define SHADER_HEADER "#version 330 core\n"
#define SHADER_STR(x) #x

int main()
{
	...同上...
	
	const char* fs_src = (const char*)SHADER_HEADER SHADER_STR
	(
		uniform sampler2D tex;
		in vec2 v_uv;
		out vec4 frag_color;

		void main()
		{
			vec4 tempColor = texture(tex, v_uv);
			frag_color = tempColor;
		}
	);

	...shader的编译和节点其他属性的设置代码同上...

	osg::ref_ptr<osg::Texture2D> tex2d = new osg::Texture2D;
	tex2d->setDataVariance(osg::Object::DYNAMIC);
	tex2d->setImage(osgDB::readImageFile("E:/wallpaper/road.jpg"));
	geo->getOrCreateStateSet()->setTextureAttributeAndModes(0, tex2d, osg::StateAttribute::ON);

   	...场景的设置和节点的添加代码同上...
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值