osgEarth示例分析——osgearth_lights
前言
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相关推荐
- osgEarth示例分析——osgearth_annotation
前言 本章为osgearth_annotation示例分析,示例中采用osgEarth提供的类,绘制标签.线.billboard.遮盖图.墙等内容. 运行时,在生成的可执行路径下,打开命令框,输入: ...
- osgEarth示例分析——osgearth_skyview
前言 本示例分析osgearth操作深空场景,或者是银河系场景,可以想象人拿着相机站在地球表面上观看天空/银河系的场景. 重点是相机操作器的使用. 在命令框输入执行程序,在data路径下有加载的图,且 ...
- osgEarth示例分析——osgearth_manip
前言 本示例主要演示osgEarth的事件处理的用法,内容比较多,这部分功能也很重要. 输入命令依然采用china-simple.earth的示例,加上了模型,但是模型并没有看到,可能是因为模型没有放 ...
- osgEarth示例分析——osgearth_elevation
前言 osgearth_elevation示例,展示了如何通过点击地球获取不同定义下的高程数据.包括:MSL高程.HAE高程.EGM96高程.点击按钮,可以移除高程图层. MSL高程:是mean se ...
- osgEarth示例分析——osgearth_graticule
前言 本示例最具有借鉴的功能:绘制网格.网格上的文字显示.拾取地球的坐标.在地球网格示例中,可以设置4种网格.执行命令如下: // --geodetic osgearth_graticuled.exe ...
- osgEarth示例分析——osgearth_srstest
前言 osgearth_srstest示例,主要涉及到两个坐标系转换,wgs84→egm96 wgs84→plate-carre wgs84:World Geodetic System 1984,是 ...
- osgEarth示例分析——osgearth_eci
前言 osgearth_eci示例,展示了J2000的天体坐标系和ECEF地固系的转换,绘制坐标系,以及读取卫星参数绘制卫星的功能.绘制卫星轨迹,添加差值效果和未添加差值的效果. 关于卫星两行根数的数 ...
- osgEarth示例分析——osgearth_terrainprofile
前言 osgearth_terrainprofile示例,涉及到一个新的类 TerrainProfileCalculator(地形轮廓计算器类),用来计算两个点连线之间的地形数据.左下角会根据点击的起 ...
- osgEarth示例分析——osgearth_features
前言 osgearth_features示例,主要演示如何通过代码方式加载shp文件,并设置其样式.在执行时,通过不同 的命令,得到不一样的效果. cmd执行命令: // rasterize 光栅化, ...
最新文章
- 代码整洁之道(Clean Code)- 读书笔记
- C语言结构体描述BMP的文件格式
- dataframe去重复 python_python – 在DataFrame中组合重复的列
- 微信公众开放平台开发04---百度BAE,java应用部署服务器,jetty了解
- mysql之配置mysql使其可用python远程控制
- mysql删除重复记录只保留一条
- getmethodid( android/widget/toast ),Android功能实现-Go语言中文社区
- C语言 一个字符串翻转函数的编写
- Navicat for mysql 破解版,安装与破解
- 通讯录_你有多久没翻过通讯录了?
- 小米路由的IPv6支持教程(纯转保存)
- 显卡更新显示计算机无法识别,电脑无法识别独立显卡
- 华大基因首席运营官张凌离职
- Chrome浏览器更新失败
- 五花八门的垂直搜索引擎
- 特殊字符在英语中的读法
- Tecplot云图——数据文本格式1
- android打电话的intent,如何在Android中使用intent打电话?
- 威联通NAS安装openwrt旁路由
- WakeOnLAN下载
热门文章
- To be contine ,NW NMM backup sqlserver failed.
- 海康威视硬盘录像机无法删除通道问题
- html怎么引入多个字体文件,css – 如何为同一个字体添加多个字体文件?
- 剖析“持续交付”:五个核心实践
- 用VBA提取字符串中的数字
- Dev-Control-gridview的属性说明
- 专家辩论区块链是否会取代现有支付系统
- vue使用echarts引入离线地图(geo.json)并切换省市(以四川为例)可下钻
- 基于Java毕业设计成绩分析系统源码+系统+mysql+lw文档+部署软件
- adb模拟按键home_【安卓试玩】电脑端adb操作手机或模拟器设备,可自行实现中控功能。 _ 一只鱼插件 - 按键精灵论坛...