在使用WebGL繪製圖形的時候,大多數狀況下,繪製一個圖形的時候,其各個圖元都是相連的。 可是在一些狀況下,咱們須要繪製圖元不相連的圖形,若是繪製的模式是gl.TRAINGLES或者gl.LINES,也是能夠達到的,可是若是繪製的模式是gl.TRAINGLE_STRIP,gl.TRAINGLE_FAN,gl.LINE_STRIP,gl.LINE_LOOP的時候,就無法在一次繪製下實現繪製多個不相連的圖元了。 通常的作法就是,經過循環,屢次繪製。好比以下代碼:web
for (var i = 0; i < num_objects; i++) { gl.drawArrays(gl.TRIANGLES,0,count); }
咱們知道,每次調用一次gl.drawArrays或者gl.drawElements方法都是一次很高的系統開銷,若是調用方法的次數不少,會致使程序的性能下降。
在OPENGL中,一種解決方法是能夠經過glMultiDrawElements方法來批量繪製多個圖元。可是這個函數在WebGL中並不支持。並且使用這個函數,仍然須要將每個分散的圖形維護一組單獨的頂點座標/紋理座標,這個是免不了的,這些數據仍然須要分開上傳,仍是會消耗必定的資源。
在WebGL2中,能夠經過圖元重啓的特性來解決這個問題。數組
前面說過,若是繪製模式是gl.TRAINGLE_STRIP,gl.TRAINGLE_FAN,gl.LINE_STRIP,gl.LINE_LOOP的時候
,繪製的全部點都是按照特定的順序被鏈接在一塊兒的,以造成複雜的圖形,也就是說最終的圖形必定是又多個相連的三角形或者線段組成,而不能是由分散的三角形或者線段組成。
若是要繪製分散的三角形或者線段,一種是前面所說的循環的方法;還有另一種方式,就是圖元重啓(Primitive restart)。
圖元重啓能夠繪製分散的三角形或者線段。所謂圖元重啓,就是當咱們使用gl.drawElements方法繪製圖形的時候,能夠在索引數組裏面指定特定的重啓標誌,當drawElements方法遇到重啓標誌的時候,就會從頭開始從新繪製一個圖元,好比下面的索引數組函數
var flag = primitiveRestartFlag; var indices = [0,1,2,3,4,flag,5,6,7,8,9]
假設繪製的模式是gl.TRAINGLE_FAN,那麼若是沒有重啓標誌,點0和點1-9 會組成一個以點0位中心的扇形,如今加入了重啓標誌,那麼點0會和點1-4組成一個以點0爲中心的扇形;以後遇到了flag,此時圖元重啓,遇到這個值的時候,WebGL不會繼續繪製圖元,而是結束上一段繪製,而後從新啓動新的繪製,也就是說用後面的索引所指定的頂點來從頭繪製一個圖形;會繪製一個以點5和點6-9組成的以點5位中心點的扇形。性能
在OPENGL中,能夠經過如下方法啓動圖元重啓功能:webgl
glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
而在WEBGL2中,圖元重啓功能默認是開啓的,並且老是開啓的,不能經過gl.enable和gl.disable方法來控制。
參考WebGL2 文檔:https://www.khronos.org/regis...rest
以前提到了圖元重啓是在遇到特定的標誌才重啓的,那麼這個標誌應該是多少了,通常而言gl.drawElements方法的索引值的類型能夠是如下幾種:code
那麼分別對應的重啓的標誌就是索引
也就是說重啓的標誌的數值就是indices數組所能容許的最大值。這個值通常來講是不會被用到的,拿來當標誌正好。資源
下面的代碼,在定義的indices數組中加入了圖元重啓標誌:文檔
/*https://www.khronos.org/registry/webgl/specs/latest/2.0/#5.18 *WebGL 2.0 behaves as though PRIMITIVE_RESTART_FIXED_INDEX were always enabled. */ var MAX_UNSIGNED_SHORT = 65535; var num_vertices = 7; var indices = new Uint16Array([ 0, 1, 2, MAX_UNSIGNED_SHORT, 2, 3, 1 ]);