2011-06-09 224 views
52

我目前正在調查從使用OpenGL和OpenGL ES SVG文件渲染矢量圖形的可能性。我打算針對Windows和Android。我的理想解決方案是擁有一個最小的C庫,可以從給定的SVG文件生成多邊形三角剖分。這會生成標準的OpenGL或OpenGL ES調用,並在重繪時使用顯示列表或vbo進行優化。我只需繪製一個顯示列表,在翻譯和旋轉後繪製矢量圖像,以便將其與其他OpenGL調用混合使用。渲染SVG支持OpenGL(和OpenGL ES)

到目前爲止,我看到的建議是首先使用QT或開羅。 - 這不是一個選項,因爲我希望管理自己的OpenGL上下文,而不需要膨脹的庫(在我嘗試實現的上下文中)。這也不適用於Android。

第二種選擇是使用渲染到紋理的庫。雖然這對靜態矢量圖形來說可能是好的,但對於經常出現縮放和旋轉的遊戲來說,這並不是一種有效或可行的選擇。

第三,有可能使用OpenVG。 OpenVG規範有一些開源實現(ShivaVG等),但我還沒有找到一個能夠在運行時從給定的SVG文件生成相應OpenVG調用的庫,並且我無法看到如何將其優化爲我們可能希望用顯示列表或vbo。

所有三種方法都受到限制。如果沒有其他解決方案存在,我認爲最有希望的選擇是使用OpenVG實現。所以我的問題是,有沒有圖書館可以做我想要的,或接近我想要的?如果不是,有沒有充分的理由爲什麼不呢?試圖從頭開始做這件事情會更好嗎?

+0

解析路徑的svg文件並不困難。檢查以下繪製二次貝塞爾曲線。 //www.opengl.org/resources/code/samples/redbook/bezcurve.c – 2011-06-09 06:51:35

+0

@Grady glEvalCoord在OpenGL ES中不存在;而GLU,它的鑲嵌器也不重要,例如凸多邊形。 @ me232很好的問題,upvote'd&favorite'd – Calvin1602 2011-06-09 08:29:02

+0

+1良好的研究和很好的框架問題 – 2011-06-09 10:19:42

回答

4

http://shivavg.svn.sourceforge.net/viewvc/shivavg/trunk/src/shPipeline.c?revision=14&view=markup

static void shDrawVertices(SHPath *p, GLenum mode) 
{ 
int start = 0; 
int size = 0; 

/* We separate vertex arrays by contours to properly 
handle the fill modes */ 
glEnableClientState(GL_VERTEX_ARRAY); 
glVertexPointer(2, GL_FLOAT, sizeof(SHVertex), p->vertices.items); 

while (start < p->vertices.size) { 
size = p->vertices.items[start].flags; 
glDrawArrays(mode, start, size); 
start += size; 
} 

glDisableClientState(GL_VERTEX_ARRAY); 
} 

所以它不使用VBO。所以我建議製作自己的SVG解析器/使用預先製作的解析器,並將調用轉發給ShivaVG。

你仍然有ShivaVG是在C(而不是在Java中)的問題,並創建OpenGL上下文(而不是opengles,如果我正確讀取的代碼)。所以,即使你使用Android的NDK進行編譯,你也必須修改代碼(例如,我已經看到了幾個glVertex3f,但似乎並不太需要......希望最好)。當然,另一種選擇是將代碼從C移植到Java。也許並不像你想象的那麼痛苦。

祝你好運!

+2

謝謝,我會看看這個,我感到驚訝的是,考慮到對硬件加速矢量圖形的需求以及OpenVG設計時考慮到移動設備的事實,並沒有一個可以實現的實現,我意識到用C#編寫的項目,試圖非常類似地做一些事情成功的結果[http://neuronspew.wordpress.com/category/svg-game-engine-project/](http://neuronspew.wordpress.com/category/svg-game-engine-project/)我會如果我能做到這一點,請務必公開我的代碼。 – 2011-06-10 01:39:22

+1

謝謝!請在完成該任務後更新此主題? – Calvin1602 2011-06-10 08:56:03

11

退房MonkVG像的OpenGL ES的頂部API實現的OpenVG的。

另外,SVG呈現在OpenVG的(MonkVG)結帳MonkSVG的頂部。

MonkVG已建成的iOS,OSX和Android平臺。

我這兩個庫的作者,並樂意回答任何問題。

+1

嗨彌迦。我找到了MonkVG的Windows項目,並設法使用VS2010進行構建。是否有任何適用於Windows的工作示例?我試圖效法這個例子。我手動創建自己的窗口和上下文,但是我想如果你有一個基於GLUT的例子,那麼基於GLUT的解決方案就沒有問題。 – 2012-01-20 09:32:49

7

我目前正在研究從SVG文件渲染矢量圖形>使用OpenGL和OpenGL ES的可能性。我打算針對Windows和Android。我的理想的解決方案 將有一個生成從給定 SVG文件中的多邊形三角最小的C庫。然後這將生成標準的OpenGL或OpenGL ES調用,並在重繪時使用display或vbo進行優化。我只需繪製一個顯示列表,以在翻譯和旋轉後繪製矢量圖像 ,從而可以將其與其他OpenGL>調用混合使用。

