webgl(3) -如何使用webgl的缓冲区,使其一次性的写入多条数据,渲染多条数据。

1. 如何使用webgl的缓冲区,使其一次性的写入多条数据,渲染多条数据。

这个的实现需要发这几步走。

1. 创建缓冲区
2. 将已经创建的缓冲区绑定到WebGL系统中已经存在的 “目标”
3. 向缓冲区传入(写入)数据
4. 将缓冲区的数据分配给webgl中的变量(attribute);
5. 开启attribute变量。

2.创建缓冲区

const vertexBuffer = gl.createBuffer()

此时的webgl系统中的变化为
在这里插入图片描述

3.将已经创建的缓冲区绑定到WebGL系统中已经存在的 “目标”

1.因为我们不能直接向缓冲区写入数据,而只能向"目标"写入数据

gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

此时的webgl系统中的变化为
在这里插入图片描述

4.向缓冲区中写入数据

1.我们不能直接向缓冲区中写入数据,只能向“目标”写入数据。
2.所以需要先将缓冲区和“目标”绑定到一起。

gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);

此时webgl中的变化
在这里插入图片描述

5. 将缓冲区的数据分配给webgl中的变量(attribute);

这一步是将缓冲区的数据,分配给webgl中的变量,所以、、

1.先要获取这个变量的存储地址
2.然后才能分配。

const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
a_Position 是 webgl中的变量,
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);

在这里插入图片描述

6.开启attribute变量。

gl.enableVertexAttribArray(a_Position);

在这里插入图片描述

6.案例代码(同时绘制三个点)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #canvas {
      
      
            height: 300px;
            width: 300px;
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script>
        // 获取webGL执行的执行上下文
        // const VSHADER_SOURCE = 
        // 'void main() { \n'+
        // '  gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n' +
        // '  gl_PointSize = 5.0;\n'+
        // '}\n';
        const VSHADER_SOURCE = 
        'attribute vec4 a_Position;\n'+
        'void main() { \n'+
        '   gl_Position = a_Position;\n'+
        '   gl_PointSize = 10.0;\n'+
        '}\n';
        // const FSHADER_SOURCE = 
        // 'void main() { \n'+
        // '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n'+
        // '};\n'
        const FSHADER_SOURCE = 
        'void main() { \n' +
        '   gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
        '}\n';
        const gl = canvas.getContext('webgl');
        function createshader(gl, type, source) {
      
      
            const shader = gl.createShader(type); // 创建type类型的着色器(顶点着色器,片源着色器);
            gl.shaderSource(shader, source); // 向shader设置GLSL代码,其实就是设置数据源。
            gl.compileShader(shader); // 开始编译shader(着色器);
            const compileStatus = gl.getShaderParameter(shader, gl.COMPILE_STATUS); status
            if (!compileStatus) {
      
      
                const err = gl.getShaderInfoLog(shader); // 获取编译 shader的信息。
                console.log(`着色器编译报错的信息为:${ 
        err}`);
                gl.deleteShader(shader); // 编译报错,就要删除对应的着色器(shader);
                return null
            }
            return shader;
        }
        function createProgram(gl, vshader, fshader) {
      
      
            const vertexShader = createshader(gl, gl.VERTEX_SHADER, vshader);
            // return;
            const fragmentShader = createshader(gl, gl.FRAGMENT_SHADER, fshader);
    
            if (!vertexShader || !fragmentShader) {
      
      
                console.log('着色器创建失败')
                return null;
            }
            const program = gl.createProgram(); // 创建一个webgl程序吧
            gl.attachShader(program, vertexShader); // 为 program绑定一个着色器
            gl.attachShader(program, fragmentShader); // 为 program绑定一个着色器
            gl.linkProgram(program);
            const linkState = gl.getProgramParameter(program, gl.LINK_STATUS); // 获取program与着色器链接的状态。
            if (!linkState) {
      
      
                const err = gl.getProgramInfoLog(program); // 获取program的链接信息
                console.log(err, 'sd')
                console.log(`链接报错的原因是${ 
        err}`)
                gl.deleteShader(vertexShader); // 删除顶点着色器
                gl.deleteShader(fragmentShader); // 删除片源着色器
                gl.deleteProgram(program); // 删除program;
                return null;
            }
            return program
        }
        function initShader() {
      
      
            const program = createProgram(gl, VSHADER_SOURCE, FSHADER_SOURCE);
            if (!program) {
      
      
                console.log('程序创建失败');
                return false;
            }
            gl.useProgram(program);
            gl.program = program;
        }
        initShader();
        function onTime(data) {
      
      
            // 1.创建一个缓冲区
            const vertexBuffer = gl.createBuffer(); 
            gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer); // 将已经创建的缓冲区,绑定到webgl系统中存在的目标。
            gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); // 将数据写入缓冲区,是在gl.ARRAY_BUFFER中的缓冲区
            // 获取a_Position这个变量的存储地址.
            const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
            // 为a_Position这个变量存储的地址,分配缓冲区数据
            gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(a_Position);
            gl.clearColor(0.0, 0.0, 1.0, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.drawArrays(gl.POINIS, 0, 3);
        }
        const data = new Float32Array([0.0,0.5,0.5,0,-0.5,0.0])
        onTime(data)
        // gl.clearColor(0.0, 0.0, 1.0, 1.0);
        // gl.clear(gl.COLOR_BUFFER_BIT);
        // gl.drawArrays(gl.POINIS, 0, 1);
    </script>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/webMinStudent/article/details/121586777