WebGL原生API及繪圖基礎

WebGL也是HTML5規範的一部分,從本質上講它是一個增強型的圖形繪製庫,與HTML5的2D Canvas類似,只是WebGL是一個三維的繪圖標準,並且同樣使用了canvas元素。使用WebGL進行圖形渲染至少要經歷以下步驟:
1. 創建一個畫布元素。
2. 獲取畫布的上下文。
3. 初始化視口。
4. 創建一個或多個包含渲染數據的數組(通常是頂點數組)。
5. 創建一個或多個矩陣,將頂點數組變換到屏幕空間。
6. 創建一個或多個着色器來實現繪製算法。
7. 使用參數初始化着色器。
8. 繪製。


一、畫布元素與繪製上下文
使用WebGL只需要創建一個canvas元素,通過與該元素關聯的DOM對象獲取WebGL上下文:

function initWebGL(canvas){
    var gl;
    try{
        gl=canvas.getContex("expremental-webgl");
    }
    catch(e){
        var msg = "Error creating webgl context: "+ e.toString();
        alert(msg);
        throw  Error(msg);
    }
    return gl;
}

二、視口
獲取了WebGL上下文就需要指定在哪裏繪製圖形,這就稱爲視口(viewport),調用gl的viewport()函數進行視口的初始化:

function initViewport(gl,canvas){
    gl.viewport(0,0,canvas.width,canvas.height);
}

其中的四個參數爲畫布左上角和右下角的座標。
三、Buffer、ArrayBuffer和類型化數組
WebGL的繪製是由圖元組成的,圖元的種類包括三角形(三角形數組)、三角形帶(triangle strip)、點和線。圖元使用的數據數組被稱爲Buffer,定義了頂點的位置。以下代碼定義了一個1×1的正方形頂點數組。

function createSquare(gl){
    var vertexBuffer;
    vertexBuffer = gl.createBuffer();//創建頂點緩衝區
    gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);//將創建的緩衝區綁定到gl數組
    var vertex = [//定義四個頂點的位置
        .5, .5, 0.0,
        -.5,.5, 0.0,
        .5, -.5, 0.0,
        -.5, -.5, 0.0
    ];
    gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertex),gl.STATIC_DRAW);//綁定位置數據到gl數組
    var square = {buffer:vertexBuffer,vertSize:3,nVerts:4,primtype:gl.TRIANGLE_TRIP};
    return square;
}

其中vertSize和nVerts分別定義了一個頂點中元素的個數和頂點的個數,此例中表明有4個頂點,每個頂點3個元素。Float32Array是爲了WebGL專門引入瀏覽器的數據類型,稱爲類型化數組,是ArrayBuffer的一種,用於js中存儲二進制數據。
四、矩陣
在繪製之前需要建立兩個矩陣——模型視圖矩陣(modelview matrix)和投影矩陣(projection martrix)。模型視圖矩陣用於定義3D座標系中正方形相對於相機的位置,投影矩陣用於在着色器中將相機空間中的3D座標準環衛繪製視口的2D座標。在本例中對模型的變換是沿-z軸平移3.333個單位,即遠離相機3.333個單位,投影矩陣定義了一個45°的相機視野。

function initMatrices(){
    modelViewMatrix = new Float32Array(
        [1,0,0,0,
         0,1,0,0,
         0,0,1,0,
         0,0,-3.333,1
         ]);
    projectionMatrix = new Float32Array([
        2.41421,0,0,0,
        0,2.41421,0,0,
        0,0,-1.002002,-1,
        0,0,-0.2002002,0
    ]);
}

在一般開發中,很少有人會自己動手計算投影矩陣,因爲一半計算非常複雜,大多都時通過框架來完成。比較有名的框架爲glMatrix,專門在js中進行矩陣的運算。
五、着色器
着色器是一小段由類C的高級語言編寫的,一般爲GLSL ES語言,每個需要繪製的物體都要提供着色器,一個着色器可以應用於多個物體。在實際應用中通常只提供一個着色器,通過不同的參數多次複用。
着色器包括兩個部分——頂點着色器(vertex shader)和片元着色器(fragment shader),後者也被稱爲像素着色器。頂點着色器負責將物體的座標轉換到2D空間去,片元着色器負責將顏色輸出到每個轉換後的頂點像素。顏色的輸出可以爲純色、紋理、光源或者材質。

var vertexShaderSource =
    "   attribute vec3 vertexPos;\n"+
    "   uniform mat4 modelViewMatrix;\n"+
    "   uniform mat4 projectionMatrix;\n"+
    "   void main(void) {\n"+
    "       //返回變換並投影后的頂點數據\n"+
    "      gl_Position = projectionMatrix*modelViewMatrix*\n"+
    "          vec4(vertexPos,1.0);\n"+
    "   }\n";
var fragmentShaderSource =
    "   void main(void) {\n"+
    "       //返回像素顏色,這裏爲白色\n"+
    "      gl_FragColor = vec4(1.0,1.0,1.0,1.0);\n"+
    "   }\n";

六、繪製圖元
我們定義了一個函數draw()來完成圖元的繪製,在該函數中我們將接管上面定義的WebGL上下文以及正方形對象。首先函數會清理一下畫布並用黑色填充作爲背景色。將頂點數組綁定到上下文中,使用着色器並把頂點數組和矩陣作爲輸入傳給着色器。最後調用WebGL的drawArrays()繪製正方形。

function draw(gl,obj){
    //用黑色清空背景
    gl.clearColor(0.0,0.0,0.0,1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);

    //設置頂點數組
    gl.bindBuffer(gl.ARRAY_BUFFER,obj.buffer);

    //設置着色器
    gl.useProgram(shaderProgram);

    //設置着色器參數:頂點座標、投影矩陣和模型視圖矩陣
    gl.vertexAttribPointer(shaderVertexPositionAttribute,obj.vertSize,gl.FLOAT,false,0,0);
    gl.uniformMatrix4fv(shaderProjectionMatrixUniform,false,projectionMatrix);
    gl.uniformMatrix4fv(shaderModelViewMatrixUniform,false,modelViewMatrix);

    //繪製物體
    gl.drawArrays(obj.primtype,0,obj.nVerts);

}

最終的繪製結果如圖所示:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章