osg之黑夜背景地月系显示

目录

效果

 代码


效果

 代码


/**
* Lights test. This application is for testing the LightSource support in osgEarth.
* 灯光测试。此应用程序用于测试osgEarth中的光源支持。
*/
#include "stdafx.h"
#include <osgViewer/Viewer>
#include <osgEarth/Notify>
#include <osgEarth/Lighting>
#include <osgEarth/PhongLightingEffect>
#include <osgEarth/NodeUtils>
#include <osgEarthUtil/EarthManipulator>
#include <osgEarthUtil/ExampleResources>
#include <osgEarthUtil/Ephemeris>
#include <osgEarthUtil/Shadowing>

#define LC "[lights] "

using namespace osgEarth;
using namespace osgEarth::Util;

int
usage(const char* name)
{
	OE_NOTICE
		<< "\nUsage: " << name << " file.earth" << std::endl
		<< MapNodeHelper().usage() << std::endl;

	return 0;
}

// converts a double-precision Vec3d to an equivalent single-precision Vec4f position
// as needed for light positions.
// Vec3d转换为Vec4f ,根据光源位置的需要
osg::Vec4
worldToVec4(const osg::Vec3d& ecef)
{
	osg::Vec4 result(0.0f, 0.0f, 0.0f, 1.0f);
	osg::Vec3d d = ecef;
	while (d.length() > 1e6)// 避免光源位置太远??
	{
		d *= 0.1;
		result.w() *= 0.1;
	}
	return osg::Vec4(d.x(), d.y(), d.z(), result.w());
}

// 生成随机颜色
osg::Vec4
randomColor()
{
	float r = (float)rand() / (float)RAND_MAX;
	float g = (float)rand() / (float)RAND_MAX;
	float b = (float)rand() / (float)RAND_MAX;
	return osg::Vec4(r, g, b, 1.0f);
}

// 添加光源
osg::Group*
addLights(osg::View* view, osg::Node* root, int lightNum)
{
	// 获取地理坐标系
	MapNode* mapNode = MapNode::get(root);
	const SpatialReference* mapsrs = mapNode->getMapSRS();
	const SpatialReference* geosrs = mapsrs->getGeographicSRS();

	osg::Vec3d world;
	osg::Group* lights = new osg::Group();

	// Add a directional light that simulates the sun - but skip this if a sky
	// was already added in the earth file.
	// 添加模拟太阳的平行光
	// 但如果地球文件中已经添加了天空,则跳过此操作。
	if (lightNum == 0)
	{
		// Ephemeris 星历表类,给出了自然发生的天体天体的位置;
		// 其中包括太阳和月亮。
		// 还包括一些相关的实用程序功能。
		Ephemeris e;
		DateTime dt(2016, 8, 10, 14.0);// 设置UTC时间
		CelestialBody sun = e.getSunPosition(dt); // 设置天体相对于地球的位置。
		world = sun.geocentric;// 太阳的地理位置

		// 定义太阳光
		osg::Light* sunLight = new osg::Light(lightNum++);
		world.normalize();// 归一化
		sunLight->setPosition(osg::Vec4d(world, 0.0));

		sunLight->setAmbient(osg::Vec4(0.2, 0.2, 0.2, 1.0));// 环境光照
		sunLight->setDiffuse(osg::Vec4(1.0, 1.0, 0.9, 1.0));// 漫反射光照

		// osg::LightSource 用于定义场景中的灯光的叶节点。
		osg::LightSource* sunLS = new osg::LightSource();
		sunLS->setLight(sunLight);

		lights->addChild(sunLS);

		// 为root节点 投射阴影
		ShadowCaster* caster = osgEarth::findTopMostNodeOfType<ShadowCaster>(root);
		if (caster)
		{
			OE_INFO << "Found a shadow caster!\n";
			caster->setLight(sunLight);
		}
		std::cout << "because no skyNode,so create sunLS" << std::endl;
	}

#if 1	// 这里主要是为测试加载其他光源
	// A red spot light. A spot light has a real position in space 
	// and points in a specific direciton. The Cutoff and Exponent
	// properties control the cone angle and sharpness, respectively
	// 一束红光。拥有真实的位置和光方向。
	// “Cutoff”和“Exponent”属性分别控制圆锥体角度和锐度
	{
		// 定义光照射 地点
		GeoPoint p(geosrs, -121, 34, 5000000., ALTMODE_ABSOLUTE);
		p.toWorld(world);

		// 定义光
		osg::Light* spot = new osg::Light(lightNum++);
		spot->setPosition(worldToVec4(world));
		spot->setAmbient(osg::Vec4(0, 0.2, 0, 1));
		spot->setDiffuse(osg::Vec4(1, 0, 0, 1));
		spot->setSpotCutoff(20.0f);
		spot->setSpotExponent(100.0f);

		// point straight down at the map:直接指向地图
		world.normalize();
		spot->setDirection(-world);

		// 光源叶子节点
		osg::LightSource* spotLS = new osg::LightSource();
		spotLS->setLight(spot);

		lights->addChild(spotLS);
	}

	// A green point light. A Point light lives at a real location in 
	// space and lights equally in all directions.
	// 绿灯。点光源位于空间中的真实位置,并在所有方向上均匀发光。
	{
		// 定义光照射 地点
		GeoPoint p(geosrs, -45, -35, 1000000., ALTMODE_ABSOLUTE);
		p.toWorld(world);

		// 定义光
		osg::Light* point = new osg::Light(lightNum++);
		point->setPosition(worldToVec4(world));
		point->setAmbient(osg::Vec4(0, 0, 0, 1));
		point->setDiffuse(osg::Vec4(1.0, 1.0, 0.0, 1));

		// 光源叶子节点
		osg::LightSource* pointLS = new osg::LightSource();
		pointLS->setLight(point);

		lights->addChild(pointLS);
	}
#endif

	// Generate the necessary uniforms for the shaders.
	// 为着色器生成必要的uniforms。
	// GenerateGL3LightingUniforms类的作用:遍历图形,查找灯光和材质,
	//		并为它们生成静态 Uniforms 或动态剔除回调,
	//		以便它们可以使用核心配置文件着色器。
	GenerateGL3LightingUniforms gen;
	lights->accept(gen);

	return lights;
}



