1. 程式人生 > >WebGL畫一個彩色矩形

WebGL畫一個彩色矩形

     今天和大家分享一個用WebGL畫矩形(rectangle)的小Demo,也可用來繪製三角形(triangle)。本文適用於初學者掌握WebGL的基本繪圖知識,WebGL是OpenGL的Web版本,所以它的繪圖過程與OpenGL是一樣的,這裡不贅述,大家自行百度。

     今天分享的是繪製一個二維的圖形--矩形;二維是三維的基礎,二維影象的Z=0,由此,先掌握二維影象的繪製,再向三維拓展,自然水到渠成。廢話不多說,直接進入正題。

     首先,webgl不能直接畫彩色矩形的,但webgl可以直接畫三角形,畫三角形有三種畫法,分別是:gl.TRIANGLES、gl.TRIANGLE_STRIP、gl.TRIANGLE_FAN,如下圖所示。

         本文用到的的是第二種繪製三角形的方法gl.TRIANGLE_STRIP,一定要特別注意,其繪製的頂點順序為(v0,v1,v2),(v2,v1,v3),由此得到兩個三角形拼湊成一個矩形。詳細過程示意圖如下圖:

     第三種方法gl.TRIANGLE_FAN也可以達到目的,但頂點的順序要稍微調整一下,(v0,v1,v2),(v0,v2,v3)。

程式執行結果如下圖:

上面是相關原理和執行結果,接下來直接上程式碼:

triangle.js

/**
 * Created by wjh on 2017/6/26.
 */

var canvas;
var gl;

function init(){
    canvas = document.getElementById("Rectangle");//獲取canvas元素
    gl = WebGLUtils.setupWebGL(canvas);
    //判斷瀏覽器是否支援webgl
    if(!gl){
        alert("您的瀏覽器不支援WebGL!")
    }

    //矩形的定點陣列,共4個(x,y,r,g,b)
    var verticescolor = new Float32Array([
        -0.5,0.0, 0.0,1.0,0.0,
        0.0,-0.5, 0.0,0.0,1.0,//r,g,b,為顏色資訊
        0.0,0.5, 1.0,0.0,0.0,
        0.5,0.0, 0.0,0.0,0.0
    ]);

    //頂點順序索引
    var indexV = new Uint8Array([
        0,1,2,
        2,1,3
    ]);

    //設定視窗大小
    gl.viewport(0,0,canvas.width,canvas.height);
    gl.clearColor(0.0,0.0,0.0,1.0);

    //初始化著色器
    var program = initShaders(gl,"v-shader","f-shader");
    gl.useProgram(program);

    //建立快取
    var tBuffer = gl.createBuffer()//為矩形頂點建立的快取
    var iBuffer = gl.createBuffer();//為頂點索引建立的快取

    gl.bindBuffer(gl.ARRAY_BUFFER,tBuffer);//繫結緩衝區
    gl.bufferData(gl.ARRAY_BUFFER,flatten(verticescolor),gl.STATIC_DRAW);//向緩衝區寫入頂點資料

    //獲取頂點著色器中attribute變數位置
    var a_Position = gl.getAttribLocation(program,"a_Position");

    var SIZE = verticescolor.BYTES_PER_ELEMENT;
    //建立a_Position與頂點著色器attribute變數“a_Position”的關聯
    gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,SIZE*5,0);
    gl.enableVertexAttribArray(a_Position);

    var a_Color = gl.getAttribLocation(program,"a_Color");
    gl.vertexAttribPointer(a_Color,3,gl.FLOAT,false,SIZE*5,SIZE*2);
    gl.enableVertexAttribArray(a_Color);

    gl.bindBuffer(gl.ARRAY_BUFFER,iBuffer);//繫結緩衝區
    gl.bufferData(gl.ARRAY_BUFFER,flatten(indexV),gl.STATIC_DRAW);//向緩衝區寫入索引資料


    render();//執行畫圖函式
}

function render(){
    gl.clear(gl.COLOR_BUFFER_BIT);//清除螢幕
  gl.drawArrays(gl.TRIANGLE_STRIP,0,4)//畫三角形,兩個三角形拼湊成一個矩形

}
window.onload = init;//window載入init函式,最終顯示矩形

html文件如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
    <title>Rectangle</title>
    <!--頂點著色器-->
    <script id="v-shader" type="x-shader/x-vertex">
        attribute vec4 a_Position;
        attribute vec4 a_Color;
        varying vec4 v_Color;
        void main()
        {
        gl_Position = a_Position;
        v_Color = a_Color;
        }
    </script>
    <!--片元著色器-->
    <script id="f-shader" type="x-shader/x-fragment">
        precision mediump float;
        varying vec4 v_Color;
        void main()
        {
        gl_FragColor = v_Color;
        }
    </script>
    <!--呼叫js檔案-->
    <script type="text/javascript" src="../../libs/webgl-utils.js"></script>
    <script type="text/javascript" src="../../libs/MV.js"></script>
    <script type="text/javascript" src="../../libs/initShaders.js"></script>
    <script type="text/javascript" src="triangle.js"></script>
</head>
<body>
<!--定義canvas ID-->
<canvas id="Rectangle" width="618" height="618">
</canvas>
</body>
</html>