osg10: osg3.3.16 遮挡裁剪节点

这篇博客介绍了如何在osg中创建遮挡裁剪节点,通过实例展示了如何围绕模型创建前后左右四个遮挡面,以实现视场内的遮挡效果。主要涉及osg的OccluderNode、ConvexPlanarOccluder等类的使用,以及场景优化和渲染设置。
摘要由CSDN通过智能技术生成

osg10: osg3.3.16 遮挡裁剪节点

/**********************************************************
*Write by FlySky
*zzuxp@163.com  http://www.OsgChina.org   
**********************************************************/

#include <osgViewer/Viewer>

#include <osg/Node>
#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Group>
#include <osg/OccluderNode>
#include <osg/StateSet>
#include <osg/ConvexPlanarOccluder>
#include <osg/BoundingBox>
#include <osg/BoundingSphere>

#include <osgDB/ReadFile>
#include <osgDB/WriteFile>

#include <osgUtil/Optimizer>

#include <iostream>

//创建遮挡节点
osg::ref_ptr<osg::Node> createOccluder(const osg::Vec3& v1,const osg::Vec3& v2,const osg::Vec3& v3,const osg::Vec3& v4)
{
	//创建遮挡节点对象
	osg::ref_ptr<osg::OccluderNode> occluderNode = new osg::OccluderNode();

	//创建遮挡平面
	osg::ref_ptr<osg::ConvexPlanarOccluder> cpo = new osg::ConvexPlanarOccluder;

	//关联遮挡板平面
	occluderNode->setOccluder(cpo.get());
	occluderNode->setName("occluder");

	//初始化一个遮挡平面
	osg::ConvexPlanarPolygon& occluder = cpo->getOccluder();
	occluder.add(v1);
	occluder.add(v2);
	occluder.add(v3);
	occluder.add(v4); 

	//为这当面画一个四边形
	osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;

	osg::ref_ptr<osg::Vec3Array> coords = new osg::Vec3Array(occluder.getVertexList().begin(),occluder.getVertexList().end());
	geom->setVertexArray(coords);

	osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
	(*colors)[0].set(1.0f,1.0f,1.0f,0.5f);
	geom->setColorArray(colors.get());
	geom->setColorBinding(osg::Geometry::BIND_OVERALL);

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

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

	osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
	//关闭光照
	stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
	//使用混合,以保证Alpha纹理正确
	stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
	//设置透明渲染元
	stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);

	geom->setStateSet(stateset.get());

	//添加四边形作为遮挡节点,遮挡节点本身不具备遮挡能力
	occluderNode->addChild(geode.get());    

	return occluderNode.get();

}

//创建绕模型的遮挡场景
osg::ref_ptr<osg::Group> createOccludersAroundModel(osg::ref_ptr<osg::Node> model)
{
	//创建场景组节点
	osg::ref_ptr<osg::Group> scene = new osg::Group();
	scene->setName("OccluderScene");

	//添加子节点
	scene->addChild(model.get());
	model->setName("cow.osg");

	//计算模型的包围盒
	const osg::BoundingSphere bs = model->getBound();

	//根据包围盒来创建几个前后左右几个遮挡面
	osg::BoundingBox bb;
	bb.expandBy(bs);

	//前遮挡面
	scene->addChild(createOccluder(bb.corner(0),
		bb.corner(1),
		bb.corner(5),
		bb.corner(4)));

	//右遮挡面
	scene->addChild(createOccluder(bb.corner(1),
		bb.corner(3),
		bb.corner(7),
		bb.corner(5)));

	//左遮挡面
	scene->addChild(createOccluder(bb.corner(2),
		bb.corner(0),
		bb.corner(4),
		bb.corner(6)));

	//后遮挡面
	scene->addChild(createOccluder(bb.corner(3),
		bb.corner(2),
		bb.corner(6),
		bb.corner(7)));

	return scene.get();
} 

int main()
{
	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();

	osg::ref_ptr<osg::Group> root = new osg::Group();
	
	osg::ref_ptr<osg::Node> node =osgDB::readNodeFile("cow.osg");

	//添加遮挡场景
	root->addChild(createOccludersAroundModel(node.get()));

	//优化场景数据
	osgUtil::Optimizer optimizer ;
	optimizer.optimize(root.get()) ;

	viewer->setSceneData(root.get());

	viewer->realize();

	viewer->run();

	return 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值