WebGL旋轉

在本章中,我們將舉一個例子來演示如何使用WebGL的來旋轉三角形。

示例 - 旋轉三角形


下面的程序展示瞭如何使用 WebGL 來旋轉三角形。

  <script>

     /\*=================Creating a canvas=========================\*/
     var canvas = document.getElementById('my\_Canvas');
     gl = canvas.getContext('experimental-webgl');

     /\*===========Defining and storing the geometry==============\*/

     var vertices = \[ -1,-1,-1, 1,-1,-1, 1, 1,-1 \];
     var colors = \[ 1,1,1, 1,1,1, 1,1,1 \];
     var indices = \[ 0,1,2 \];

     //Create and store data into vertex buffer
     var vertex\_buffer = gl.createBuffer ();
     gl.bindBuffer(gl.ARRAY\_BUFFER, vertex\_buffer);
     gl.bufferData(gl.ARRAY\_BUFFER, new Float32Array(vertices), gl.STATIC\_DRAW);

     //Create and store data into color buffer
     var color\_buffer = gl.createBuffer ();
     gl.bindBuffer(gl.ARRAY\_BUFFER, color\_buffer);
     gl.bufferData(gl.ARRAY\_BUFFER, new Float32Array(colors), gl.STATIC\_DRAW);

     //Create and store data into index buffer
     var index\_buffer = gl.createBuffer ();
     gl.bindBuffer(gl.ELEMENT\_ARRAY\_BUFFER, index\_buffer);
     gl.bufferData(gl.ELEMENT\_ARRAY\_BUFFER, new Uint16Array(indices), gl.STATIC\_DRAW);

     /\*==========================Shaders=========================\*/

     var vertCode = 'attribute vec3 position;'+
        'uniform mat4 Pmatrix;'+
        'uniform mat4 Vmatrix;'+
        'uniform mat4 Mmatrix;'+
        'attribute vec3 color;'+//the color of the point
        'varying vec3 vColor;'+

        'void main(void) { '+//pre-built function
           'gl\_Position = Pmatrix\*Vmatrix\*Mmatrix\*vec4(position, 1.);'+
           'vColor = color;'+
        '}';

     var fragCode = 'precision mediump float;'+
        'varying vec3 vColor;'+
        'void main(void) {'+
           'gl\_FragColor = vec4(vColor, 1.);'+
        '}';

     var vertShader = gl.createShader(gl.VERTEX\_SHADER);
     gl.shaderSource(vertShader, vertCode);
     gl.compileShader(vertShader);

     var fragShader = gl.createShader(gl.FRAGMENT\_SHADER);
     gl.shaderSource(fragShader, fragCode);
     gl.compileShader(fragShader);

     var shaderProgram = gl.createProgram();
     gl.attachShader(shaderProgram, vertShader);
     gl.attachShader(shaderProgram, fragShader);
     gl.linkProgram(shaderProgram);

     /\*===========associating attributes to vertex shader ============\*/

     var Pmatrix = gl.getUniformLocation(shaderProgram, "Pmatrix");
     var Vmatrix = gl.getUniformLocation(shaderProgram, "Vmatrix");
     var Mmatrix = gl.getUniformLocation(shaderProgram, "Mmatrix");
     gl.bindBuffer(gl.ARRAY\_BUFFER, vertex\_buffer);

     var position = gl.getAttribLocation(shaderProgram, "position");
     gl.vertexAttribTutorialser(position, 3, gl.FLOAT, false,0,0) ; //position
     gl.enableVertexAttribArray(position);
     gl.bindBuffer(gl.ARRAY\_BUFFER, color\_buffer);

     var color = gl.getAttribLocation(shaderProgram, "color");
     gl.vertexAttribTutorialser(color, 3, gl.FLOAT, false,0,0) ; //color
     gl.enableVertexAttribArray(color);
     gl.useProgram(shaderProgram);

     /\*========================= MATRIX ========================= \*/

     function get\_projection(angle, a, zMin, zMax) {
        var ang = Math.tan((angle\*.5)\*Math.PI/180);//angle\*.5
        return \[
           0.5/ang, 0 , 0, 0,
           0, 0.5\*a/ang, 0, 0,
           0, 0, -(zMax+zMin)/(zMax-zMin), -1,
           0, 0, (-2\*zMax\*zMin)/(zMax-zMin), 0
        \];
     }

     var proj\_matrix = get\_projection(40, canvas.width/canvas.height, 1, 100);
     var mov\_matrix = \[1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1\];
     var view\_matrix = \[1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1\];

     //translating z
     view\_matrix\[14\] = view\_matrix\[14\]-6; //zoom

     /\*=======================rotation========================\*/
     function rotateZ(m, angle) {
        var c = Math.cos(angle);
        var s = Math.sin(angle);
        var mv0 = m\[0\], mv4 = m\[4\], mv8 = m\[8\]; 

        m\[0\] = c\*m\[0\]-s\*m\[1\];
        m\[4\] = c\*m\[4\]-s\*m\[5\];
        m\[8\] = c\*m\[8\]-s\*m\[9\];
        m\[1\] = c\*m\[1\]+s\*mv0;
        m\[5\] = c\*m\[5\]+s\*mv4;
        m\[9\] = c\*m\[9\]+s\*mv8;
     }

     /\*=================Drawing===========================\*/

     var time\_old = 0;
     var animate = function(time) {
        var dt = time-time\_old;
        rotateZ(mov\_matrix, dt\*0.002);
        time\_old = time;

        gl.enable(gl.DEPTH\_TEST);
        gl.depthFunc(gl.LEQUAL);
        gl.clearColor(0.5, 0.5, 0.5, 0.9);
        gl.clearDepth(1.0);
        gl.viewport(0.0, 0.0, canvas.width, canvas.height);
        gl.clear(gl.COLOR\_BUFFER\_BIT | gl.DEPTH\_BUFFER\_BIT);

        gl.uniformMatrix4fv(Pmatrix, false, proj\_matrix);
        gl.uniformMatrix4fv(Vmatrix, false, view\_matrix);
        gl.uniformMatrix4fv(Mmatrix, false, mov\_matrix);

        gl.bindBuffer(gl.ELEMENT\_ARRAY\_BUFFER, index\_buffer);
        gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED\_SHORT, 0);
        window.requestAnimationFrame(animate);
     }

     animate(0);

  </script>

這將產生以下結果(這裏只能放靜態圖片,具體旋轉效果可自己運行代碼觀察) -

WebGL旋轉