美文网首页
webgl学习五 动画,绘制一个旋转的三角形

webgl学习五 动画,绘制一个旋转的三角形

作者: MrSwilder | 来源:发表于2020-11-23 16:43 被阅读0次
<html>

<head>
    <title>
        旋转动画
    </title>
    <script type="text/javascript" src="./lib/webgl-debug.js"></script>
    <script type="text/javascript" src="./lib/webgl-utils.js"></script>
    <script type="text/javascript" src="./lib/cuon-utils.js"></script>
    <script type="text/javascript" src="./lib/cuon-matrix.js"></script>
</head>

<body onload="main()">
    <canvas id='canvas' width="800" height="800"></canvas>
    <script type="text/javascript">
        //定义变量存储位置
        //attribute:存储顶点位置,经常变的,无精度限定
        //uniform:存储不变的值,有精度限定
        var VShader =
            "attribute vec4 a_color;\n" +
            "uniform mat4 u_rotate;\n" +
            "varying vec4 v_color;\n" +
            "attribute vec4 a_position;\n" +
            "void main(){\n" +
            "gl_Position=a_position*u_rotate;" +
            "gl_PointSize=10.0;\n" +
            "v_color=a_color;\n" +
            "}"


        var FShader =
            "precision mediump float;\n" +
            "varying vec4 v_color;\n" +
            "void main(){\n" +
            "gl_FragColor=v_color;\n" +

            "}"


        function main() {
            var canvas = document.getElementById("canvas");
            var gl = getWebGLContext(canvas);
            if (!gl) {
                console.log("获取webgl上下文失败")
                return;
            }
            if (!initShaders(gl, VShader, FShader)) {
                console.log("初始化着色器失败");
                return;
            }
            //获取着色器中的变量的地址
            var a_position = gl.getAttribLocation(gl.program, 'a_position')
            if (a_position < 0) {
                console.log("获取a_position变量地址失败")
                return;
            }

            var a_color = gl.getAttribLocation(gl.program, 'a_color')
            if (a_color < 0) {
                console.log("获取a_color变量地址失败")
                return;
            }

            var u_rotate = gl.getUniformLocation(gl.program, 'u_rotate')
            if (u_rotate < 0) {
                console.log("获取u_rotate变量地址失败")
                return;
            }


            initVertexBuffer(gl, a_position, a_color, u_rotate);

            var angle_step = 10
            var tick = function() {

                //这种方式也可以转动,但是由于请求的时间间距不同,设为固定角度会出现忽快忽慢现象
                //currentAngle+=0.5;
                //根据时间来计算应该转过的角度,这种方式比较稳定,速度一致
                currentAngle = animate(currentAngle)
                draw(currentAngle)
                requestAnimationFrame(tick)
            }
            tick()


            function draw(currentAngle) {
                var rotateMat = new Matrix4();
                rotateMat.setRotate(currentAngle, 0, 0);
                gl.uniformMatrix4fv(u_rotate, false, rotateMat.elements);
                gl.clearColor(0, 0, 0, 1)
                gl.clear(gl.COLOR_BUFFER_BIT)
                gl.drawArrays(gl.TRIANGLES, 0, 3)
            }

            var currentAngle = 0;


            var last_time = Date.now();

            function animate(currentAngle) {

                var now = Date.now();
                var time_length = now - last_time;
                last_time = now;
                var newAngle = currentAngle + (angle_step * time_length) / 1000
                return newAngle %= 360
            }


        }






        //初始化颜色缓冲区
        function initVertexBuffer(gl, a_position, a_color, u_rotate) {
            var vertexs = new Float32Array([
                1.0, 0, 0.0, 1, 0, 0, 1, -1.0, 0, 0.0, 0, 1, 0, 1,
                0, 1.0, 0.0, 0, 0, 1, 1
            ])

            //计算所占字节数
            var fsize = vertexs.BYTES_PER_ELEMENT;

            //创建缓冲区
            var vextexBuffer = gl.createBuffer();
            if (!vextexBuffer) {
                console.log("创建缓冲区失败")
                return;
            }
            //绑定到顶点缓冲区
            gl.bindBuffer(gl.ARRAY_BUFFER, vextexBuffer);
            //给顶点缓冲区传值,GL_STATIC_DRAW表示数据变得很少
            gl.bufferData(gl.ARRAY_BUFFER, vertexs, gl.STATIC_DRAW);
            //将顶点缓冲区的值给a_position变量
            gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, fsize * 7, 0);



            //开启顶点缓冲区中的Attribute类型变量a_position
            gl.enableVertexAttribArray(a_position)
                //将顶点缓冲区的值给a_color变量,7个一组,占四个数字,偏移3
            gl.vertexAttribPointer(a_color, 4, gl.FLOAT, false, fsize * 7, fsize * 3);
            gl.enableVertexAttribArray(a_color)


        }
    </script>
</body>

</html>
图片.png

相关文章

网友评论

      本文标题:webgl学习五 动画,绘制一个旋转的三角形

      本文链接:https://www.haomeiwen.com/subject/vjcliktx.html