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

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

        目前自定义粒子的方法有很多,在OSG 中使用的是 Billboard 技术与色彩融合技术。色彩融合是一种高级的渲染技术,如果读者有兴趣,可参看 OSG 粒子系统实现的源代码。这里采用简单的布告牌技术(osg::Billboard)与动画来实现。这种方法也可以生成比较好的粒子系统的效果。最好使用同名的贴图,示例中并没有对这些贴图进行处理,它只是向读者展示如何模拟一个自定义的粒子系统,读者可仔细体会。

        自定义粒子系统示例(二)的代码如程序清单11-6所示。

/* 自定义粒子系统示例2 */
void particleSystem_11_6(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();

	// 向场景中添加帧动画
	osg::ref_ptr<osg::Sequence>sq = new osg::Sequence();
	sq = createSequence(strDataFolder);
	root->addChild(sq.get());

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

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

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

osg::ref_ptr<osg::Node> createBillBoard(osg::ref_ptr<osg::Image> image)
{
	// 创建四边形
	osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();

	// 设置顶点
	osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array();
	v->push_back(osg::Vec3(-0.5, 0.0, -0.5));
	v->push_back(osg::Vec3(0.5, 0.0, -0.5));
	v->push_back(osg::Vec3(0.5, 0.0, 0.5));
	v->push_back(osg::Vec3(-0.5, 0.0, 0.5));
	geometry->setVertexArray(v.get());

	// 设置法线
	osg::ref_ptr<osg::Vec3Array> normal = new osg::Vec3Array();
	normal->push_back(osg::Vec3(1.0, 0.0, 0.0) ^ osg::Vec3(0.0, 0.0, 1.0));
	geometry->setNormalArray(normal.get());
	geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);

	// 设置纹理坐标
	osg::ref_ptr<osg::Vec2Array> vt = new osg::Vec2Array();
	vt->push_back(osg::Vec2(0.0, 0.0));
	vt->push_back(osg::Vec2(1.0, 0.0));
	vt->push_back(osg::Vec2(1.0, 1.0));
	vt->push_back(osg::Vec2(0.0, 1.0));
	geometry->setTexCoordArray(0, vt.get());

	// 绘制四边形
	geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
	if (image.get())
	{
		// 属性对象
		osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();

		// 创建一个Texture2D属性对象
		osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D();

		// 关联image
		texture->setImage(image.get());

		// 关联Texture2D纹理对象,第三个参数默认为ON
		stateset->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::ON);

		// 启用混合
		stateset->setMode(GL_BLEND, osg::StateAttribute::ON);

		// 关闭光照
		stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

		geometry->setStateSet(stateset.get());
	}

	// 创建BillBoard对象1
	osg::ref_ptr<osg::Billboard> billboard1 = new osg::Billboard();

	// 设置旋转模式为绕视点
	billboard1->setMode(osg::Billboard::POINT_ROT_EYE);

	// 添加Drawable,并设置其位置,默认位置为osg::Vec3(0,0,0)
	billboard1->addDrawable(geometry.get(), osg::Vec3(5.0, 0.0, 0.0));

	//osg::ref_ptr<osg::Billboard> billboard2 = new osg::Billboard();
	osg::ref_ptr<osg::Group> billboard = new osg::Group();
	billboard->addChild(billboard1.get());

	return billboard.get();
}

// 创建帧动画
osg::ref_ptr<osg::Sequence> createSequence(const string &strDataFolder)
{
	// 创建帧动画对象
	osg::ref_ptr<osg::Sequence> seq = new osg::Sequence();

	// 文件名向量对象
	typedef std::vector<string> Filenames;
	Filenames filenames;
	char name_count[256];
	for (int i = 0; i < 60; ++i)
	{
		sprintf_s(name_count, "%sosgVR\\bz%d.jpg", strDataFolder.c_str(),i);
		filenames.push_back(name_count);
	}

	for (Filenames::iterator itr = filenames.begin(); itr != filenames.end(); ++itr)
	{
		// 加载模型
		osg::Image *image = osgDB::readImageFile(*itr);
		if (image)
		{
			// 添加子节点
			seq->addChild(createBillBoard(image));

			// 设定节点的持续时间
			seq->setTime(seq->getNumChildren() - 1, 0.1);
		}
	}

	// 设置帧动画持续的时间
	seq->setInterval(osg::Sequence::LOOP, 0, -1);

	// 设置播放的速度及重复的次数
	seq->setDuration(1.0, -1);

	// 开始播放
	seq->setMode(osg::Sequence::START);

	return seq.get();
}

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

图11-8自定义粒子系统示例(二)截图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/188767.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Canvas艺术之旅:探索锚点抠图的无限可能

说在前面 在日常的图片处理中&#xff0c;我们经常会遇到需要抠图的情况&#xff0c;无论是为了美化照片、制作海报&#xff0c;还是进行图片合成。抠图对于我们来说也是一种很常用的功能了&#xff0c;今天就让我们一起来看下怎么使用canvas来实现一个锚点抠图功能。 效果展示…

Int8量化算子在移动端CPU的性能优化

本文介绍了Depthwise Convolution 的Int8算子在移动端CPU上的性能优化方案。ARM架构的升级和相应指令集的更新不断提高移动端各算子的性能上限&#xff0c;结合数据重排和Sdot指令能给DepthwiseConv量化算子的性能带来较大提升。 背景 MNN对ConvolutionDepthwise Int8量化算子在…

鸿蒙开发报错:agconnect sdk not initialized. please call initialize()【BUG已解决】