int
main(int argc, char** argv)
{
	osg::ArgumentParser arguments(&argc, argv);

	// help?
	if (arguments.read("--help"))
		return usage(argv[0]);

	// create a viewer:
	osgViewer::Viewer viewer(arguments);

	// Whether to test updating material
	// 是否测试更新材质
	bool update = arguments.read("--update");

	// Tell the database pager to not modify the unref settings
	viewer.getDatabasePager()->setUnrefImageDataAfterApplyPolicy(true, false);

	// install our default manipulator (do this before calling load)
	viewer.setCameraManipulator(new EarthManipulator(arguments));

	// disable the small-feature culling
	viewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f);

	// 在添加光源之前,需要关闭viewer本身的光
	viewer.setLightingMode(viewer.NO_LIGHT);

	// load an earth file, and support all or our example command-line options
	osg::ref_ptr<osg::Node> node = MapNodeHelper().load(arguments, &viewer);
	if (node.valid())
	{
		MapNode* mapNode = MapNode::get(node.get());
		if (!mapNode)
			return -1;

		// Example of a custom material for the terrain.
		// 地形自定义材质示例。
		osg::ref_ptr< osg::Material > material = 0;
		if (update)// 开启update属性后,会创建material,进而调用回调方法,随机更改影像颜色
		{
			OE_NOTICE << "Custom material" << std::endl;
			material = new osg::Material;// 材质决定材质颜色
			material->setDiffuse(osg::Material::FRONT, osg::Vec4(1, 1, 1, 1));//漫反射光照    
			material->setAmbient(osg::Material::FRONT, osg::Vec4(1, 1, 1, 1));// 环境光照
			// Attach our StateAttributeCallback so that uniforms are updated.绑定材质回调
			material->setUpdateCallback(new MaterialCallback());
			mapNode->getOrCreateStateSet()->setAttributeAndModes(material);
		}

		// Does a Sky already exist (loaded from the earth file)?
		SkyNode* sky = osgEarth::findTopMostNodeOfType<SkyNode>(node.get());
		if (!sky)// 如果没有深空节点
		{
			std::cout << "no skyNode " << std::endl;
			// Add phong lighting.添加标签照明???
			PhongLightingEffect* phong = new PhongLightingEffect();
			phong->attach(node->getOrCreateStateSet());
		}

		// 添加光源. 当没有sky时,才会采用addLights中,创建光源的方式添加。
		osg::Group* lights = addLights(&viewer, node.get(), sky ? 1 : 0);

		mapNode->addChild(lights);

		viewer.setSceneData(node.get());
		while (!viewer.done())
		{
			if (viewer.getFrameStamp()->getFrameNumber() % 100 == 0)
			{
				// 每100帧,随机生成一个颜色
				if (material)
				{
					material->setDiffuse(osg::Material::FRONT, randomColor());
				}
			}
			viewer.frame();
		}
		return 0;
	}
	else
	{
		return usage(argv[0]);
	}
}

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

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

