function updateAndRenderPrimitives(scene) {
var frameState = scene._frameState;
// 下面是primitive.update逻辑,会单独开一个篇幅分析
scene._groundPrimitives.update(frameState);
scene._primitives.update(frameState);
updateDebugFrustumPlanes(scene);
updateShadowMaps(scene);
if (scene._globe) {
scene._globe.render(frameState);
}
}
继续进入主线的Globe.prototype.render
Globe.prototype.render = function (frameState) {
if (!this.show) {
return;
}
if (defined(this._material)) {
this._material.update(frameState.context);
}
this._surface.render(frameState);
};
再进入this._surface.render(frameState);
QuadtreePrimitive.prototype.render = function (frameState) {
var passes = frameState.passes;
var tileProvider = this._tileProvider;
if (passes.render) {
tileProvider.beginUpdate(frameState);
selectTilesForRendering(this, frameState);
createRenderCommandsForSelectedTiles(this, frameState);
tileProvider.endUpdate(frameState);
}
if (passes.pick && this._tilesToRender.length > 0) {
tileProvider.updateForPick(frameState);
}
};
这里发现四个重要的步骤
tileProvider.beginUpdate(frameState);
selectTilesForRendering(this, frameState);
createRenderCommandsForSelectedTiles(this, frameState);
tileProvider.endUpdate(frameState);
一步一步来
tileProvider.beginUpdate(frameState);
selectTilesForRendering(this, frameState);
function selectTilesForRendering(primitive, frameState) {
// 1.清空
var tilesToRender = primitive._tilesToRender;
tilesToRender.length = 0;
..
// 2.创建两个0级瓦片,分别是x=0 y=0 z=0/ x=1 y=0 z=0
if (!defined(primitive._levelZeroTiles)) {
if (tileProvider.ready) {
var tilingScheme = tileProvider.tilingScheme;
primitive._levelZeroTiles = QuadtreeTile.createLevelZeroTiles(
tilingScheme
);
var numberOfRootTiles = primitive._levelZeroTiles.length;
if (rootTraversalDetails.length < numberOfRootTiles) {
rootTraversalDetails = new Array(numberOfRootTiles);
for (i = 0; i < numberOfRootTiles; ++i) {
if (rootTraversalDetails[i] === undefined) {
rootTraversalDetails[i] = new TraversalDetails();
}
}
}
} else {
// Nothing to do until the provider is ready.
return;
}
}
...
// 3.判断tile的可见性
// Traverse in depth-first, near-to-far order.
for (i = 0, len = levelZeroTiles.length; i < len; ++i) {
tile = levelZeroTiles[i];
primitive._tileReplacementQueue.markTileRendered(tile);
if (!tile.renderable) {
queueTileLoad(primitive, primitive._tileLoadQueueHigh, tile, frameState);
++debug.tilesWaitingForChildren;
} else {
visitIfVisible(
primitive,
tile,
tileProvider,
frameState,
occluders,
false,
rootTraversalDetails[i]
);
}
}
}
createRenderCommandsForSelectedTiles(this, frameState);
function createRenderCommandsForSelectedTiles(primitive, frameState) {
var tileProvider = primitive._tileProvider;
var tilesToRender = primitive._tilesToRender;// 待渲染tile 队列
for (var i = 0, len = tilesToRender.length; i < len; ++i) {
var tile = tilesToRender[i];
tileProvider.showTileThisFrame(tile, frameState);
}
}
tileProvider.endUpdate(frameState);
主要是各个tile构建自己的DrawCommand
GlobeSurfaceTileProvider.prototype.endUpdate = function (frameState) {
...
addDrawCommandsForTile(this, tile, frameState);
}
function addDrawCommandsForTile(tileProvider, tile, frameState) {
...
if (tileProvider._drawCommands.length <= tileProvider._usedDrawCommands) {
command = new DrawCommand();
command.owner = tile;
command.cull = false;
command.boundingVolume = new BoundingSphere();
command.orientedBoundingBox = undefined;
uniformMap = createTileUniformMap(frameState, tileProvider);
tileProvider._drawCommands.push(command);
tileProvider._uniformMaps.push(uniformMap);
} else {
command = tileProvider._drawCommands[tileProvider._usedDrawCommands];
uniformMap = tileProvider._uniformMaps[tileProvider._usedDrawCommands];
}
...
}