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閱讀 230,622評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,716評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,746評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,991評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,706評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,036評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,029評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,203評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,725評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,451評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,677評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,161評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,857評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,266評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,606評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,407評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,643評論 2 380

推薦閱讀更多精彩內容