Cesium中Entity的渲染流程草图

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中,完成最终的渲染

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355

推荐阅读更多精彩内容