#常见问题解答

##运行时

#错误:‘140后删除GL_ModelViewMatrix’

OsgEarth要求您链接到支持OpenGL 3+的OpenSceneGraph。如果您自己构建OSG,请确保设置CMake标志 OSG_GL3_AVAILABLE=ON

最常见的症状是如下所示的错误消息: ``` VERTEX Shader "oe_rex_morph" infolog: 0(94) : error C7616: global variable gl_ModelViewMatrix is removed after version 140 0(124) : error C7616: global variable gl_MultiTexCoord1 is removed after version 140 0(125) : error C7616: global variable gl_MultiTexCoord2 is removed after version 140 `` `

##地球文件

#在Earth文件中放置3D模型

您可以将对象放置为 Annotation 。批注必须位于 Annotations 一层。使用这种方法的一个好处是,您可以对符号系统进行建模,以设置模型的样式。此方法如下所示: ``` XML<批注>

<模型>

<position srs=“WGS84”lat=“43”long=“-100”/><style>

model:“../data/red_flag.osg.45.scale”;model-scale:auto;

</style>

</型号>

</注解> ```

另一种方法是使用 ModelLayer 如下所示: ``` XML<Model name=“My Model Layer”>

<url>location_of_my_3d_model.osgb</url><location srs=“WGS84”lat=“34.0”long=“-80.4”/>

</型号> ```

请参阅各种 feature 存储库中的地球文件,以获取更多信息和示例。

##接口说明

#使用接口放置3D模型

这个 osgEarth::GeoTransform 类继承自 osg::Transform 并将为您将地图坐标转换为OSG世界坐标。将对象放置在地理空间位置,如下所示: ``c++ GeoTransform* xform = new GeoTransform(); GeoPoint point(srs, -121.0, 34.0, 1000.0); xform->setPosition(point); ` `

如果希望对象自动钳制到地形曲面,只需取消海拔高度: ``c++ GeoTransform* xform = new GeoTransform(); GeoPoint point(srs, -121.0, 34.0); xform->setPosition(point); ` `

只要您的对象位于场景图形中 osgEarth::MapNode 。如果您的节点是 notMapNode ,您将需要手动告诉它在哪里可以找到地形: ``` xform->setTerrain(mapNode->getTerrain()); `` `

这个 srs 对象是这些示例中的 SpatialReference 坐标的一部分。对于标准配置 WGS84 经度/纬度坐标,可以通过调用 ``c++ auto srs = SpatialReference::get("wgs84"); ` `

-#型号没有纹理或照明

osgearth场景图下的所有内容都使用着色程序进行渲染。因此,在使用自己的模型(或手动创建几何体)时,需要创建明暗器组件,以便它们能够正确渲染。

osgEarth具有用于此目的的内置着色器生成器。在节点上运行着色器生成器,如下所示:

`C++ osgEarth::Registry::shaderGenerator().run( myNode ); `

之后,您的节点将包含允许osgearth正确渲染的明暗器片段,并允许它与其他osgearth功能(如天空照明)一起使用。

-#不呈现线条或批注

使用需要设置某些初始状态的着色器渲染线条。可以将此状态应用于顶级摄影机(或几何体上方的任何其他位置),如下所示:

`c++ #include <osgEarth/GLUtils> ... GLUtils::setGlobalDefaults(camera->getOrCreateStateSet()); `

对于批注 (FeatureNodePlaceNode 等)最佳做法是将Annotation节点作为 MapNode 在场景图中。您还可以将它们添加到 `AnnotationLayer `并将该图层添加到地图中。

批注需要访问 MapNode 以便正确渲染。如果不能将它们放在 MapNode ,您必须手动安装一些东西才能使它们工作:

``` C++#include<osgEarth/CullingUtils>#include<osgEarth/GLUtils>.

//手动为您的批注分配MapNode Node->setMapNode(MapNode);

//在批注上方的某个组中,安装该回调组->addCullCallback(new InstallViewportSizeUniform());

//在批注上方的某个组中,设置总账默认值GLUtils::setGlobalDefaults(group->getOrCreateStateSet()); ```

再说一遍: MapNode 自动执行所有这些操作,因此仅当您不将批注作为 MapNode

-#文本注释(LabelNode、PlaceNode)不呈现

渲染文本需要禁用OSG的小功能剔除,如下所示:

``C++ view->getCamera()->setSmallFeatureCullingPixelSize(-1.0f); ` `注意:每个摄像头都必须这样做。

-#使用Qt QOpenGLWidget时的渲染问题

在您的习俗中 QOpenGLWidget::paintGL() 方法,请在进行任何OpenSceneGraph调用之前执行以下操作:

```c++ void MyQOpenGLWidget::paintGL() {

_viewer->getCamera()->getGraphicsContext()->setDefaultFboId(defaultFramebufferObject());..。

}

在本例中 _viewer 指的是 osgViewer::Viewer ,但任何访问当前 osg::Camera 好的。

以下是更详细的解释:

Qt5 QOpenGLWidget 渲染到OpenGL帧缓冲区对象(FBO)。将OpenSceneGraph查看器嵌入到 QOpenGLWidget ,OSG并不知道那个FBO。它只是假设它正在直接渲染到显示设备。OsgEarth或OpenSceneGraph中的一些功能也使用FBO进行渲染--例如,要素覆盖和阴影--OSG无法知道它需要在之后重新激活Qt的FBO渲染目标。这可能会导致空白显示或其他渲染问题。叫唤 setDefaultFboId 让OSG知道如何正确重置渲染目标。

-##社区和支持

#使用GitHub的最佳实践是什么?

使用OSGearth存储库的最佳方法是在Github上创建自己的克隆并从该克隆中工作。为什么不直接针对主存储库工作?您可以,但是如果您需要进行更改、错误修复等,您将需要自己的克隆来发出请求。

  1. 创建自己的GitHub帐户并登录。

  2. 克隆osgearth repo。

  3. 从克隆中工作。定期将其同步到主存储库以获取最新更改。

#如何向osgEarth提交更改?

我们接受通过GitHub的贡献和错误修复 [拉取请求] (https://help.github.com/articles/using-pull-requests)机制。

首先,您需要自己的Github帐户和回购分支(见上文)。接下来,遵循以下准则:

  1. 创建一个 分支 在其中进行更改。

  2. 做出改变。

  3. 发行A 拉取请求 与OSGerth主存储库相对应。

  4. 我们将回顾 PR 包括在内。

如果我们决定不包含您的深渊翻滚,您仍然可以将其保存在我们的克隆存储库中并自己使用。这样做可以保持对osgEarth许可证的遵从性,因为您的更改仍然对公众可用-即使它们没有合并到主资料库中。

#我可以雇人帮我安装osgEarth吗?

当然了!我们鹈鹕地图公司从事的业务是支持osgEarth SDK的用户,并提供承包、培训和集成服务。与我们联系的最简单方式是通过我们的网站。 [联系人表单] (http://pelicanmapping.com/?page_id=2).)