OSG粒子系统与阴影-自定义粒子系统示例<1>(4)

自定义粒子系统示例(一)

        自定义粒子系统示例(一)的代码如程序清单11-5所示:

/* 自定义粒子系统示例1 */
void particleSystem_11_5(const string &strDataFolder)
{
	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
	osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
	traits->x = 40;
	traits->y = 40;
	traits->width = 600;
	traits->height = 480;
	traits->windowDecoration = true;
	traits->doubleBuffer = true;
	traits->sharedContext = 0;

	osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());

	osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
	camera->setGraphicsContext(gc.get());
	camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
	GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
	camera->setDrawBuffer(buffer);
	camera->setReadBuffer(buffer);

	osg::ref_ptr<osg::Group> root = new osg::Group();

	// 自定义粒子系统加入场景
	root->addChild(createParticleScene(strDataFolder));

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

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

	viewer->realize();
	viewer->run();
}

// 创建自定义粒子系统
osg::ref_ptr<osg::Group> createParticleScene(const string &strDataFolder)
{
	osg::ref_ptr<osg::Group> root = new osg::Group();

	// 创建粒子系统模板
	osgParticle::Particle ptemplate;	
	ptemplate.setLifeTime(2);// 设置声明周期
	ptemplate.setSizeRange(osgParticle::rangef(0.75, 3.0));// 设置粒子大小变化范围	
	ptemplate.setAlphaRange(osgParticle::rangef(0.0, 1.0));// 设置粒子Alpha变化范围
	ptemplate.setColorRange(osgParticle::rangev4(osg::Vec4(1.0, 0.5, 0.3, 1.0),
		osg::Vec4(0.0, 0.7, 1.0, 0.0)));// 设置粒子颜色变化范围	
	ptemplate.setRadius(0.05);// 设置半径	
	ptemplate.setMass(0.05);// 设置重量

	// 创建粒子系统
	osg::ref_ptr<osgParticle::ParticleSystem> ps = new osgParticle::ParticleSystem();

	string strClrPath = strDataFolder + "Images\\smoke.rgb";
	ps->setDefaultAttributes(strClrPath, false, false);// 设置材质,是否放射粒子,是否添加光照	
	ps->setDefaultParticleTemplate(ptemplate);// 加入模板

	// 创建发射器和计数器,调整每一帧增加的粒子的数目
	osg::ref_ptr<osgParticle::RandomRateCounter> counter = new osgParticle::RandomRateCounter();
	counter->setRateRange(100.0,100.0);// 设置每秒增加的粒子的个数
	
	// 设置一个点放置器
	osg::ref_ptr<osgParticle::PointPlacer> placer = new osgParticle::PointPlacer();
	placer->setCenter(osg::Vec3(0.0, 0.0, 0.0));// 设置位置

	// 创建弧度发射器
	osg::ref_ptr<osgParticle::RadialShooter> shooter = new osgParticle::RadialShooter();
	shooter->setInitialSpeedRange(100, 0);// 设置发射器速度变化范围

	// 创建粒子放射器(包括计数器、放射器和发射器)
	osg::ref_ptr<osgParticle::ModularEmitter> emitter = new osgParticle::ModularEmitter();
	emitter->setParticleSystem(ps.get());// 关联粒子系统
	emitter->setCounter(counter.get());// 关联计数器
	emitter->setPlacer(placer.get());// 关联点放置器
	emitter->setShooter(shooter.get());// 关联发射器
	root->addChild(emitter.get());// 加入场景


	// 创建重力模拟对象
	osg::ref_ptr<osgParticle::AccelOperator> ap = new osgParticle::AccelOperator();
	ap->setToGravity(-1.0);// 设置重力加速度,默认值为9.80665

	// 创建空气阻力模拟
	osg::ref_ptr<osgParticle::FluidFrictionOperator> ffo = new osgParticle::FluidFrictionOperator();	
	// FluidViscosity为1.8e-5,FluidDensity为1.2929
	ffo->setFluidToAir();// 设置空气属性

	// 创建标准编程器对象,控制粒子在生命周期中的更新
	osg::ref_ptr<osgParticle::ModularProgram> program = new osgParticle::ModularProgram();
	program->setParticleSystem(ps.get());// 关联粒子系统
	program->addOperator(ap.get());// 关联重力	
	program->addOperator(ffo.get());// 关联空气阻力
	root->addChild(program.get());// 添加到场景

	// 添加更新器,实现每帧粒子的管理
	osg::ref_ptr<osgParticle::ParticleSystemUpdater> psu = new osgParticle::ParticleSystemUpdater();	
	psu->addParticleSystem(ps.get());// 关联粒子系统

	
	osg::ref_ptr<osg::Geode> geode = new osg::Geode;
	geode->addDrawable(ps.get());	
	root->addChild(geode.get());// 加入到场景中
	root->addChild(psu.get());

	return root.get();
}

        运行程序,截图如图11-7所示。

图11-7自定义粒子系统示例(一)截图

  • 30
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听风者868

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值