前言

osgearth_lights示例,模拟仿真了白天黑夜,添加了星空背景(太阳、月亮、其他天体),支持通过控件更改时间进而改变光照,支持随机更新图层颜色。

earth文件中,需要添加<sky>标签,否则无法加载skyNode节点。

<!--
osgEarth Sample
Demonstrates the use of the night color filter,
which only shows a layer in nighttime.
You need to have the sky activated for this shader to work.
-->
<map name="readymap.org" type="geocentric"><options><terrain first_lod="1" normalize_edges="true"/></options><!--此为全球影像图--><image name="GlobeImage" driver="gdal"><url>./globe/globel.tif</url></image>     <sky driver="simple" hours="14.0" ambient="1.0"/></map>

执行命令

// 运行白天黑夜地球
osgearth_lightsd.exe earth_image\lights.earth// --update 参数,支持随机更新影像图层颜色
osgearth_lightsd.exe earth_image\lights.earth --update

可以看到星空、太阳、月亮。右下角控制面板显示UTC时间、月、年、环境光因子。可以通过滑块进行设置。在代码中,并没有找到此控制面板的创建代码。

代码分析

1、osgEarth::Util::Ephemeris 类:星历表类,给出了自然发生的天体天体的位置;其中包括太阳和月亮。还包括一些相关的实用函数方法。

2、关于光源的创建和添加:先创建 osg::Light* sunLight 并为其设置参数,再创建 osg::LightSource* sunLS,并 sunLS->setLight(sunLight);最后将 sunLS 添加到根节点 lights->addChild( sunLS );

3、关于自定义地形材质,并加入到mapNode节点 进行应用。

完整代码

/*** Lights test. This application is for testing the LightSource support in osgEarth.* 灯光测试。此应用程序用于测试osgEarth中的光源支持。*/
#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 settingsviewer.getDatabasePager()->setUnrefImageDataAfterApplyPolicy( true, false );// install our default manipulator (do this before calling load)viewer.setCameraManipulator( new EarthManipulator(arguments) );// disable the small-feature cullingviewer.getCamera()->setSmallFeatureCullingPixelSize(-1.0f);// 在添加光源之前,需要关闭viewer本身的光viewer.setLightingMode(viewer.NO_LIGHT);// load an earth file, and support all or our example command-line optionsosg::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]);}
}

osgEarth示例分析——osgearth_lights相关推荐

  1. osgEarth示例分析——osgearth_annotation

    前言 本章为osgearth_annotation示例分析,示例中采用osgEarth提供的类,绘制标签.线.billboard.遮盖图.墙等内容. 运行时,在生成的可执行路径下,打开命令框,输入: ...

  2. osgEarth示例分析——osgearth_skyview

    前言 本示例分析osgearth操作深空场景,或者是银河系场景,可以想象人拿着相机站在地球表面上观看天空/银河系的场景. 重点是相机操作器的使用. 在命令框输入执行程序,在data路径下有加载的图,且 ...

  3. osgEarth示例分析——osgearth_manip

    前言 本示例主要演示osgEarth的事件处理的用法,内容比较多,这部分功能也很重要. 输入命令依然采用china-simple.earth的示例,加上了模型,但是模型并没有看到,可能是因为模型没有放 ...

  4. osgEarth示例分析——osgearth_elevation

    前言 osgearth_elevation示例,展示了如何通过点击地球获取不同定义下的高程数据.包括:MSL高程.HAE高程.EGM96高程.点击按钮,可以移除高程图层. MSL高程:是mean se ...

  5. osgEarth示例分析——osgearth_graticule

    前言 本示例最具有借鉴的功能:绘制网格.网格上的文字显示.拾取地球的坐标.在地球网格示例中,可以设置4种网格.执行命令如下: // --geodetic osgearth_graticuled.exe ...

  6. osgEarth示例分析——osgearth_srstest

    前言 osgearth_srstest示例,主要涉及到两个坐标系转换,wgs84→egm96  wgs84→plate-carre wgs84:World Geodetic System 1984,是 ...

  7. osgEarth示例分析——osgearth_eci

    前言 osgearth_eci示例,展示了J2000的天体坐标系和ECEF地固系的转换,绘制坐标系,以及读取卫星参数绘制卫星的功能.绘制卫星轨迹,添加差值效果和未添加差值的效果. 关于卫星两行根数的数 ...

  8. osgEarth示例分析——osgearth_terrainprofile

    前言 osgearth_terrainprofile示例,涉及到一个新的类 TerrainProfileCalculator(地形轮廓计算器类),用来计算两个点连线之间的地形数据.左下角会根据点击的起 ...

  9. osgEarth示例分析——osgearth_features

    前言 osgearth_features示例,主要演示如何通过代码方式加载shp文件,并设置其样式.在执行时,通过不同 的命令,得到不一样的效果. cmd执行命令: // rasterize 光栅化, ...

最新文章

  1. 如何使用Next.js创建动态的Rick and Morty Wiki Web App
  2. 一文读懂MQTT协议
  3. java 多线程Callable和Runable执行顺序问题详解
  4. 全国计算机等级考试题库二级C操作题100套(第05套)
  5. [熵编码] 指数哥伦布编码
  6. (王道408考研操作系统)第二章进程管理-第一节3:进程控制(配合Linux讲解)
  7. eslint是什么_为什么eslint没有 no-magic-string?
  8. MySQL check the manual that corresponds to your MySQL server version for the right syntax错误
  9. 黑苹果白果序列号_黑苹果从入门到放弃黑苹果:OC配置入门
  10. 电气工程类中文核心期刊
  11. Ping32文档加密软件有哪些特点
  12. 信息学奥赛NOIP/CSP-J初赛知识点汇总
  13. 联想计算机的控制面板在哪,教程知识:联想win10控制面板在哪里打开
  14. 静态网页设计——春节
  15. 【软件测试】翻了下招聘APP只会点点点,很慌......测试业务?技术?
  16. [置顶]封闭环境下的人性博弈——长文纪念诺兰的蝙蝠侠三部曲
  17. 实现GB28181平台级联到海康平台的级联
  18. MATLAB参数估计 置信区间
  19. 贪吃蛇大作战ai_当玩家发现《贪吃蛇大作战》是单机游戏后 世界都炸了
  20. 监控摄像头卡顿_监控画面卡顿的解决方法

热门文章

  1. IDC主机系统详细对比评测
  2. Session和Cookie
  3. Java动态生成pdf文件(用于实时生成电子证书)
  4. C# System.ObjectDisposedException:“无法访问已释放的对象。 ObjectDisposed_ObjectName_Name”
  5. 浅析UPS模块化电源的特点及其优势
  6. Kotlin第4篇 【Kotlin】进阶视频课程-关东升-专题视频课程
  7. 2017年第三届 美亚杯电子取证 个人赛题解
  8. 自己动手打造winpe-只完成了引导的制作和文件夹的构件-仅仅为了学习!
  9. PhEmail:基于Python的开源网络钓鱼测试工具
  10. Linux系统安装网络抓包工具wireshark