Agg學習筆記

2021-09-06 16:27:10 字數 2782 閱讀 3817

很久前就聽一大牛說起agg,據說是乙個架構極度牛b的2d引擎,沉寂了許久,最後花了兩周時間走馬觀花地把它過了一遍。果然如那大牛所言,這傢伙簡直就是巧奪天工的藝術品。今天稍稍瞄了一下google扔出來的,也宣稱極度牛b的2d引擎skia,不過個人感覺整體架構大不如agg漂亮。至於兩者的效能,沒做過比較,只是聽說skia效能表現優異。

在啃這塊骨頭之前,有兩點建議:

稍了解一點2d計算機圖形學的知識。這一點在學習agg的過程中至關重要。

至少嘗試使用過一種ui框架,諸如wtl、mfc等。

很多人曾說agg將c++模板用到了爐火純青的地步,不過就我現在的認知,發現其用法也就正規正矩而已,沒用像boost那樣到處是奇技淫巧,讓人眼花繚亂,找不到北。也許我功底還不行,無法體會高人的用意。

agg對於開源的東西,找學習資料總是值得先去官網瞄瞄。agg官網的reference 不多,不過強烈建議看下這裡【 】。如果不喜歡看e文,國內有人翻譯(感謝之),質量還不錯,見這裡【 】。認真看完第一篇【basic renderers】很重要,這篇文章對agg的底層架構做了清晰的講述,包括renderbuffer和底層render,以及兩者的職責分離。這種設計相當好,因為renderbuffer並不應該知道上層使用何種顏色模式。

為了對agg有乙個總體的了解(非技術層次),可以參考這裡【 】。下面這張圖是agg總體框架的乙個總體表述

最後一項screen output可以不理會,那是os的事。agg處理的最底層是rendering buffer 。說白了rendering buffer就是一塊記憶體塊,類似bitmap。當然這也不一定,它也可以是通過os api獲得視窗螢幕的對映位址(

windows

下可以通過

gdi函式獲得),或者是framebuffer,這樣整個螢幕就可以任意虐,如果沒猜錯的話,android這鳥毛就這麼幹的。

在講renderers之前,有必要區分兩個概念,圖形和影象。簡單地講,圖形就是一些點線組成的形狀,可以通過lineto和moveto原語構造。而影象一般包含形狀和具體的顏色資訊。而readerers【渲染器】就是將圖形資訊渲染成影象。

渲染器層實際上包含三層:

顏色模式(例如

rgba

)相關的底層渲染層,這一層直接跟rendering buffer日。在這一層,每乙個畫素的大小、顏色的表示被確定。

basic render層,這一層在底層的基礎上進行簡單的裁剪支援。包括單裁剪和多區域裁剪。多區域裁剪效能和區域數量相關。

應用渲染層,這一層負責渲染具體的線段。在後面會講到,在agg中任何乙個多邊形在光柵化後都會分解成一條條水平線(span),然後依次渲染。

scanline rasterizer就是將任意多邊形(頂點源)分解成水平線,然後交給頂層渲染器渲染。在這一層也可以進行適當的裁剪。反鋸齒功能在這一層引入,agg中的畫素儲存使用浮點型,小數部分即傳說中的亞畫素。

coordinate conversion pipeline對頂點源進行座標轉換,我們熟悉的操作如放大/縮小、旋轉等操作都在這一層完成,這部分**對數學基礎和演算法要求較高,我直接死不鳥跳過。在反走樣插值功能在這一層引入。

vertex source提供光柵化的多邊形,它通過乙個迭代器來傳遞頂點。頂點源包括普通的圖形,例如矩形、橢圓、三角形,也包括字型等複雜多邊形。在linux下被廣泛應用的freetype庫就是根據字元編碼、其他字元引數來生成乙個字型多邊形。這在agg中也被支援。

前面提到的都是一些很簡單的向量繪圖操作,那麼agg對貼圖、漸變色和字型引擎的支援怎麼樣呢?

關於agg對貼圖的支援,預設包含對bmp格式的支援,agg原始碼內建了對bmp格式的解碼**,不過預設並不支援png和jpg等流行格式。我想作者可能是為了保持簡單,不想引入libpng和libjpeg。agg對所有格式除了解碼部分外,處理是一致的。

前面一直講到渲染,那何謂渲染呢,說白了就是將乙個畫素用顏色填充(或混合

blend)。而前面一直忽略了乙個問題,就是渲染時用什麼顏色來填充(準確的講,並不是填充,而是混合

(blend))特定的畫素呢?在agg中其實也包含乙個虛擬的「顏色源」,這個顏色源中的每乙個點和「頂點源「中的點一一對應。可以有多種方式構造這個虛擬的顏色源,首先可以指定一種顏色,即純色填充,其次可以通過一定演算法來生成」漸變「效果,當然也可以從中獲取。

說到,其實任何格式在處理前都必須轉化成bitmap格式,所謂的libpng和libjpeg就是幹這個事。而bitmap說到底就是乙個矩形顏色源。也許有人會疑惑,某些不是支援不規則形狀麼,例如png格式。其實png並不支援不規則形狀,而是支援alpha通道。而2d引擎在渲染時通過alpha blend後某些地方就成了透明色,使用者看起來就是不規則形狀了。

說到這裡,agg對貼圖的支援就很簡單了,從貼圖資源中獲得顏色源,然後使用它渲染特定多邊形(裁剪在這個多邊形中完成)。而對的放大/縮小、旋轉等過程類似coordinate conversion pipeline對頂點源的操作。

agg對漸變的支援和貼圖一致。

agg內建對英文本元的支援,我沒有仔細研究原始碼,不過可以推測它將所有英文本元的路徑儲存在乙個全域性(靜態)變數中,渲染前直接通過這些路徑生成頂點,因而效率極高。不過這種方式有幾個不足:

不支援未儲存的字元,很顯然不要靠他來支援」我日「。

不支援字型,因為字型路徑表述都是寫死的,除非修改源**。

更高階的字型支援來自字型引擎,agg支援windows gdi的字型介面,也可以使用第三方的字型引擎,例如freetype。agg可以通過字型引擎提供的字模來包裝乙個頂點源,因而可以將字型渲染成任意效果。此外agg也可以對字型引擎進一步封裝,實現乙個類似貼圖的介面,然後渲染多邊形,不過個人覺得這種方式很彆扭,而且渲染時不太靈活。暫時沒有測試兩種方式的效率差別。

最後,因本人水平有限,錯誤之處在所難免,歡迎指正。

AGG入門 1 VS2013編譯agg原始碼

src 目錄下所有cpp檔案 核心庫 src ctrl 目錄下所有cpp檔案 控制項庫 src platform 下對應平台目錄 win32 下的所有cpp檔案 平台支援庫 font freetype 下所有的cpp檔案 freetype字型支援庫 font win32 tt 下所有的cpp檔案 t...

python pandas中的agg函式

python中的agg函式通常用於呼叫groupby 函式之後,對資料做一些聚合操作,包括sum,min,max以及其他一些聚合函式 如下所示 df pd.read excel r d myexcel 1.xlsx df a b c 0 bob 12 451 millor 15 232 bob 34...

AGG 字型快取管理器

每次都重新讀字模是很費時的,比如前面的例子,c 裡的兩個 就讀兩次字模,效率可以想象。乙個好的辦法是把已讀出來的字模快取起來,下次再遇到這個字時就不用從字型引擎裡讀取了,agg提供的font cache manager類就是 負責這項工作的。標頭檔案 include agg font cache m...