zoukankan      html  css  js  c++  java
  • webgl学习笔记三-平移旋转缩放

    写在前面

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

    webgl学习笔记一-绘图单点

    webgl学习笔记二-绘图多点

    平移

    1、关键点说明

    • 顶点着色器需要加上 uniform vec4 u_Translation, 存储平移的坐标矢量。

    • 顶点坐标位置 : gl_Position = a_Position + u_Translation

    • 平移API : gl.uniform4f(u_Translation, Tx, Ty, Tz, 0.0);

    2、demo

    • html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <canvas id="canvas" width="200px" height="200px"></canvas>
    
    
    </body>
    </html>
    
    • JavaScript
    
    <script>
        function main() {
            //顶点着色器程序
            var VSHADER_SOURCE =
                'attribute vec4 a_Position;
    ' +
                'uniform vec4 u_Translation;
    ' +
                'void main() {
    ' +
                '  gl_Position = a_Position + u_Translation;
    ' +
                '}
    ';
    
            //片元着色器
            var FSHADER_SOURCE =
                'void main() {
    ' +
                '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    ' +
                '}
    ';
    
    
            //获取canvas元素
            var canvas = document.getElementById('canvas');
            //获取绘制二维上下文
            var gl = canvas.getContext('webgl');
            if (!gl) {
                console.log("Failed");
                return;
            }
            //编译着色器
            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 shaderProgram = gl.createProgram();
            gl.attachShader(shaderProgram, vertShader);
            gl.attachShader(shaderProgram, fragShader);
            gl.linkProgram(shaderProgram);
            gl.useProgram(shaderProgram);
    
            //获取坐标点
            var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
    
            if (a_Position < 0) {
                console.log('Failed to get the storage location of a_Position');
                return;
            }
    
            var n = initBuffers(gl, shaderProgram);
    
            if (n < 0) {
                console.log('Failed to set the positions');
                return;
            }
    
    
    
            // 清除指定<画布>的颜色
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
    
            // 清空 <canvas>
            gl.clear(gl.COLOR_BUFFER_BIT);
    
            gl.drawArrays(gl.TRIANGLES, 0, n);
        }
    
        function opt(gl, shaderProgram) {
            var Tx = 0.5, Ty = 0.5, Tz = 0.0;
    
            var u_Translation = gl.getUniformLocation(shaderProgram, 'u_Translation');
            if (!u_Translation) {
                console.log('Failed to get the storage location of u_Translation');
                return;
            }
            gl.uniform4f(u_Translation, Tx, Ty, Tz, 0.0);
    
        }
    
        function initBuffers(gl, shaderProgram) {
            var vertices = new Float32Array([
                0, 0.5,   -0.5, -0.5,   0.5, -0.5
            ]);
            var n = 3;//点的个数
            //创建缓冲区对象
            var vertexBuffer = gl.createBuffer();
            if (!vertexBuffer) {
                console.log("Failed to create the butter object");
                return -1;
            }
            //将缓冲区对象绑定到目标
            gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
            //向缓冲区写入数据
            gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
            //获取坐标点
            var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
            //将缓冲区对象分配给a_Position变量
            gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
            //连接a_Position变量与分配给它的缓冲区对象
            gl.enableVertexAttribArray(a_Position);
            return n;
    
        }
    
        main();
    </script>
    
    

    旋转

    1、关键点说明

    • 坐标P(x,y,z) , 绕Z轴旋转β角度变成 p1(x1, y1, z1)
      则根据数据三角函数公式可得:

    x1 = xcosβ - ysinβ

    y1 = xsinβ + ycosβ

    z1=z

    • 顶点着色器需要加上 uniform float u_CosB, u_SinB 存储旋转角度。

    • 顶点坐标位置 :

      • gl_Position.x = a_Position.x * u_CosB - a_Position.y * u_SinB
      • gl_Position.y = a_Position.x * u_SinB + a_Position.y * u_CosB
    • 旋转API :

      • gl.uniform1f(u_CosB, cosB)
      • gl.uniform1f(u_sinB, sinB);

    2、demo

    • JavaScript
    <script>
        function main() {
            //顶点着色器程序
            var VSHADER_SOURCE =
                'attribute vec4 a_Position;
    ' +
                'uniform float u_CosB, u_SinB;
    ' +
                'void main() {
    ' +
                '  gl_Position.x = a_Position.x * u_CosB - a_Position.y * u_SinB;
    ' +
                '  gl_Position.y = a_Position.x * u_SinB + a_Position.y * u_CosB;
    ' +
                '  gl_Position.z = a_Position.z;
    ' +
                '  gl_Position.w = 1.0;
    ' +
                '}
    ';
    
            //片元着色器程序
            var FSHADER_SOURCE =
                'void main() {
    ' +
                '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    ' +
                '}
    ';
    
            var Tx = 0.5, Ty = 0.5, Tz = 0.0;
    
            //获取canvas元素
            var canvas = document.getElementById('canvas');
            //获取绘制二维上下文
            var gl = canvas.getContext('webgl');
            if (!gl) {
                console.log("Failed");
                return;
            }
            //编译着色器
            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 shaderProgram = gl.createProgram();
            gl.attachShader(shaderProgram, vertShader);
            gl.attachShader(shaderProgram, fragShader);
            gl.linkProgram(shaderProgram);
            gl.useProgram(shaderProgram);
    
            //获取坐标点
            var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
    
            if (a_Position < 0) {
                console.log('Failed to get the storage location of a_Position');
                return;
            }
    
            var n = initBuffers(gl, shaderProgram);
    
            if (n < 0) {
                console.log('Failed to set the positions');
                return;
            }
    
            opt(gl, shaderProgram);
    
            // 清除指定<画布>的颜色
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
    
            // 清空 <canvas>
            gl.clear(gl.COLOR_BUFFER_BIT);
    
            gl.drawArrays(gl.TRIANGLES, 0, n);
        }
    
        function opt(gl, program) {
            // 旋转角度
            var ANGLE = 90.0;
    
            var radian = Math.PI * ANGLE / 180.0;
            var cosB = Math.cos(radian);
            var sinB = Math.sin(radian);
    
            var u_CosB = gl.getUniformLocation(program, 'u_CosB');
            var u_sinB = gl.getUniformLocation(program, 'u_SinB');
    
            gl.uniform1f(u_CosB, cosB);
            gl.uniform1f(u_sinB, sinB);
        }
    
        function initBuffers(gl, shaderProgram) {
            var vertices = new Float32Array([
                0, 0.5,   -0.5, -0.5,   0.5, -0.5
            ]);
            var n = 3;//点的个数
            //创建缓冲区对象
            var vertexBuffer = gl.createBuffer();
            if (!vertexBuffer) {
                console.log("Failed to create the butter object");
                return -1;
            }
            //将缓冲区对象绑定到目标
            gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
            //向缓冲区写入数据
            gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
            //获取坐标点
            var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
            //将缓冲区对象分配给a_Position变量
            gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
            //连接a_Position变量与分配给它的缓冲区对象
            gl.enableVertexAttribArray(a_Position);
            return n;
    
        }
    
        main();
    </script>
    

    缩放

    1、关键点说明

    • 顶点着色器需要加上 uniform mat4 u_xformMatrix, 存储缩放因子的坐标矢量。

    • 顶点坐标位置 : gl_Position = u_xformMatrix * a_Position

    • 缩放API : gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);

      • u_xformMatrix : 缩放因子
      • xformMatrix : 原始坐标

    2、demo

    • JavaScript
    <script>
        function main() {
            //顶点着色器程序
            var VSHADER_SOURCE =
                'attribute vec4 a_Position;
    ' +
                'uniform mat4 u_xformMatrix;
    ' +
                'void main() {
    ' +
                '  gl_Position = u_xformMatrix * a_Position;
    ' +
                '}
    ';
    
            //片元着色器程序
            var FSHADER_SOURCE =
                'void main() {
    ' +
                '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    ' +
                '}
    ';
    
            var Tx = 0.5, Ty = 0.5, Tz = 0.0;
    
            //获取canvas元素
            var canvas = document.getElementById('canvas');
            //获取绘制二维上下文
            var gl = canvas.getContext('webgl');
            if (!gl) {
                console.log("Failed");
                return;
            }
            //编译着色器
            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 shaderProgram = gl.createProgram();
            gl.attachShader(shaderProgram, vertShader);
            gl.attachShader(shaderProgram, fragShader);
            gl.linkProgram(shaderProgram);
            gl.useProgram(shaderProgram);
    
            //获取坐标点
            var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
    
            if (a_Position < 0) {
                console.log('Failed to get the storage location of a_Position');
                return;
            }
    
            var n = initBuffers(gl, shaderProgram);
    
            if (n < 0) {
                console.log('Failed to set the positions');
                return;
            }
    
            opt(gl, shaderProgram);
    
            // 清除指定<画布>的颜色
            gl.clearColor(0, 0, 0, 1);
    
            // 清空 <canvas>
            gl.clear(gl.COLOR_BUFFER_BIT);
    
            // Draw the rectangle
            gl.drawArrays(gl.TRIANGLES, 0, n);
        }
    
        // 缩放
        function opt(gl, program) {
            // 缩放因子
    
            var Sx = 1.0, Sy = 1.5, Sz = 1.0;
            var xformMatrix = new Float32Array([
                Sx,   0.0,  0.0,  0.0,
                0.0,  Sy,   0.0,  0.0,
                0.0,  0.0,  Sz,   0.0,
                0.0,  0.0,  0.0,  1.0
            ]);
    
            var u_xformMatrix = gl.getUniformLocation(program, 'u_xformMatrix');
    
            gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);
        }
    
        // 构建缓冲区
        function initBuffers(gl, shaderProgram) {
            var vertices = new Float32Array([
                0, 0.5,   -0.5, -0.5,   0.5, -0.5
            ]);
            var n = 3;//点的个数
            //创建缓冲区对象
            var vertexBuffer = gl.createBuffer();
            if (!vertexBuffer) {
                console.log("Failed to create the butter object");
                return -1;
            }
            //将缓冲区对象绑定到目标
            gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
            //向缓冲区写入数据
            gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
            //获取坐标点
            var a_Position = gl.getAttribLocation(shaderProgram, 'a_Position');
            //将缓冲区对象分配给a_Position变量
            gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
            //连接a_Position变量与分配给它的缓冲区对象
            gl.enableVertexAttribArray(a_Position);
            return n;
        }
    
        // 主方法调用
        main();
    </script>
    

    写在最后

      新博客

  • 相关阅读:
    malloc函数具体解释
    信息熵(Entropy)究竟是用来衡量什么的?
    机器学习笔记——皮尔逊相关系数
    GridView导出Excel的超好样例
    Microsoft Visual C++ Runtime Library Runtime Error的解决的方法
    编译过程
    java实现第三届蓝桥杯星期几
    java实现第三届蓝桥杯星期几
    java实现第三届蓝桥杯星期几
    java实现第三届蓝桥杯星期几
  • 原文地址:https://www.cnblogs.com/chenmo-xpw/p/7466587.html
Copyright © 2011-2022 走看看