文章目录 项目场景:问题描述原因分析:解决方案:总结:项目场景: 鸿蒙开发报错: agconnect sdk not initialized. please call initialize() 问题描述 报错内容为: 10-25 11:41:01.152 6076-16676 E A0c0d0/JSApp: app Log: 数据查询失败: {“code”:1100001,“messag…

【经典小练习】输出文件路径名

文章目录 &#x1f339;问题✨思路&#x1f354;代码&#x1f6f8;读取文件&#xff0c;并把文件名保存到文件中 对指定目录下的所有 Java 文件进行编译、打包等处理&#xff1b; 查找指定目录下所有包含特定字符串的 Java 文件&#xff1b; 统计指定目录下所有 Java 文件的行数…

@ResponseBody详解

ResponseBody() 作用&#xff1a; responseBody注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后&#xff0c;写入到response对象的body区&#xff0c;通常用来返回JSON数据或者是XML数据。 位置&#xff1a; ResponseBody是作用在方法上的&…

Task.Run为什么会存在内存泄漏的风险?

由于值类型是拷贝方式的赋值&#xff0c;捕获的本地变量和类成员是指向各自的值&#xff0c;对本地变量的捕获不会影响到整个类。但如果把类中的值类型改为引用类型&#xff0c;那这两者最终指向的是同一个对象值&#xff0c;这是否意味着使用本地变量还是无法避免内存泄漏&…

个人测试用例以及测试金句分享

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 ☁️测试必背金句 界面易用可双安&…

微软 Edge 浏览器目前无法支持 avif 格式

avif 格式在微软 Edge 浏览器中还是没有办法支持。 如果你希望能够查看 avif 格式&#xff0c;那么只能通过浏览器打开&#xff0c;然后浏览器将会把这个文件格式下载到本地。 avif 格式已经在其他的浏览器上得到了广泛的支持&#xff0c;目前不支持的可能就只有 Edge 浏览器。…

【尚跑】2023宝鸡马拉松安全完赛,顺利PB达成

1、赛事背景 千年宝地&#xff0c;一马当先&#xff01;10月15日7时30分&#xff0c;吉利银河2023宝鸡马拉松在宝鸡市行政中心广场鸣枪开跑。 不可忽视的是&#xff0c;这次赛事的卓越之处不仅在于规模和参与人数&#xff0c;还在于其精心的策划和细致入微的组织。为了确保每位…

第一百八十回 介绍两种阴影效果

文章目录 1. 概念介绍2. 实现方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"自定义SlideImageSwitch组件"相关的内容&#xff0c;本章回中将介绍两种阴影效果.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在…

01背包问题

介绍 有N件物品和一个最多能被重量为W 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 分析 优化后的代码 public class demo {static class Item{int index;String na…

VMware OpenSLP漏洞解决方案

PS&#xff1a;早期为客户做VMware检测的方法&#xff0c;大家如有遇到可参考 OpenSLP堆溢出漏洞攻击大量ESXI服务器&#xff0c;该漏洞编号为CVE-2021-21974&#xff0c;由 OpenSLP 服务中的堆溢出问题引起 大于以下版本则不受影响 ESXi versions 7.x prior to ESXi7…

css优化滚动条样式

css代码&#xff1a; ::-webkit-scrollbar {width: 6px;height: 6px; }::-webkit-scrollbar-track {background-color: #f1f1f1; }::-webkit-scrollbar-thumb {background-color: #c0c0c0;border-radius: 3px; }最终样式&#xff1a;

AOP简介

目录 AOP简介 AOP思想的实现方案 模拟AOP的基础代码 AOP相关概念 AOP简介 AOP&#xff0c;Aspect Oriented Programming&#xff0c;面向切面编程&#xff0c;是对面向编程OOP的升华。OOP是纵向对一个事物的抽象&#xff0c;一个对象包括静态的属性信息&#xff0c;包括动态…

ubuntu+Teslav100 环境配置

系统基本信息 nvidia-smi’ nvidia-smi 470.182.03 driver version:470.182.03 cuda version: 11.4 产看系统体系结构 uname -aUTC 2023 x86_64 x86_64 x86_64 GNU/Linux 下载miniconda https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/?CM&OA https://mi…

TikTok 将开源“云中和”边缘加速器

“从某种意义上说&#xff0c;我们正在努力破解云的骨干网&#xff0c;以造福于我们&#xff0c;”TikTok产品管理基础设施经理Vikram Siwach指出&#xff0c;他解释了该公司即将开源的“全球服务加速器”的好处&#xff0c;这是一个可编程的边缘平台&#xff0c;可将应用程序需…

最详细手把手教你安装 Git + TortoiseGit 及使用

软件下载 从 Git 官网 下载 Git 安装程序&#xff0c;点击 Download for Windows&#xff1a; 点击下载 64-bit Git for Windows Setup: Git for Windows Setup 为安装版本&#xff0c;建议选择此版本Git for Windows Portable 为绿色免安装版本 从 TortoiseGit 官网 下载 T…

万字解析设计模式之责任链模式、状态模式

目录 一、责任链模式 1.1概述 1.2结构 1.3实现 1.4 优缺点 1.5应用场景 1.6源码解析 二、状态模式 2.1概述 2.2结构 2.3实现 2.4优缺点 2.5应用场景 三、责任链模式实验 任务描述 实现方式 编程要求 测试说明 四、状态模式实验 任务描述 实现方式 编程要…

什么是无监督学习

1 概况 1.1 定义 无监督学习&#xff08;Unsupervised Learning&#xff09;是机器学习的一种类型&#xff0c;它涉及从未标记的数据中发现隐藏的模式。与监督学习不同&#xff0c;无监督学习的数据没有显式的标签或已知的结果变量。其核心目的是探索数据的内在结构和关系。无…
最新文章