相关文章

Vite创建React项目,另外一种更加简单的方法

在上一篇blog中一个一个安装依赖dependencies&#xff0c;有没有一步到位的方法呢&#xff0c;有! 参考《React 18 Design Patterns and Best Practices Design, build, and deploy production-ready web applications with React》4th 第一章倒数第二节Vite as a solution有个…

Mysql数据库 12.SQL语言 触发器

一、触发器&#xff08;操作日志表&#xff09; 1.介绍 不需要主动调用的一种储存过程&#xff0c;是一个能够完成特定过程&#xff0c;存储在数据库服务器上的SQL片段。 对当前表中数据增删改查的一种记录<日志表>&#xff0c;根据触发器自动执行&#xff0c;记录当前…

在mac上使用jmap -heap命令报错:Attaching to process ID 96530, please wait...

在mac上执行命令jmap -heap 96530 报错&#xff1a; Attaching to process ID 96530, please wait... ERROR: attach: task_for_pid(96530) failed: (os/kern) failure (5) Error attaching to process: sun.jvm.hotspot.debugger.DebuggerException: Cant attach to the proc…

OpenHarmony 社区运营报告(2023 年 10 月)

● 截至 2023 年 10 月&#xff0c;OpenHarmony 社区共有 51 家共建单位&#xff0c;累计超过 6200 名贡献者产生 24.2 万多个 PR&#xff0c;2.3 万多个 Star&#xff0c;6.1 万多个 Fork&#xff0c;59 个 SIG。 ● OpenHarmony 4.0 版本如期而至&#xff0c;开发套件同步升级…

【经验模态分解】2.EMD的3个基本概念

