1.cesium关系草图
Viewer
DataSourceDisplay
DataSourceCollection
CustomDataSource
EntityCollection
Entity
2.
Viewer.entities.add({
rectangle : {
coordinates : Cesium.Rectangle.fromDegrees(-92.0, 20.0, -86.0, 27.0),
outline : true,
outlineColor : Cesium.Color.WHITE,
outlineWidth : 4,
stRotation : Cesium.Math.toRadians(45),
}
});
当我们调用EntityCollection.add方法时,根据参数会new一个Entity对象,此时EntityCollection充当了一个容器的作用。接着,Cesium内部通过事件的机制,在DataSourceDisplay中根据Entity类型安排具体模块,最终该模块完成对应Entity的解析工作。
3.渲染前DataSourceDisplay就拿到所有的Visualizer(可视化生产器 理解成模子)
这里添加的是Rectangle所以用到的是GeometryVisualizer:
DataSourceDisplay.defaultVisualizersCallback =function(scene, entityCluster, dataSource) {
varentities = dataSource.entities;
return[
。。。。。
new GeometryVisualizer(RectangleGeometryUpdater, scene, entities),
。。。。。
];
};
把渲染工作交接给GeometryVisualizer的_onCollectionChanged函数:
entityCollection.collectionChanged.addEventListener(GeometryVisualizer.prototype._onCollectionChanged,this)
加入到对应到队列中排队(这里的队列是_addedEntities) 针对EntityCollection的每一种队列,Visualizer分别提供了_addedObjects,_removedObjects,_changedObjects三个队列一一对接。
EntityCollection.prototype.add =function(entity) {
if(!(entityinstanceof Entity)) {
entity =new Entity(entity);
}
varid = entity.id;
if(!this._removedEntities.remove(id)) {
this._addedEntities.set(id, entity);
}
fireChangedEvent(this);
return entity;
};
总结:DataSourceDisplay初始化的时候会调用defaultVisualizersCallback,会针对所有Geometry的Type创建对应的Visualizer;EntityCollection.Add每次添加一个Entity,会通过一系列事件传递,将该Entity传递到每一个Visualizer,保存到Visualizer中_addedObjects队列中。
Viewer初始化时会绑定clock.onTick事件,确保每一帧都会调用。而其内部则调用DataSourceDisplay.update,进而遍历所有的Visualizer,调用其update方法
GeometryVisualizer.prototype.update做了三件事:
1.new Updater
function RectangleGeometryUpdater(entity, scene) {
this._options =new GeometryOptions(entity);
this._onEntityPropertyChanged(entity, 'rectangle', entity.rectangle, undefined);
}
每一个GeometryVisualizer都绑定一个具体的Updater,用来解析Entity,以Rectangle为例// Rectangle则由对应的RectangleGeometryUpdater来解析// 通过new Updater,将Entity对应的RectangleGraphics解析为RectangleGeometryUpdater的GeometryOptionsupdater =newthis._type(entity,this._scene);
this._updaters.set(id, updater);
// 根据该RectangleGeometryUpdater的材质风格创建对应的GeometryInstance,分到对应的批次队列中// 每一个批次队列中的Geometry风格相同,因此可以通过一次DrawCommand渲染该队列中所有Geometry// 目的是减少渲染次数,提高渲染效率
2.insertUpdaterIntoBatch
不准确的说(但有助于理解),GeometryOptions主要对应RectangleGraphics的几何数值,而在insertUpdaterIntoBatch中则根据RectangleGraphics的材质风格进行分组,只有材质一致的RectangleGeometryUpdater才能分到一起,进行后面的批次。比如学校分班,优等生,中等生分到不同的班级,老师根据不同班级的能力进行适当的区分,就是一种通过分组的方式来优化的思路。打组批次也是同样一个道理。
3.batch.update
之前的步骤1和步骤2,我们对当前这一帧中新增的Entity进行解析,构造成对应的GeometryInstance,放到对应的Batch队列中。比如有两个Rectangle类型的Entity,假设他们的风格一样,都是纯色的,当然颜色可能不相同,但最终都是在一个批次队列(StaticOutlineGeometryBatch)。接下来,1每一个批次队列会构建一个Primitive,包括该队列中所有的GeometryInstances,因为显卡强大的并行能力,绘制一个三角面和绘制N个三角面的所需的时间是一样的(N取决于顶点数),2所以尽可能的将多个Geometry封装成一个VBO是提高渲染性能的一个关键思路(批次&实例化)。而这个batch.update完成的前半部分,而Primitive.update则完成了最后,也是最关键的一步。
总结上面大致流程:
DataSourceDisplay.prototype.update
GeometryVisualizer.prototype.update
updater =newthis._type(entity,this._scene);
new GeometryOptions(entity);
_onEntityPropertyChanged()
insertUpdaterIntoBatch
StaticGeometryColorBatch.prototype.add
RectangleGeometryUpdater.prototype.createFillGeometryInstance
new GeometryInstance()
Batch.prototype.add
batches[i].update(time)
StaticGeometryColorBatch.prototype.update
Batch.prototype.update
new Primitive()
primitives.add(primitive);
Primitive.prototype.update
this._scene.render(currentTime);
Scene.prototype.render
function render(scene, time)
function updateAndExecuteCommands()
function executeCommandsInViewport()
function updatePrimitives()
PrimitiveCollection.prototype.update()
for (var i = 0; i < primitives.length; ++i) {
primitives[i].update(frameState);
}
loadAsynchronous(多线程创建vbo),createVertexArray以及create*这几个内容
createVertexArray
上面的Geometry已经将数据处理为indexBuffer和vertexBuffer,下面则需要将该数据结合attributes创建为vbo&vao,这个过程就是通过createVertexArray完成
createRS
创建RenderState
createSP
创建ShaderProgram
很明显,渲染主要是数据+风格,当我们满足了geometry的数据部分已经符合WebGL渲染的格式后,结合appearance封装的材质,设置对应的RenderState以及Shader和所需要的参数。最后,我们构造出最终的DrawCommand,添加到DrawCommandList中,完成最终的渲染
网友评论