webgl学习笔记四-动画

写在前面

建议先阅读下前面我的三篇文章。

webgl学习笔记一-绘图单点

webgl学习笔记二-绘图多点

webgl学习笔记三-平移旋转缩放

  下面我们将讲解下如何让一个正方形动起来~不断擦除和重绘正方形,并且每次重绘时轻微地改变其角度。

demo

  • 吊下胃口

image

  • html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<script src="../../lib/cuon-matrix.js"></script>

<body>
<canvas id="canvas" width="200px" height="200px"></canvas>



</body>
</html>
  • JavaScript
<script>

    // 顶点着色器程序
    var VSHADER_SOURCE =
        'attribute vec4 a_Position;\n' +
        'uniform mat4 u_ModelMatrix;\n' +
        'void main() {\n' +
        '  gl_Position = u_ModelMatrix * a_Position;\n' +
        '}\n';

    // 片元着色器程序
    var FSHADER_SOURCE =
        'void main() {\n' +
        '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
        '}\n';

    // Rotation angle (degrees/second)
    var ANGLE_STEP = 45.0;

    function main() {

        // init gl
        var gl = initCanvas();

        // Initialize shaders
        var shaderProgram = initShader(gl, VSHADER_SOURCE, FSHADER_SOURCE).program;


        // Write the positions of vertices to a vertex shader
        var n = initVertexBuffers(gl, shaderProgram);
        if (n < 0) {
            console.log('Failed to set the positions of the vertices');
            return;
        }

        // Specify the color for clearing <canvas>
        gl.clearColor(0, 0, 0, 1);

        // Get storage location of u_ModelMatrix
        var u_ModelMatrix = gl.getUniformLocation(shaderProgram, 'u_ModelMatrix');
        if (!u_ModelMatrix) {
            console.log('Failed to get the storage location of u_ModelMatrix');
            return;
        }

        // Current rotation angle
        var currentAngle = 0.0;
        // Model matrix
        var modelMatrix = new Matrix4();

        // Start drawing
        var tick = function () {
            currentAngle = animate(currentAngle);  // Update the rotation angle
            draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix);   // Draw the triangle
            requestAnimationFrame(tick, canvas); // Request that the browser ?calls tick
        };
        tick();
    }

    // init cavas webgl context

    function initCanvas() {

        //获取canvas元素
        var canvas = document.getElementById('canvas');
        //获取绘制二维上下文
        var gl = canvas.getContext('webgl');
        if (!gl) {
            console.log("Failed");
            return null;
        }
        return gl;
    }

    // init shader
    function initShader(gl, vshader_source, fshader_source) {

        //编译着色器

        var vertShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vertShader, vshader_source);
        gl.compileShader(vertShader);

        var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fragShader, fshader_source);
        gl.compileShader(fragShader);

        //合并程序
        var program = gl.createProgram();
        gl.attachShader(program, vertShader);
        gl.attachShader(program, fragShader);
        gl.linkProgram(program);
        gl.useProgram(program);

        return {

            program: program
        }
    }

    function initVertexBuffers(gl, shaderProgram) {
        var vertices = new Float32Array([
            -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5
        ]);
        var n = 4;   // The number of vertices

        // Create a buffer object
        var vertexBuffer = gl.createBuffer();
        if (!vertexBuffer) {
            console.log('Failed to create the buffer object');
            return -1;
        }

        // Bind the buffer object to target
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        // Write date into the buffer object
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

        // Assign the buffer object to a_Position variable
        var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
        if (a_Position < 0) {
            console.log('Failed to get the storage location of a_Position');
            return -1;
        }
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);

        // Enable the assignment to a_Position variable
        gl.enableVertexAttribArray(a_Position);

        return n;
    }

    function draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix) {
        // Set the rotation matrix
        modelMatrix.setRotate(currentAngle, 0, 0, 1);
        modelMatrix.translate(0.35, 0, 0);

        // Pass the rotation matrix to the vertex shader
        gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);

        // Clear <canvas>
        gl.clear(gl.COLOR_BUFFER_BIT);

        // Draw the rectangle
        gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
    }

    // Last time that this function was called
    var g_last = Date.now();

    function animate(angle) {
        // Calculate the elapsed time
        var now = Date.now();
        var elapsed = now - g_last;
        g_last = now;
        // Update the current rotation angle (adjusted by the elapsed time)
        var newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0;
        return newAngle %= 360;
    }

    main();

</script>
posted @ 2017-09-03 11:27  坚守一辈子的幸福  阅读(457)  评论(0编辑  收藏  举报