/*** poject 经验模态分解及其衍生算法的研究及其在语音信号处理中的应用* file EMD的3个基本概念* author jUicE_g2R(qq:3406291309)* * language MATLAB/Python/C/C* EDA Base on matlabR2022b* editor Obsidian&#xff08;黑曜石笔记软件…

电脑msvcp110.dll丢失怎么办,msvcp110.dll缺失的详细修复步骤

在现代科技发展的时代&#xff0c;电脑已经成为我们生活和工作中不可或缺的工具。然而&#xff0c;由于各种原因&#xff0c;电脑可能会出现一些问题&#xff0c;其中之一就是msvcp110.dll文件丢失。这个问题可能会导致一些应用程序无法正常运行&#xff0c;给我们的生活和工作…

linux生产者消费者模型

今天是一个与互斥锁和条件变量有关的一个模型&#xff0c;生产者消费者模型&#xff0c;为什么要用这个模型呢&#xff1f;其实这个模型我个人感觉的有点就是提高了效率&#xff0c;在多线程的情况下&#xff0c;提高了非常明显。并且解耦了生产者和消费者的关系。下面是一个这…

探索经典算法:贪心、分治、动态规划等

1.贪心算法 贪心算法是一种常见的算法范式&#xff0c;通常在解决最优化问题中使用。 贪心算法是一种在每一步选择中都采取当前状态下最优决策的算法范式。其核心思想是选择每一步的最佳解决方案&#xff0c;以期望达到最终的全局最优解。这种算法特点在于只考虑局部最优解&am…

Git设置显示中文

git config --global i18n.comitencoding utf-8 git config --global i18n.logoutputencoding utf-8 export LESSCHARSETutf-8

人声与背景音乐源分离

一.人声分离项目说明 人声分离是将音频录音分离为各个源的任务。该存储库是音乐源分离的 PyTorch 实现。用户可以通过安装此存储库将自己喜欢的歌曲分成不同的来源。用户还可以训练自己的源分离系统。该存储库还可用于训练语音增强、乐器分离和任何分离系统。 2.1 环境配置 …

[直播自学]-[汇川easy320]搞起来(3)看文档安装软件 查找设备

2023.11.09 20&#xff1a;04 按照文档 解压压缩包得到&#xff1a; 打开 里面有一条值得注意&#xff1a; 想把软件安装到C盘&#xff0c;但是C盘没什么空间了&#xff0c;把C盘清理清理。 20&#xff1a;35 安装很快完成&#xff0c;然后阅读 由于PLC是新的&#xff0c…

django安装和rest接口写法

django安装 确保已经安装了Python。命令行中输入python --version来检查Python的版本。 安装Django。你可以在命令行中使用以下命令来安装Django&#xff1a; pip install django创建一个新的Django项目。在命令行中&#xff0c;进入你想要创建项目的目录&#xff0c;并运行以…

vscode 访问本地或者远程docker环境

1、vscode 访问docker本地环境 直接点击左下角连接图标&#xff0c;弹出选项可以选择容器&#xff0c;只要容器在本地运行者&#xff0c;选择attach可以看到运行中的容器可以选择&#xff0c;选择其中需要选择的就行 ## 运行容器&#xff0c;可以-d后台运行都可以 docker run…

跨时钟域(Clock Domain Crossing,CDC)

本文参考&#xff1a;http://t.csdnimg.cn/VHga2 【数字IC基础】跨时钟域&#xff08;CDC&#xff0c;Clock Domain Crossing&#xff09;_ReRrain的博客-CSDN博客 同步设计&#xff1a;所有设计使用同一时钟源&#xff0c;频率相位可预知。 异步设计&#xff1a;设计中有两…

RPC接口测试技术-websocket 自动化测试实践

WebSocket 是一种在单个 TCP 连接上进行全双工通信(Full Duplex 是通讯传输的一个术语。通信允许数据在两个方向上同时传输&#xff0c;它在能力上相当于两个单工通信方式的结合。全双工指可以同时&#xff08;瞬时&#xff09;进行信号的双向传输&#xff08; A→B 且 B→A &a…

elementui-plus el-tree组件数据不显示问题解决

当前情况: 显示: 注意看右侧的树是没有文字的,数据已经渲染,个数是对的,但就是没有文字, 解决: 对比以后发现是template中的#default{data}没有写大括号导致的 所以写上大括号后: 正常显示

ArcGIS 气象风场等示例 数据制作、服务发布及前端加载

1. 原始数据为多维数据 以nc数据为例。 首先在pro中需要以多维数据的方式去添加多维数据&#xff0c;这里的数据包含uv方向&#xff1a; 加载进pro的效果&#xff1a; 这里注意 数据属性需要为矢量uv&#xff1a; 如果要发布为服务&#xff0c;需要导出存储为tif格式&…

C语言编写一个程序采集招聘信息

因为在这里无法详细解释每行代码和步骤。但是&#xff0c;我可以给大家一个使用Python和requests库编写的简单爬虫程序的例子&#xff0c;它可以从网站上获取招聘信息。你可以根据这个例子&#xff0c;将其改写为使用C语言编写的爬虫程序。 import requests# 指定爬虫IP信息 pr…

javaScript爬虫程序抓取评论

由于评论区目前没有开放的API接口&#xff0c;所以我们不能直接通过编程获取到评论区的内容。但是&#xff0c;我们可以通过模拟浏览器的行为来实现这个功能。以下是一个使用Python的requests库和BeautifulSoup库来实现这个功能的基本思路&#xff1a; import requests from bs…

Matlab论文插图绘制模板第125期—特征渲染的三维气泡图

在之前的文章中&#xff0c;分享了很多Matlab三维气泡图的绘制模板&#xff1a; 进一步&#xff0c;再来分享一下特征渲染的三维气泡图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自行下载。有需要的…