> 文章列表 > webgl-矩阵、旋转、平移、缩放

webgl-矩阵、旋转、平移、缩放

webgl-矩阵、旋转、平移、缩放

关键代码

旋转

        /*

         * [

         *     cosB, -sinB, 0, 0,

         *     sinB, cosB,  0, 0,

         *     0,     0,    1, 0,

         *     0,     0,    0, 1

         *  ]

         *

         *  矩阵本该是这个但是由于webgl的矩阵行和列是颠倒的所以我们传入的矩阵也需要倒置

         */

        rotationMatrix = [

            cosB, sinB, 0, 0,

            -sinB, cosB, 0, 0,

            0, 0, 1, 0,

            0, 0, 0, 1

        ]

平移矩阵

 

        //向x轴正方向平移0.2

        translateMatrix = [

            1, 0, 0, 0.2,

            0, 1, 0, 0,

            0, 0, 1, 0,

            0, 0, 0, 1

        ]

缩放矩阵

 

        //沿着x,y轴放大2倍

        scaleMatrix =[

            2, 0, 0, 0,

            0, 2, 0, 0,

            0, 0, 1, 0,

            0, 0, 0, 1

        ]

html

<!DOCTYPE html>

<head>

    <style>

        *{

            margin: 0px;

            padding: 0px;

        }

    </style>

</head>

<body>

    <canvas id = 'webgl'>

        您的浏览器不支持HTML5,请更换浏览器

    </canvas>

    <script src="./main.js"></script>

</body>

main.js

let canvas = document.getElementById('webgl')

canvas.width = window.innerWidth

canvas.height = window.innerHeight

let radio = window.innerWidth / window.innerHeight;

let ctx = canvas.getContext('webgl')

//创建顶点资源和像素资源(颜色)

let vertexSource = `

attribute vec2 a_position;

uniform mat4 matrix;

void main() {

  gl_Position = matrix * vec4(a_position, 0.0, 1.0);

  gl_PointSize = 10.0;

}

`

let fragmentSource = `

precision mediump float;

void main (){

  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);

}

`

if (initShader(ctx, vertexSource, fragmentSource)) {

    //画三角形

    let vertexs = [

        //   x     y    R    G    B

        -0.5, 0.0, 1.0, 0.0, 0.0, //第一个点的信息

        0.5, 0.0, 0.0, 1.0, 0.0, //第二个点的信息

        0.0, 0.5, 0.0, 0.0, 1.0,//第三个点的信息

    ]

    let float32Array = new Float32Array(vertexs)

    //创建buffer

    let buffer = ctx.createBuffer()

    //绑定buffer

    ctx.bindBuffer(ctx.ARRAY_BUFFER, buffer)

    //往buffer中填充值,并指定数据用途

    ctx.bufferData(ctx.ARRAY_BUFFER, float32Array, ctx.STATIC_DRAW)

    //获取vertexShader指定变量内存

    let a_Position = ctx.getAttribLocation(ctx.program, "a_position")

    //指定每两个数组元素为一个点

    /*

     * 当数组元素不需进行分割拆分的时候最后两位可以指定为0,0

     *

     *

     */

    ctx.vertexAttribPointer(

        a_Position, //location: vertex Shader里面的attributes变量的location

        2, ctx.FLOAT, //size: attribute变量的长度 vec2长度2 vec3长度3

        false, //normalized: 正交化 true或false  , [1, 2] => [1/根号5, 2/根号5]

        5 * float32Array.BYTES_PER_ELEMENT, //stride: 每个点的信息所占的BYTES

        0 //offset: 每个点的信息,从第几个BYTES开始数

    )

    ctx.enableVertexAttribArray(a_Position);

    // ctx.drawArrays(ctx.TRIANGLE_FAN, 0, 3)

 

    //旋转矩阵

    let angle = 0

    let rotationMatrix

    let translateMatrix

    function render() {

        angle++

        let cosB = Math.cos(angle / 180 * Math.PI)

        let sinB = Math.sin(angle / 180 * Math.PI)

        /*

         * [

         *     cosB, -sinB, 0, 0,

         *     sinB, cosB,  0, 0,

         *     0,     0,    1, 0,

         *     0,     0,    0, 1

         *  ]

         *

         *  矩阵本该是这个但是由于webgl的矩阵行和列是颠倒的所以我们传入的矩阵也需要倒置

         */

        rotationMatrix = [

            cosB, sinB, 0, 0,

            -sinB, cosB, 0, 0,

            0, 0, 1, 0,

            0, 0, 0, 1

        ]

        //向x轴正方向平移0.2

        translateMatrix = [

            1, 0, 0, 0.2,

            0, 1, 0, 0,

            0, 0, 1, 0,

            0, 0, 0, 1

        ]

        //沿着x,y轴放大2倍

        scaleMatrix =[

            2, 0, 0, 0,

            0, 2, 0, 0,

            0, 0, 1, 0,

            0, 0, 0, 1

        ]

        let matrix = ctx.getUniformLocation(ctx.program, "matrix")

        ctx.uniformMatrix4fv(

            matrix, //localtion:vertex Shader里面的attributes变量的location

            false, //是否转置 一定设置为false

            new Float32Array(rotationMatrix)

        )

        ctx.drawArrays(ctx.TRIANGLE_FAN, 0, 3)

        window.requestAnimationFrame(render)

    }

    render()

}

 

//创建顶点阴影和像素阴影

function createShader(ctx, type, source) {

    //创建shader

    let shader = ctx.createShader(type)

    //绑定

    ctx.shaderSource(shader, source)

    //编译shader

    ctx.compileShader(shader)

    //获取编译结果

    let compiler = ctx.getShaderParameter(shader, ctx.COMPILE_STATUS)

    if (compiler) {

        return shader

    } else {

        let log = ctx.getShaderInfoLog(shader)

        console.log("compile shaders error", log)

        //删除异常的shader,防止内存泄露

        ctx.deleteShader(shader)

        return null

    }

}

function createProgram(ctx, vertexShader, fragmentShader) {

    //创建program

    let program = ctx.createProgram()

    if (!program) {

        return null

    }

    //点资源和像素资源合并

    ctx.attachShader(program, vertexShader)

    ctx.attachShader(program, fragmentShader)

    ctx.linkProgram(program)

    //获取linked的结果

    let linked = ctx.getProgramParameter(program, ctx.LINK_STATUS)

    if (linked) {

        return program

    } else {

        //获取link错误信息

        let log = ctx.getProgramInfoLog(program)

        console.log("link program error", log)

        //删除防止内存泄漏

        ctx.delete(program)

        ctx.deleteShader(vertexShader)

        ctx.deleteShader(fragmentShader)

        return null

    }

}

function initShader(ctx, vertexSource, fragmentSource) {

    let vertexShader = createShader(ctx, ctx.VERTEX_SHADER, vertexSource)

    let fragmentShader = createShader(ctx, ctx.FRAGMENT_SHADER, fragmentSource)

    let program = createProgram(ctx, vertexShader, fragmentShader)

    if (program) {

        ctx.useProgram(program)

        //挂载到ctx

        ctx.program = program

        return true

    } else {

        return false

    }

}

效果图