在我的上一篇博客OSG嵌入Qt的第二种方式:使用QOpenGLWidget/QGLWidget中,在空旷的世界中只添加了cow,显得空旷,由于最近在做OSGEarth相关的开发,于是想着在OSG中怎么来添加一个数字球呢?
于是,来研究了下。发现,比我想象中的简单很多。
思路是:
- 在OSG中添加一个球,这个用osg::Sphere实现
- 给新添的球设置一个半径为地球的半径,具体的就是WGS84坐标的参考半径
- 给球添加一个纹理,当然是全球影像了
- 给球添加经纬度坐标系统,可以利用osg::CoordinateSystemNode实现
- 给球添加操作器,目前的OSG中并没有像OSGEarth那样的earth操作器,只能拿TerrainManipulator来用了。若想要OSGEarth中那样操作器的效果,只能自己写一个了。
下面的代码:
#include<osgViewer/Viewer>
#include<osgGA/TrackBallManipulator>
#include<osg/Shape>
#include<osg/ShapeDrawable>
#include<osg/Texture2D>
#include<osgDB/readFile>
int main(int argc, char*argv[])
{
osg::ArgumentParser arguments(&argc, argv);
osgViewer::Viewer viewer(arguments);
viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
viewer.setRunFrameScheme(osgViewer::Viewer::CONTINUOUS);
viewer.setCameraManipulator(new osgGA::TrackballManipulator);
osg::ref_ptr<osg::Group> m_spRoot = new osg::Group;
// 精细度设置
osg::TessellationHints* hints = new osg::TessellationHints;
hints->setDetailRatio(5.0f);
// 新建半径为WGS84参考半径的球。即地球半径为6356752.3142米
osg::ShapeDrawable* sd = new osg::ShapeDrawable(
new osg::Sphere(osg::Vec3(0.0, 0.0, 0.0), osg::WGS_84_RADIUS_POLAR), hints);
osg::Geode* geode = new osg::Geode;
geode->addDrawable(sd);
// 添加全球的纹理,图片的OSG资源Data中的图片,即使下载osg时附带的图片、模型数据资源文件夹下的图片
geode->getOrCreateStateSet()->setTextureAttributeAndModes(0,
/* 注意:这里需要读取jpg,故请保证jpg插件存在,否则读取jpg会失败。
关于怎么编译jpg插件到osg,请参见:https://blog.csdn.net/danshiming/article/details/115412956*/
new osg::Texture2D(osgDB::readImageFile(R"(E:\osg\OpenSceneGraph-Data\Images/land_shallow_topo_2048.jpg)")));
// 经纬度坐标处理
osg::CoordinateSystemNode* csn = new osg::CoordinateSystemNode;
// 设置地球坐标系统为WGS_84,即:经纬度、高程坐标系。
csn->setEllipsoidModel(new osg::EllipsoidModel());
csn->addChild(geode);
m_spRoot->addChild(csn);
viewer.setSceneData(m_spRoot);
viewer.getCamera()->setNearFarRatio(0.00001f);
viewer.run();
}
原文链接:https://blog.csdn.net/chlk118/article/details/46991369/