WebGl基础图形之点的绘制

63 阅读1分钟

初探webgl——点的绘制

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <met httpsa name="viewport" content="width=device-width, initial-scale=1.0">
        <title>点</title>
</head>
<body>
    <canvas width="500" height="500" id='canvas'></canvas>
    <script type="GLSL" id="vertex">
        attribute vec2 a_position;
        uniform vec2 screenSize;
        attribute vec4 a_color;
        varying  vec4 v_color;
        void main() {
            v_color = a_color;
            float x = a_position.x*2.0/screenSize.x -1.0;
            float y = 1.0 - a_position.y*2.0/screenSize.y;
            gl_Position = vec4(x,y,0,1);
            gl_PointSize = 10.0;
        }
    </script>
    <script type="GLSL" id="fragment">
        precision mediump float;
        varying vec4 v_color;
        void main() {
            gl_FragColor = v_color;
        }
    </script>
    <script>
        let oCanvas = document.getElementById('canvas')
        let gl = oCanvas.getContext('webgl')
        let points = []
        if (!gl) {
            alert('浏览器版本不支持!请升级版本过着使用谷歌浏览器')
        }
        let vertexStr = document.getElementById('vertex').innerText
        let fragmentStr = document.getElementById('fragment').innerText
        let vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexStr)
        let fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentStr)
        let program = createProgam(gl, vertexShader, fragmentShader)
        gl.useProgram(program)
        let a_position = gl.getAttribLocation(program, 'a_position')
        let screenSize = gl.getUniformLocation(program, 'screenSize')
        let a_color = gl.getAttribLocation(program, 'a_color')
        gl.uniform2f(screenSize, oCanvas.clientWidth, oCanvas.clientHeight)
        gl.clearColor(0, 0, 1, 1)
        gl.clear(gl.COLOR_BUFFER_BIT)
        function bindEvent() {
            oCanvas.onmousedown = function (e) {
                let x = e.offsetX;
                let y = e.offsetY;
                points.push({
                    x,
                    y,
                    color: [Math.random(), Math.random(), Math.random(), 0.5 + Math.random() * 0.4]
                })
                gl.clearColor(0, 0, 1, 1)
                gl.clear(gl.COLOR_BUFFER_BIT)
                points.map((i) => {
                    //向attribute变量赋值
                    gl.vertexAttrib2f(a_position, i.x, i.y)
                    gl.vertexAttrib4f(a_color, ...i.color)
                    gl.drawArrays(gl.POINTS, 0, 1)
                })
                // gl.vertexAttrib2f(a_position, x, y)
                // gl.vertexAttrib4f(a_color, Math.random(), Math.random(), Math.random(), 0.5 + Math.random() * 0.4)
                // gl.drawArrays(gl.POINTS, 0, 1) 这是一个异步操作  类似于vue试图更新  当发生多点绘制时 他会等待数据  一起执行绘制
                //缓存区 多点绘制
                // let f32Arr =[]
                // points.map((i)=>{
                //     f32Arr.push(i.x,i.y,...i.color)  
                // })
                // let pointBuffer = gl.createBuffer()
                // gl.bindBuffer(gl.ARRAY_BUFFER, pointBuffer)
                // gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(f32Arr), gl.STATIC_DRAW)
                // gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false,4*6, 0)
                // gl.vertexAttribPointer(a_color,4, gl.FLOAT, false, 4 * 6, 4*2)
                // //启动
                // gl.enableVertexAttribArray(a_position)
                // gl.enableVertexAttribArray(a_color)
                // //参数 绘制类型   起始位置   顶点个数
                // gl.drawArrays(gl.POINTS, 0, points.length)
            }
        }
        bindEvent()
        function createProgam(gl, vertexShader, fragmentShader) {
            let program = gl.createProgram()
            console.log(vertexShader, fragmentShader, 'sss');
            gl.attachShader(program, vertexShader)
            gl.attachShader(program, fragmentShader)
            gl.linkProgram(program)
            let success = gl.getProgramParameter(program, gl.LINK_STATUS)
            if (success) {
                return program
            } else {
                console.log(gl.getProgramInfo(program), '着色器链接失败');
            }
        }

        function createShader(gl, type, source) {
            let shader = gl.createShader(type)
            gl.shaderSource(shader, source)
            gl.compileShader(shader)
            let success = gl.getShaderParameter(shader, gl.COMPILE_STATUS)
            if (success) {
                return shader
            } else {
                console.log(gl.getShaderInfoLog(shader), '着色器执行报错');
            }
        }
    </script>
</body>
</html>