webgl与glsl着色器绘制三角形

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        html,
        body {
            width: 100%;
            height: 100%;
            overflow: hidden;
        }

        #glcanvas {
            width: 100%;
            height: 100%;
        }
    </style>
    <!-- //attribute变量只能在顶点着色器里使用,表示:顶点、材质、光照 
            uniform 定义变量,是通过程序传进来的
            -->
    <script id="vertex-shader" type="nojs">
            attribute vec4 a_position;
                    uniform mat4 u_Mat;
                    void main(){
                        gl_Position=u_Mat*a_position;
                    }
        </script>
    <!-- 
                precision highp float;高精度
                precision mediump float;中精度
                precision lowp float;低精度
             -->
    <script id="fragment-shader" type="nojs">
            precision mediump float;
                    void main(){
                        gl_FragColor=vec4(1,0,0,1);
                    }
        </script>
</head>

<body onload="main()">
    <canvas id="glcanvas">
        你的浏览器似乎不支持或者禁用了 HTML5
        <code>&lt;canvas&gt;</code>
        元素。
    </canvas>
    <script>
        // 从这里开始
        function main() {
            const canvas = document.querySelector("#glcanvas");
            // 初始化 WebGL 上下文
            const gl = canvas.getContext("webgl");
            console.log(`gl`, gl);
            // 确认 WebGL 支持性
            if (!gl) {
                alert("无法初始化 WebGL,你的浏览器、操作系统或硬件等可能不支持 WebGL。");
                return;
            }

            // 使用完全不透明的黑色清除所有图像
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            // 用上面指定的颜色清除缓冲区
            gl.clear(gl.COLOR_BUFFER_BIT);
            // 获取顶点着色器文本
            let vertexShaderSource = document.getElementById("vertex-shader").textContent
            // 获取片元着色器文本
            let fragmentShaderSource = document.getElementById("fragment-shader").textContent
            console.log(`vertexShaderSource`, vertexShaderSource);
            console.log(`fragmentShaderSource`, fragmentShaderSource);
            // 创建顶点着色器
            let vertexShader = gl.createShader(gl.VERTEX_SHADER)
            // 创建片元着色器
            let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER)
            console.log(`vertexShader`, vertexShader);
            console.log(`fragmentShader`, fragmentShader);
            // 向着色器指定glsl源代码
            gl.shaderSource(vertexShader, vertexShaderSource)
            gl.shaderSource(fragmentShader, fragmentShaderSource)
            // 编译顶点着色器
            gl.compileShader(vertexShader)
            // 编译片元着色器
            gl.compileShader(fragmentShader)

            // 检查顶点着色器
            let vertexSuccess = gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)
            console.log(`vertexSuccess`, vertexSuccess);
            // 获取顶点着色器的信息日志,查看具体的错误位置以及错误类型
            let vertexLog = gl.getShaderInfoLog(vertexShader)
            console.log(`vertexLog`, vertexLog);
            // 检查片元着色器
            let fragmentSuccess = gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)
            console.log(`fragmentSuccess`, fragmentSuccess);
            // 获取片元着色器的信息日志,查看具体的错误位置以及错误类型
            let fragmentLog = gl.getShaderInfoLog(fragmentShader)
            console.log(`fragmentLog`, fragmentLog);

            // 创建一个程序
            let program = gl.createProgram()
            // 为程序对象分配着色器
            gl.attachShader(program, vertexShader)
            gl.attachShader(program, fragmentShader)
            // 连接程序对象
            gl.linkProgram(program)
            // 检查着色器对象是否连接成功
            let programSccess = gl.getProgramParameter(program, gl.LINK_STATUS)
            console.log(`programSccess`, programSccess);
            // 获取连接程序对象的信息日志,查看具体的错误位置以及错误类型
            let programLog = gl.getProgramInfoLog(program)
            console.log(`programLog`, programLog);
            // 获取着色器 中生命的变量
            let positionAttributeLocation = gl.getAttribLocation(program, "a_position")
            // 创建缓存区
            let positionBuffer = gl.createBuffer()
            // 将缓存区的对象绑定到webgl
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
            // 创建顶点
            let positions = [
                0.0,
                0.5,
                -0.5,
                -0.5,
                0.5,
                -0.5
            ]
            // STATIC_DRAW静态绘制
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW)
            // 定义视图大小 x y w h
            gl.viewport(0, 0, gl.canvas.width, gl.canvas.height)

            // 使用程序
            gl.useProgram(program)
            // 激活对应属性,只有激活才能使用
            gl.enableVertexAttribArray(positionAttributeLocation)
            //
            gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0)
            let u_Mat
            let scale = {
                x: 0.3,
                y: 0.3,
                z: 0.3
            }
            let animate = () => { // 定义一个缩放的矩阵
                //     scale.x-=0.1
                //    if(scale.x==0.8){
                //     scale.x=0.1
                //    }

                let mat = new Float32Array([
                    scale.x,
                    0.0,
                    0.0,
                    0.0,
                    0.0,
                    scale.x,
                    0.0,
                    0.0,
                    0.0,
                    0.0,
                    scale.x,
                    0.0,
                    0.0,
                    0.0,
                    0.0,
                    1.0,
                ])
                // 缩放变量
                u_Mat = gl.getUniformLocation(program, 'u_Mat')
                gl.uniformMatrix4fv(u_Mat, false, mat)
                // 绘制图形
                gl.drawArrays(gl.TRIANGLES, 0, 3)
                requestAnimationFrame(animate)
            }
            animate()
            // 清空颜色
            gl.clearColor(0, 0, 0, 1)
            // 清空绘制区域
            gl.clear(gl.COLOR_BUFFER_BIT)

        }
    </script>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/qq_37312180/article/details/132542395