WebGl基础图形之线的绘制

62 阅读1分钟
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <met httpsa name="viewport" content="width=device-width, initial-scale=1.0">
        <title>webgl线</title>
</head>
<body>
    <canvas width="500" height="500" id='canvas'></canvas>
    <script type="GLSL" id="vertex">
        attribute vec2 a_position;
        uniform vec2 screenSize;
        attribute float pointsize;
        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 = pointsize;
        }
    </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)
        gl.clearColor(0, 0, 1, 1)
        gl.clear(gl.COLOR_BUFFER_BIT)
        let a_position = gl.getAttribLocation(program, 'a_position')
        let pointsize = gl.getAttribLocation(program, 'pointsize')
        let screenSize = gl.getUniformLocation(program, 'screenSize')
        let a_color = gl.getAttribLocation(program, 'a_color')
        gl.uniform2f(screenSize, oCanvas.clientWidth, oCanvas.clientHeight)
        function bindEvent() {
            oCanvas.onmousedown = function (e) {
                let x = e.offsetX;
                let y = e.offsetY;
                points.push({
                    x,
                    y,
                    size: 10.0
                })
                if (points.length ) {
                    gl.vertexAttrib4f(a_color, 0.2, 0.3, 0.4, 0.7)
                    //创建缓冲区对象
                    let positionBuffer = gl.createBuffer()
                    //将其绑定到target(顶点的数据、顶点的索引值)表示的目标上
                    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
                    //缓存区写入数据
                    let f32Arr =[]
                    for (let index = 0; index < points.length; index++) {
                        f32Arr.push(...[points[index].x,points[index].y,points[index].size])
                    }
                    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(f32Arr), gl.STATIC_DRAW)
                    //向缓冲区对象传送数据  第四个参数针对非浮点类型
                    //相邻两个顶点之间的字节数
                    gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 4 * 3, 0)
                    gl.vertexAttribPointer(pointsize, 1, gl.FLOAT, false, 4 * 3, 4 * 2)
                    //启动
                    gl.enableVertexAttribArray(a_position)
                    gl.enableVertexAttribArray(pointsize)
                    gl.clearColor(0, 0, 1, 1)
                    gl.clear(gl.COLOR_BUFFER_BIT)
                    //参数 绘制类型   起始位置   顶点个数
                    //LINE_STRIP  连线  LINES 线段   LINE_LOOP  回路
                    gl.drawArrays(gl.LINE_STRIP, 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>