如果您只想將SVG矢量形狀轉換爲OpenGL | ES,那麼我建議您自己做解析器和邏輯。請注意,SVG是一個龐大的規格,具有不同的功能,如繪製服務器(漸變,圖案...),參考,過濾器,剪裁,字體處理,動畫,腳本,鏈接等。

如果你想要滿svg支持,那麼有一個名爲egueb(尤其是esvg)的庫,它使用enesim(一個具有軟件和opengl後端的渲染庫)來繪製。在大多數情況下,它使用着色器,並且所有東西都被渲染成紋理,該庫非常靈活,可以讓您適應特定的需求,例如修改渲染的場景,轉換等等。因爲gl繪圖始終是在紋理中完成的。

到目前爲止,我看到的建議是首先使用QT或開羅。 - 這不是一個選項 ,因爲我希望管理自己的OpenGL上下文而不需要膨脹的庫(在我嘗試實現的 上下文中)。這也不適用於Android。

第二種選擇是使用渲染到紋理的庫。雖然對於 靜態矢量圖形來說這可能是好的,但對於經常出現縮放比例和旋轉的遊戲來說,這並不是一個有效或可行的選項。

在GL後端的特定情況下,enesim不會創建GLX(或任何其他窗口依賴於上下文),你必須提供它,所以它能夠很好的滿足您的情況,因爲它僅使用GL調用。

唯一的缺點是該庫在gl支持或全面的SVG規範支持方面尚未完成,但根據您的需求,在我看來,這是一個不錯的選擇。

+0

你用什麼算法將三次貝塞爾曲線(路徑)轉換爲OpenGL?怎麼樣消除鋸齒 – Raks 2013-06-23 14:32:22

12

我的答案會關於顯示矢量圖形的OpenGL wtih一般,因爲這個問題的解決方案都可以支持,而平凡SVG特別是,雖然沒有支持動畫SVGs(SMIL)。由於沒有關於動畫的說法,我假設這個問題只包含靜態SVG。首先,我不打擾任何OpenVG,即使使用MonkVG,這可能是最現代的,儘管不完整的實現。 OpenVG委員會已於2011年結束,大多數(如果不是所有的話)實施都是棄用軟件或最好的遺留軟件。

2011年以來,技術狀態是馬克·基爾加德的嬰兒,NV_path_rendering,這也是目前唯一的一個供應商(英偉達)你可能已經從它的名字已經猜到了擴展。還有一些對很多材料:

當然你也可以負載SVGs和這樣https://www.youtube.com/watch?v=bCrohG6PJQE的。它們還支持路徑的PostScript語法。你也可以混合路徑與其他的OpenGL(3D)的東西呈現,作爲全世界展示:

NV_path_rendering現在所使用的谷歌的場景,當可用的背後Skia的庫。 (Nvidia在2013年底和2014年提供了代碼。)其中一位開羅開發者(也是英特爾員工)似乎也很喜歡它http://lists.cairographics.org/archives/cairo/2013-March/024134.html,儘管我還沒有意識到開羅使用任何具體措施NV_path_rendering。

NV_path_rendering在固定管道上有一些小的依賴關係,所以它在OpenGL ES中可能有點麻煩。此問題記錄在上面鏈接的官方擴展文檔中。有關解決方法參見例如什麼Skia的/鉻做:具有更小(或徹頭徹尾的無)供應商的支持或學術浮華https://code.google.com/p/chromium/issues/detail?id=344330

一個暴發戶是NanoVG,這是目前開發和維護。 (https://github.com/memononen/nanovg)考慮到隨着時間的推移,OpenGL上2D庫的數量已經逐漸增加,你用一種不被主要供應商支持的東西大打賭,以我的愚見。

5

需要說的是,使用OpenGL或OpenGL ES渲染SVG或OpenVG從根本上說是一個壞主意。 OpenVG的實現有如此緩慢和很大程度上被放棄的原因。根據OpenGL的要求,將路徑(所有SVG/OpenVG渲染的基礎)鑲嵌到三角形列表中的過程基本上是緩慢而低效的。它基本上需要在3D渲染管道中插入排序/搜索算法,這會削弱性能。還有一個問題是動態內存分配方案是必需的,因爲數據集的大小是未知的,因爲SVG對路徑幾何的複雜性沒有限制。一個非常糟糕的設計。

SVG和OpenVG由開發人員創建,他們對現代3D圖形硬件引擎實際上的工作原理(三角列表)缺乏瞭解。它們被創建成爲Adobe Flash的開放替代品,它也具有相同的有缺陷的架構,這使得Flash在業界出現難以預測的性能。

我的建議是重新考慮你的設計,並直接使用OpenGL三角形列表。您可能需要編寫更多的代碼,但是您的應用程序的性能會提高一千倍左右,而且您可以比其他人更容易地調試您的代碼。

+0

只是一個說明:有很多方法可以用OpenGL繪製SVG,並且鑲嵌到三角形的路徑可能更糟糕。使用着色器怎麼樣? – 2016-11-11 07:54:58

1

你可以看看AmanithVG,他們似乎已經實現了一個好的路徑 - >三角形管道。我已經嘗試了iOS GL虎示例,並且似乎三角測量不是真正的瓶頸。