把原始地图数据整理成 OpenGL 能画的三维地形数据

SceneBuilder::build() 可以理解成:把原始地图数据整理成 OpenGL 能画的三维地形数据

它的整体流程是:

SceneBuildRequest
  -> 读取高程/矢量数据
  -> 生成 TerrainMesh
  -> 塞进 SceneData
  -> 返回 SceneBuildResult

build() 主逻辑

  1. 检查数据配置是否有效
if (!request.dataset.isValid())

比如高程 TIFF 路径为空,就直接失败。

  1. 读取地图数据
MapDataResult dataResult =
        m_mapDataReader.read(request.dataset, request.mapBounds);

这里会读取:

高程 GeoTIFF
水系 SHP
机场 SHP

并按 request.mapBounds 裁剪。

  1. 判断数据是否读取成功
if (!dataResult.success)

如果高程读失败,场景就没法构建。

  1. 创建 SceneData
SceneData scene;
scene.elevationBlock = dataResult.elevationBlock;
scene.waterFeatures = dataResult.waterFeatures;
scene.airportFeatures = dataResult.airportFeatures;
scene.mapBounds = dataResult.resolvedMapBounds;

这一步只是把原始数据放进场景对象。

  1. 构建地形网格
buildTerrainMesh(scene.elevationBlock,
                 scene.mapBounds,
                 &scene.terrainMesh,
                 &meshError)

这一步最关键:把高程矩阵变成 OpenGL 更容易画的网格。

  1. 校验场景
if (!scene.isValid())

确保高程和 mesh 都有效。

  1. 返回结果
result.scene = scene;
result.success = true;

OpenGL 里什么是顶点、索引、法线

假设你的高程块是 3 x 3

A --- B --- C
|     |     |
D --- E --- F
|     |     |
G --- H --- I

每个格点都有一个地图坐标和高程。
这些点变成三维坐标后,就是 顶点 vertices

A = (x, y, z)
B = (x, y, z)
C = (x, y, z)
...

z 就是高程。

但是 OpenGL 画面通常画的是三角形,不是直接画一个“格子”。
一个四边形格子要拆成两个三角形:

A --- B
|   / |
| /   |
D --- E

可以拆成:

A, D, B
B, D, E

这些点在 vertices 数组里有编号:

A=0, B=1, C=2
D=3, E=4, F=5
G=6, H=7, I=8

所以三角形不用重复存点,只存点的编号。这就是 索引 indices

indices = {
    0, 3, 1,
    1, 3, 4
};

意思是:

第一个三角形:顶点 0、3、1
第二个三角形:顶点 1、3、4

法线 normals 是什么

法线就是每个顶点“朝哪个方向”。
它主要用于光照。

比如一块平地,法线大概朝上:

(0, 0, 1)

山坡上的法线会斜一点。OpenGL 根据法线判断:

这个面朝不朝光源?
亮一点还是暗一点?

没有法线,地形可能看起来很平、很假,或者光照不对。

TerrainMesh 里各数组含义

vertices

三维顶点坐标。OpenGL 主要画它。

indices

三角形索引。告诉 OpenGL 哪三个顶点组成一个三角形。

normals

每个顶点的法线,用于光照。

texCoords

纹理坐标。如果后面把影像贴到地形上,用它决定图片贴在哪里。

mapCoords

每个顶点对应的真实地图坐标,比如经纬度。用于调试、拾取、叠加矢量。

elevations

每个顶点的原始高程值。

validMask

标记这个点是不是有效高程:

1 有效
0 NoData / 无效

一句话总结:
build() 是把“地图数据”变成“场景数据”;buildTerrainMesh() 是把“高程像素矩阵”变成 OpenGL 能画的“三角形网格”。

posted @ 2026-05-26 16:27  twjy  阅读(5)  评论(0)    收藏  举报