webGL-- 存储限定符和VBO小综合例子

224 阅读1分钟

本篇主要是对之前学习的一个总结,准备明天开始学习索引缓冲和变换矩阵。

学习目标:

  • 了解并使用存储限定符;

    • 存储限定符

      1. Attribute
      2. Uniform
      3. Varing

        - Attribute
         主要传递 不同顶点时,代表不同信息;
        - Uniform
        对于所有顶点,信息都相同,共享的特性,属于全局的;
        - Varying
        是顶点着色器和片段着色器之间的桥梁;
        
      
  • 绘制彩色三角形例子 (VBO和存储限定符)


function initShader(gl, vertexSource, fragementSource) {
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertexSource);
    gl.compileShader(vertexShader);



    if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
        var error = gl.getShaderInfoLog(vertexShader);
        gl.deleteShader(vertexShader);
        return false;

    }


    const fragementShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragementShader, fragementSource);
    gl.compileShader(fragementShader);


    if (!gl.getShaderParameter(fragementShader, gl.COMPILE_STATUS)) {//获取编译状态

        var error = gl.getShaderInfoLog(fragementShader);
        gl.deleteShader(fragementShader);
        return false;
    }

    const program = gl.createProgram();

    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragementShader);

    gl.linkProgram(program);

    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {//获取链接状态
        var error = gl.getProgramInfoLog(program);
        gl.deleteProgram(program);
        return false;
    }

    //在把着色器对象链接到程序对象以后,记得删除着色器对象
    gl.deleteShader(vertexShader);
    gl.deleteShader(fragementShader);

    gl.useProgram(program);
    return program;
}


function createVBO(gl, data) {
    const vbo = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
    gl.bindBuffer(gl.ARRAY_BUFFER, null);
    return vbo;
}

 window.onload = function () {
            const canvas = document.getElementById('canvas');

            canvas.width = 300;
            canvas.height = 300;

            const gl = canvas.getContext("webgl");

            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            gl.clearDepth(1.0);
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

            const vertexSource = `
            attribute vec3 position;
			attribute vec4 color;
			varying   vec4 vColor;
			 
			void main(){
				vColor = color;
				gl_Position = vec4(position, 1.0);
			}
            `;


            const fragSource = ` 
            precision mediump float;
			varying vec4 vColor;

            void main(){
               gl_FragColor = vColor;
            }`;



            const shaderProgram = initShader(gl, vertexSource, fragSource);
            console.log(shaderProgram);

            // attributeLocation的获取
            var attLocation = new Array(2);
            attLocation[0] = gl.getAttribLocation(shaderProgram, "position");
            attLocation[1] = gl.getAttribLocation(shaderProgram, "color");

            // 将元素数attribute保存到数组中
            var attStride = new Array(2);
            attStride[0] = 3;
            attStride[1] = 4;


            // 保存顶点的位置信息的数组
            var vertex_position = [
                0.0, 1.0, 0.0,
                1.0, 0.0, 0.0,
                -1.0, 0.0, 0.0
            ];

            // 保存顶点的颜色信息的数组
            var vertex_color = [
                1.0, 0.0, 0.0, 1.0,
                0.0, 1.0, 0.0, 1.0,
                0.0, 0.0, 1.0, 1.0
            ];

            const colorVBO = createVBO(gl, vertex_color);
            const vertexVBO = createVBO(gl, vertex_position);

            // VBO绑定(位置信息)
            gl.bindBuffer(gl.ARRAY_BUFFER, vertexVBO);
            gl.vertexAttribPointer(attLocation[0], attStride[0], gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(attLocation[0]);


            // VBO绑定(颜色信息)
            gl.bindBuffer(gl.ARRAY_BUFFER, colorVBO);
            gl.vertexAttribPointer(attLocation[1], attStride[1], gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(attLocation[1]);

            // 绘制模型
            gl.drawArrays(gl.TRIANGLES, 0, 3);

            // context的刷新
            gl.flush();

        }