前言

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. 代码整洁之道(Clean Code)- 读书笔记
  2. C语言结构体描述BMP的文件格式
  3. dataframe去重复 python_python – 在DataFrame中组合重复的列
  4. 微信公众开放平台开发04---百度BAE,java应用部署服务器,jetty了解
  5. mysql之配置mysql使其可用python远程控制
  6. mysql删除重复记录只保留一条
  7. getmethodid( android/widget/toast ),Android功能实现-Go语言中文社区
  8. C语言 一个字符串翻转函数的编写
  9. Navicat for mysql 破解版,安装与破解
  10. 通讯录_你有多久没翻过通讯录了?
  11. 小米路由的IPv6支持教程(纯转保存)
  12. 显卡更新显示计算机无法识别,电脑无法识别独立显卡
  13. 华大基因首席运营官张凌离职
  14. Chrome浏览器更新失败
  15. 五花八门的垂直搜索引擎
  16. 特殊字符在英语中的读法
  17. Tecplot云图——数据文本格式1
  18. android打电话的intent,如何在Android中使用intent打电话?
  19. 威联通NAS安装openwrt旁路由
  20. WakeOnLAN下载

热门文章

  1. To be contine ,NW NMM backup sqlserver failed.
  2. 海康威视硬盘录像机无法删除通道问题
  3. html怎么引入多个字体文件,css – 如何为同一个字体添加多个字体文件?
  4. 剖析“持续交付”:五个核心实践
  5. 用VBA提取字符串中的数字
  6. Dev-Control-gridview的属性说明
  7. 专家辩论区块链是否会取代现有支付系统
  8. vue使用echarts引入离线地图(geo.json)并切换省市(以四川为例)可下钻
  9. 基于Java毕业设计成绩分析系统源码+系统+mysql+lw文档+部署软件
  10. adb模拟按键home_【安卓试玩】电脑端adb操作手机或模拟器设备,可自行实现中控功能。 _ 一只鱼插件 - 按键精灵论坛...