第二章 创建webGL设备和绘制缓冲区呈现 Context Creation and Drawing Buffer Presentation
第二章 創建webGL設備和繪制緩沖區呈現 Context Creation and Drawing Buffer Presentation
??? 在開始使用webGL API之前您先要從現有的HTML Canvas控件中創建一個WebGLRenderingContext對象,有關HTML Canvas的知識將在后邊進行介紹
WebGLRenderingContext實例對象管理OpenGL狀態并將繪圖的數據放到緩沖區里,緩沖區也需要在這時候創建
在創建緩沖區時您也可以提供配置參數,否則將使用默認參數,有關默認配置在該文檔的其它部分介紹
繪制緩沖區將在HTML混合操作開始之前立即渲染到HTML混合器中,但只有當自上次HTML混合操作之后緩沖區有修改時才會這樣
2.1 畫布元素 The canvas Element
??? 通過調用現有的HTMLCanvasElement實例的getContext("webgl")方法可以得到WebGLRenderingContext對象,參數需明確指定為"webgl",并且區分大小寫.(實際試驗時,在現階段chrome需要傳遞參數experimental-webgl才可以創建,待WEBGL規范正式頒發后應該會改回webgl)
第一次調用這個方法時,一個WebGLRenderingContext對象將被創建并返回,同時一個繪圖緩沖區也將同時創建,重復調用getContext方法并使用相關的參數'webgl',則返回上次創建的對象并不會創建新的實例
HTML Canvas規范中定義了試圖在同一個Canvas中創建兩個或以上不兼容設備時的行為
???? 如果調用時getContext方法時傳遞了第二個參數,那么這個參數一定是WebGLContextAttributes類型的對象,它包含的配置將在創建緩沖區時使用,有關WebGLContextAttributes細節請點擊這里.
???? 混合(alpha),深度(depth),模板(stencil)和抗矩齒(antialias)特性都可以接收,但都不是必須的.webGL不保證它們一定遵守它們,但是會盡最大努力去工作.
即使特性的組合不受webGL支持時,或者不受顯卡支持的時候,webGL在創建WebGLRenderingContext對象時也不會報錯.創建WebGLRenderingContext時使用的特性可以通過調用WebGLRenderingContext對象的getContextAttributes()方法獲得.透明像素(premultipliedAlpha)和緩沖區保護(preserveDrawingBuffer)功能必須實現.
???? 重復使用參數'webgl'調用getContext方法時,已經存在的WebGLContextAttributes對象,如果有的話,將被忽略.
2.2 繪制緩沖區 The Drawing Buffer
???? 在調用API方法后緩沖區將被立即渲染,所以在創建WebGLRenderingContext對象后,應緊接著定義緩沖區.下表展示了不同類型緩沖區組成的繪制緩沖區,還有它們的大小,以及是否有默認值.整個繪制緩沖區的大小取決于HTMLCanvasElement的寬和高.下表同時展示了這些緩沖區首次創建時,或者當尺寸變化后,或者創建保護緩沖區參數設置為false時,這些緩沖區將使用的默認值.
???? 如果width和height屬性沒有提供,則不論緩存沖是首次創建,還是HTMLCanvasElement對象的寬高發生變化,一個小面積的緩沖區都將被創建.這個緩沖區的建立取決于webAPI具體實現.并且不保證它們總能符合預期的長寬比例.實際使用的緩沖區的大小可以通過drawingBufferWidth 和drawingBufferHeight 屬性獲得.
By default, the buffers shall be the size shown below.可選參數WebGLContextAttributes可以用來修改無論是否已經定義的緩沖.它也可以用來定義顏色緩沖區是否包含透明通道.如果有定義透明通道那么HTML混合器將使用透明通道與頁面其余部分合并.WebGLContextAttributes對象只能在首次調用getContext時使用,在繪制緩沖區建立之后將再沒有機會修改它.
???? 在HTML混合操作之前webGL將它的繪制緩沖區渲染到HTML中,但是只有自最后混合操作后緩沖區有修改時才這樣.在繪制緩沖區渲染之前,需要確保所有的渲染操作都flush到繪制緩沖區.默認情況下,混合操作之后,繪制緩沖區的將被清空成上表中的默認值.
???? 這個默認行為可以通過WebGLContextAttributes對象的preserveDrawingBuffer屬性進行修改.如果這個標識為true,緩沖區的內容將被保留,直到用戶手動清除或者覆蓋.如果該標識為false,那么在渲染方法返回后,以此context為源圖像進行一些操作時將會導致undefined錯誤,這些操作包括readPixels方法或者toDataURL 方法.或者把它作為另外一個context的texImage2D或drawImage時(進行上述操作也將導致undefined錯誤).
雖然有時候保留緩沖區很方便,但是在某些平臺上運行時將可能導致性能損失.只要有可能就應當把它(preserveDrawingBuffer)設置為false,包括使用同步技術獲取繪制緩沖區得到繪制緩沖區內容.當需要調用一系列的方法渲染同一個繪制緩沖區時,您可以使用Framebuffer Object對象.
???? 當開發人員無法獲取緩沖區內容的一些情況下,webGL都將保證去優化您對緩沖區執行的指定的清除操作(clear operation).例如,當開發人員明確指定了清除操作,但這并非必須時(Implementations may optimize away the required implicit clear operation of the Drawing Buffer as long as a guarantee can be made that the author cannot gain access to buffer contents from another process. For instance, if the author performs an explicit clear then the implicit clear is not needed.)
2.3 WebGL視圖 The WebGL Viewport
???? OpenGL管理一個矩形的視圖作為它狀態(state)的一部分.OpenGL狀態(state)在繪制緩沖區里定義了一塊存放渲染結果的區域.webGL Context創建后,視圖緊接著進行了初始化,并且以(0,0)為源點,Canvas的寬高作為視圖的寬和高(Canvas.width,Canvas.height).
???? Canvas大小變化時,WebGL不應該影響OpenGL Viewport的狀態.
???? 如果webGL程序中沒有設置視圖的邏輯,那么它將不處理Canvas大小變化事件,下邊的EAMCScript代碼示例演示了如何通過代碼重置視圖大小.
基礎原理:自動設置viewport將會干擾程序里的手動設置,程序應該處理Canvas大小發生變化時引發的resize事件,并且重新設置視圖
2.3 透明像素,畫布接口和texImage2D Premultiplied Alpha,Canvas APIs and texImage2D
??? OpenGL API允許程序修改在渲染時使用的混合模型(blending models),基于這個特性,控制繪制緩沖區的透明值如何被解釋將成為可能(and for this reason allows control over how alpha values in the drawing buffer are interpreted;),參見WebGLContextAttributes節點中的介紹
???? HTML Canvas在實現接口toDataURL 和drawImage 必須考慮創建context時指定的透明像素參數.在對已經渲染完畢的Canvas對象調用toDataURL方法時,如果請求的圖像沒有透明像素而webGL Context的透明像素參數(premultipliedAlpha )指定為true,那么像素的值必須被撥離.顏色通道將被混合操作分離,請注意這個操作會讓原圖像失真.在繪制過程中,使用CanvasRenderingContext2D對象的drawImage方法可以得到被webGL渲染過的Canvas對象,可以在這里修改(也可以不修改)webGL的內容,這取決于CanvasRenderingContext2D 的預乘(Premultiplication)操作的需要.
預乘(Premultiplication) 定義:一個圖像用它自己的RGB通道乘以它自己的ALPHA通道
???? 把webGL渲染過的Canvas對象傳遞給texImage2D方法時,像素值可能需要根據透明像素格式進行修改,或者,像素值可能需要修改成透明格式.
http://www.lighthouse3d.com/tutorials/glsl-tutorial/?lights
http://www.khronos.org/webgl/wiki/Tutorial
http://learningwebgl.com/blog/?p=28
http://learningwebgl.com/lessons/lesson01/index.html
http://www.lighthouse3d.com/tutorials/glsl-tutorial/?lights
2 Context Creation and Drawing Buffer Presentation
Before using the WebGL API, the author must obtain a WebGLRenderingContext object for a given HTMLCanvasElement as described below. This object is used to manage OpenGL state and render to the drawing buffer, which must also be created at the time of context creation. The author may supply configuration options for this drawing buffer, otherwise default values shall be used as specified elsewhere in this document. This drawing buffer is presented to the HTML page compositor immediately before an HTML page compositing operation, but only if the drawing buffer has been modified since the last compositing operation.
2.1 The canvas Element
A WebGLRenderingContext object shall be created by calling the getContext() method of a given HTMLCanvasElement [CANVAS] object with the exact string ‘webgl’. This string is case sensitive. When called for the first time, a WebGLRenderingContext object is created and returned. Also at this time a drawing buffer shall be created. Subsequent calls to getContext() with the same string shall return the same object.
The HTML Canvas specification [CANVAS] defines the behavior when attempting to fetch two or more incompatible contexts against the same canvas element.
A second parameter may be passed to the getContext() method. If passed, this parameter shall be a WebGLContextAttributes object containing configuration parameters to be used in creating the drawing buffer. See WebGLContextAttributes for more details.
The alpha, depth, stencil and antialias attributes are requests, not requirements. The WebGL implementation does not guarantee that they will be obeyed, but should make a best effort to honor them. Combinations of attributes not supported by the WebGL implementation or graphics hardware shall not cause a failure to create a WebGLRenderingContext. The attributes actually used to create the context may be queried by the getContextAttributes() method on the WebGLRenderingContext. The premultipliedAlpha and preserveDrawingBuffer attributes must be obeyed by the WebGL implementation.
On subsequent calls to getContext() with the ‘webgl’ string, the passed WebGLContextAttributes object, if any, shall be ignored.
2.2 The Drawing Buffer
The drawing buffer into which the API calls are rendered shall be defined upon creation of the WebGLRenderingContext object. The table below shows all the buffers which make up the drawing buffer, along with their minimum sizes and whether they are defined or not by default. The size of this drawing buffer shall be determined by the width and height attributes of the HTMLCanvasElement. The table below also shows the value to which these buffers shall be cleared when first created, when the size is changed, or after presentation when the preserveDrawingBuffer context creation attribute is false.
If the requested width or height cannot be satisfied, either when the drawing buffer is first created or when the width and height attributes of theHTMLCanvasElement are changed, a drawing buffer with smaller dimensions shall be created. The dimensions actually used are implementation dependent and there is no guarantee that a buffer with the same aspect ratio will be created. The actual drawing buffer size can be obtained from the drawingBufferWidth anddrawingBufferHeight attributes.
By default, the buffers shall be the size shown below. The optional WebGLContextAttributes object may be used to change whether or not the buffers are defined. It can also be used to define whether the color buffer will include an alpha channel. If defined, the alpha channel is used by the HTML compositor to combine the color buffer with the rest of the page. The WebGLContextAttributes object is only used on the first call to getContext. No facility is provided to change the attributes of the drawing buffer after its creation.
WebGL presents its drawing buffer to the HTML page compositor immediately before a compositing operation, but only if the drawing buffer has been modified since the last compositing operation. Before the drawing buffer is presented for compositing the implementation shall ensure that all rendering operations have been flushed to the drawing buffer. By default, after compositing the contents of the drawing buffer shall be cleared to their default values, as shown in the table above.
This default behavior can be changed by setting the preserveDrawingBuffer attribute of the WebGLContextAttributes object. If this flag is true, the contents of the drawing buffer shall be preserved until the author either clears or overwrites them. If this flag is false, attempting to perform operations using this context as a source image after the rendering function has returned can lead to undefined behavior. This includes readPixels or toDataURL calls, or using this context as the source image of another context's texImage2D or drawImage call.
While it is sometimes desirable to preserve the drawing buffer, it can cause significant performance loss on some platforms. Whenever possible this flag should remain false and other techniques used. Techniques like synchronous drawing buffer access (e.g., calling readPixels or toDataURL in the same function that renders to the drawing buffer) can be used to get the contents of the drawing buffer. If the author needs to render to the same drawing buffer over a series of calls, a Framebuffer Object can be used.
Implementations may optimize away the required implicit clear operation of the Drawing Buffer as long as a guarantee can be made that the author cannot gain access to buffer contents from another process. For instance, if the author performs an explicit clear then the implicit clear is not needed.
2.3 The WebGL Viewport
OpenGL manages a rectangular viewport as part of its state which defines the placement of the rendering results in the drawing buffer. Upon creation of the WebGL context, the viewport is initialized to a rectangle with origin at (0, 0) and width and height equal to (canvas.width, canvas.height).
A WebGL implementation shall not affect the state of the OpenGL viewport in response to resizing of the canvas element.
Note that if a WebGL program does not contain logic to set the viewport, it will not properly handle the case where the canvas is resized. The following ECMAScript example illustrates how a WebGL program might resize the canvas programmatically.
Rationale: automatically setting the viewport will interfere with applications that set it manually. Applications are expected to use onresize handlers to respond to changes in size of the canvas and set the OpenGL viewport in turn.
2.4 Premultiplied Alpha, Canvas APIs and texImage2D
The OpenGL API allows the application to modify the blending modes used during rendering, and for this reason allows control over how alpha values in the drawing buffer are interpreted; see the premultipliedAlpha parameter in the WebGLContextAttributes section.
The HTML Canvas APIs toDataURL and drawImage must respect the premultipliedAlpha context creation parameter. When toDataURL is called against a Canvas into which WebGL content is being rendered, then if the requested image format does not specify premultiplied alpha and the WebGL context has thepremultipliedAlpha parameter set to true, then the pixel values must be de-multiplied; i.e., the color channels are divided by the alpha channel. Note that this operation is lossy.
Passing a WebGL-rendered Canvas to the drawImage method of CanvasRenderingContext2D may or may not need to modify the the rendered WebGL content during the drawing operation, depending on the premultiplication needs of the CanvasRenderingContext2D implementation.
When passing a WebGL-rendered Canvas to the texImage2D API, then depending on the setting of the premultipliedAlpha context creation parameter of the passed canvas and the UNPACK_PREMULTIPLY_ALPHA_WEBGL pixel store parameter of the destination WebGL context, the pixel data may need to be changed to or from premultiplied form.
總結
以上是生活随笔為你收集整理的第二章 创建webGL设备和绘制缓冲区呈现 Context Creation and Drawing Buffer Presentation的全部內容,希望文章能夠幫你解決所遇到的問題。