WebGL--入门程序

295 阅读2分钟

基本知识:

OpenGL核心是一个c库,不支持类型重载,在函数参数不同的时候要重新定义新的函数;

  • 预定义精度
    • 顶点着色器中的预定义精度:

      • precision highp float;
      • precision highp int;
      • precision lowp sampler2D;
      • precision lowp samplerCube;
    • 片段着色器中的预定义精度

      • precision mediump int;
      • precision lowp sampler2D;
      • precision lowp samplerCube;
    • 存储限定符

      • uniform:是一种 从cpu中的应用向GPU中的着色器发送数据的方式,uniform是全局的。

        • 获取uniform的位置(glGetUniformLocation(shaderProgram,"outColor")); 返回-1就代表没有找到位置。
        • glUniform4f设置uniform值;
        • glUniform()函数有一个特定的后缀,标识 设定unifrom类型。
          • f: 函数需要一个float作为它的值;

          • i:函数需要一个int作为它的值;

          • ui:函数需要一个unsigned int作为它的值;

          • 3f: 函数需要3个float作为它的值;

          • fv:函数需要一个float向量和数组 作为它的值;

  • 学习目的:

    • 使用存储限定符修改之前在canvas画一个点的程序;

    /**
     * 
     * 初始化着色器
     * 
     * 
     * openGL 学习资料 https://learnopengl-cn.readthedocs.io/zh/latest/01%20Getting%20started/05%20Shaders/
     * 
     */
    function initShaders(gl, VertexSource, FragmentSource) {
        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;
        }
    
    
        //创建片段着色器 -并 编译
        const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fragmentShader, FragmentSource);
        gl.compileShader(fragmentShader);
    
    
        if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {//获取编译状态
            var error = gl.getShaderInfoLog(fragmentShader);
            console.log("error", error);
            gl.deleteShader(fragmentShader);
            return;
        }
    
        //着色器程-序对象
        const shaderProgram = gl.createProgram();
        gl.attachShader(shaderProgram, vertexShader);//把着色器 附加到程序对象上
        gl.attachShader(shaderProgram, fragmentShader);
    
        //着色器对象链接到程序对象
        gl.linkProgram(shaderProgram);
    
        //在把着色器对象链接到程序对象以后,记得删除着色器对象
        gl.deleteShader(vertexShader);
        gl.deleteShader(fragmentShader);
    
    
        if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {//获取链接状态
            var error = gl.getProgramInfoLog(shaderProgram);
            gl.deleteProgram(shaderProgram);
            return;
        }
    
        return shaderProgram;
    }
    
    function webgl() {
           const canvas = document.getElementById('canvas');
           const gl = canvas.getContext('webgl');
           if (!gl) {
               return;
           }
    
           //attribute uniform
           //getAttribuLocation(program,"a_pos");//获取顶点属性变量的位置
           //vertexAttribut4f(location,v1,v2,v3,v4)//赋值 为顶点属性赋值
    
           // vec4 向量浮点数
           const VertexSource = `
               attribute vec4 a_pos;
               void main(){
                   gl_Position=a_pos;
                   gl_PointSize=10.0;
               }
           `;
    
           const FragmentSource = `
               precision lowp float;
               uniform vec3 u_color;
               void main(){
                   gl_FragColor=vec4(u_color,1.0);
               }
           `;
         
    
           const shaderProgram = initShaders(gl, VertexSource, FragmentSource);
           
             
           //--激活着色器程序(使用着色器程序 )
           gl.useProgram(shaderProgram);
    
           const a_pos = gl.getAttribLocation(shaderProgram, "a_pos");
           gl.vertexAttrib4f(a_pos, 0.0, -1.0, 0.0, 1.0);
    
    
           const u_color = gl.getUniformLocation(shaderProgram, "u_color");
           gl.uniform4fv(u_color, [0.0, 1.0, 0.0, 1.0]);
           
           //绘制 --指定图元 
           gl.drawArrays(gl.POINTS, 0, 1);
    
       }
      webgl();