WebGl基础图形之三角的绘制

95 阅读2分钟
<!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">
        /*
          a_position :顶点坐标
          a_TexCoord: 纹理坐标
          screenSize: canvas 画布大小
          v_TexCoord: 传递给片元着色器的纹理坐标
        */
        attribute vec2 a_position;
        uniform vec2 screenSize;
        uniform vec2 screenSize;
        attribute vec2 a_TexCoord;
        varying  vec2 v_TextCoord;
        void main() {
            /*
               将纹理坐标传给片元着色器
            */
            v_TexCoord = a_TexCoord;
            /*
               坐标转换  将canvas 坐标转化为webgl坐标
            */
            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 vec2 v_TextCoord;
        /*
          纹理图像 源数据
        */
        uniform  sampler2D u_Sampler;
        void main() {
            /*
              texture2D 将纹理图像上指定的位置(纹理坐标)纹素颜色信息取出
            */
            gl_FragColor = texture2D(u_Sampler,v_TextCoord);
        }
    </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 screenSize = gl.getUniformLocation(program, 'screenSize')
        let u_Sampler = gl.getUniformLocation(program, 'u_Sampler')
        let a_TexCoord = gl.getAttribLocation(program, 'a_TexCoord')
        let img = new Image()
        img.src = "1.png"
        //创建纹理单元
        let texture = gl.createTexture()
        img.onload = function () {
              //激活纹理单元
            gl.activeTexture(gl.TEXTURE0)
            //绑定纹理对象(webgl中的纹理对象,要绑定的纹理单元)
            gl.bindTexture(gl.TXTURE_2D,texture)
            //配置纹理信息 textParameteri(gl.TXTURE_2D,key,value) key:gl.TEXTURE_
            gl.textParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR)  //纹理放大
            gl.textParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR)   //纹理缩小
            gl.textParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE)  //纹理水平填充
            gl.textParameteri(gl.TEXTURE_2D,gl.TEXTURE__WRAP_T,gl.CLAMP_TO_EDGE)  //纹理垂直填充
            gl.texImage2D(gl.TEXTURE_2D,0,gl.R)
        }
        // let a_TexCoord = gl.getAttribLocation(program, 'a_TexCoord')
        gl.uniform2f(screenSize, oCanvas.clientWidth, oCanvas.clientHeight)
        r(gl.COLOR_BUFFER_BIT)
        drow()
        function drow() {
            gl.vertexAttrib4f(a_color, 0.2, 0.3, 0.4, 0.7)
            //创建缓冲区对象
            let positionBuffer = gl.createBuffer()
            //将其绑定到target(顶点的数据、顶点的索引值)表示的目标上
            gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
            // let indexBuffer = gl.createBuffer()
            //将其绑定到target(顶点的数据、顶点的索引值)表示的目标上
            // gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer)
            //缓存区写入数据
            let f32Arr =
                [
                    100, 75, 0.5, 0.5,
                    50, 50, 0, 1,
                    50, 100, 0, 0,
                    150, 100, 1, 0,
                    150, 50, 1, 1,
                    50, 50, 0, 1
                ]
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(f32Arr), gl.STATIC_DRAW)
            // gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([0,1,2,3]), gl.STATIC_DRAW)
            //向缓冲区对象传送数据  第四个参数针对非浮点类型
            //相邻两个顶点之间的字节数
            gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 4 * 4, 0)
            gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, 4 * 4, 4 * 2)
            //启动
            gl.enableVertexAttribArray(a_position)
            gl.clearColor(0, 0, 1, 1)
            gl.clear(gl.COLOR_BUFFER_BIT)
            //TRIANGLES 三角形   TRIANGLE_STRIP 三角带  三角扇 TRIANGLE_FAN
            gl.drawArrays(gl.TRIANGLE_FAN, 0, 6)
        }
        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>