记录下吧,这两种方法都可

93 阅读2分钟
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebGL2 Draw Triangle</title>
    <style>
        canvas {
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script>
        // 获取 Canvas 及 WebGL2 上下文
        const canvas = document.getElementById('canvas');
        const gl = canvas.getContext('webgl2');

        if (!gl) {
            console.error('WebGL 2 不可用');
        }

        // 设置画布的大小
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        // 清除颜色
        gl.clearColor(0.0, 0.0, 0.0, 1.0); // 黑色背景
        gl.clear(gl.COLOR_BUFFER_BIT);

        const vertexShaderSource = `
            attribute vec3 aPos;
            attribute vec3 aColor;
            varying vec3 v_color;

            void main() {
                v_color = aColor;
                gl_Position = vec4(aPos, 1.0);
            }
        `

        // fragment shader
        const fragmentShaderSource = `
            precision mediump float;
            varying vec3 v_color;
            void main() {
                gl_FragColor = vec4(v_color, 1.0);
            }
        `

        // 创建并编译着色器
        function createShader(gl, type, source) {
            const shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                return shader;
            }
            console.error(`编译着色器错误: ${gl.getShaderInfoLog(shader)}`);
            gl.deleteShader(shader);
        }

        // 创建程序并链接着色器
        function createProgram(gl, vertexShader, fragmentShader) {
            const program = gl.createProgram();
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragmentShader);
            gl.linkProgram(program);
            if (gl.getProgramParameter(program, gl.LINK_STATUS)) {
                return program;
            }
            console.error(`链接程序错误: ${gl.getProgramInfoLog(program)}`);
            gl.deleteProgram(program);
        }

        // 创建着色器程序
        const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
        const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
        const program = createProgram(gl, vertexShader, fragmentShader);

        // 定义三角形的顶点
        const positions = new Float32Array([
            0,  0.5, 0.0, // 顶点1
            -0.5, -0.5, 0.0,// 顶点2
            0.5, -0.5, 0.0, // 顶点3
        ]);
        const colors = new Float32Array([
            1.0, 0.0,0.0,
            0.0, 1.0,0.0,
            0.0, 0.0,1.0,
        ]);
        let FSIZE = positions.BYTES_PER_ELEMENT
        console.log('fsize===',FSIZE)
        //let posVbo;
        //let colorVbo;
        // 创建并绑定位置缓冲区
        const posVbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, posVbo);
        gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);

        const colorVbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorVbo);
        gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); 
        // 创建vao
        const vao = gl.createVertexArray();
        gl.bindVertexArray(vao)
        // 告诉 WebGL 如何从位置缓冲区读取数据
        //第二种写法
        const positionAttributeLocation = gl.getAttribLocation(program, 'aPos');
        gl.bindBuffer(gl.ARRAY_BUFFER, posVbo);
        gl.enableVertexAttribArray(positionAttributeLocation);
        gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);

        const colorAttributeLocation = gl.getAttribLocation(program, 'aColor');
        gl.bindBuffer(gl.ARRAY_BUFFER, colorVbo);
        gl.enableVertexAttribArray(colorAttributeLocation);
        gl.vertexAttribPointer(colorAttributeLocation, 3, gl.FLOAT, false, 0, 0);

        // 使用着色器程序
        gl.useProgram(program);
        
        // 绘制三角形
        gl.drawArrays(gl.TRIANGLES, 0, 3);
        gl.bindVertexArray(null)
        
       
    </script>
</body>
</html>

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebGL2 Draw Triangle</title>
    <style>
        canvas {
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script>
        // 获取 Canvas 及 WebGL2 上下文
        const canvas = document.getElementById('canvas');
        const gl = canvas.getContext('webgl2');

        if (!gl) {
            console.error('WebGL 2 不可用');
        }

        // 设置画布的大小
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;

        // 清除颜色
        gl.clearColor(0.0, 0.0, 0.0, 1.0); // 黑色背景
        gl.clear(gl.COLOR_BUFFER_BIT);

        // 定义顶点着色器源码
        const vertexShaderSource = `#version 300 es
            layout (location = 0) in vec3 aPos;
            layout (location = 1) in vec3 aColor;
            out vec3 color;
            void main() {
                gl_Position = vec4(aPos,1.0);
                color = aColor;
            }
        `;

        // 定义片段着色器源码
        const fragmentShaderSource = `#version 300 es
            precision mediump float;
            in vec3 color;
            out vec4 fragColor;
            void main() {
                fragColor = vec4(color, 1.0); 
            }
        `;


        // 创建并编译着色器
        function createShader(gl, type, source) {
            const shader = gl.createShader(type);
            gl.shaderSource(shader, source);
            gl.compileShader(shader);
            if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                return shader;
            }
            console.error(`编译着色器错误: ${gl.getShaderInfoLog(shader)}`);
            gl.deleteShader(shader);
        }

        // 创建程序并链接着色器
        function createProgram(gl, vertexShader, fragmentShader) {
            const program = gl.createProgram();
            gl.attachShader(program, vertexShader);
            gl.attachShader(program, fragmentShader);
            gl.linkProgram(program);
            if (gl.getProgramParameter(program, gl.LINK_STATUS)) {
                return program;
            }
            console.error(`链接程序错误: ${gl.getProgramInfoLog(program)}`);
            gl.deleteProgram(program);
        }

        // 创建着色器程序
        const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
        const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
        const program = createProgram(gl, vertexShader, fragmentShader);

        // 定义三角形的顶点
        const positions = new Float32Array([
            0,  0.5, 0.0, // 顶点1
            -0.5, -0.5, 0.0,// 顶点2
            0.5, -0.5, 0.0, // 顶点3
        ]);
        const colors = new Float32Array([
            1.0, 0.0,0.0,
            0.0, 1.0,0.0,
            0.0, 0.0,1.0,
        ]);
        let FSIZE = positions.BYTES_PER_ELEMENT
        console.log('fsize===',FSIZE)
        //let posVbo;
        //let colorVbo;
        // 创建并绑定位置缓冲区
        const posVbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, posVbo);
        gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);

        const colorVbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorVbo);
        gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW); 
        // 创建vao
        const vao = gl.createVertexArray();
        gl.bindVertexArray(vao)
        // 告诉 WebGL 如何从位置缓冲区读取数据
        //第一种写法
        gl.bindBuffer(gl.ARRAY_BUFFER, posVbo);//只有绑定了posVbo,下面的属性描述才会与此vbo相关
        gl.enableVertexAttribArray(0);
        gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0)

        gl.bindBuffer(gl.ARRAY_BUFFER, colorVbo);
        gl.enableVertexAttribArray(1);
        gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
      
        // 使用着色器程序
        gl.useProgram(program);
        
        // 绘制三角形
        gl.drawArrays(gl.TRIANGLES, 0, 3);
        gl.bindVertexArray(null)
        
       
    </script>
</body>
</html>