WebGL入门学习之辅助函数initShaders()内部流程

已被阅读 1876 次 | 文章分类:javascript | 2020-06-27 22:04

在使用webgl渲染着色器的时候,将渲染的详细流程封装在一个函数,方便调用;有助于理解WebGL原生API如何将字符串形式的GLSL ES代码显卡中运行的着色器代码

一:函数作用

函数作用:编译GLSL ES代码,创建和初始化着色器供WebGl使用

二:函数内部流程

具体步骤有如下七步;

(1) 创建着色器对象:gl.createShader(type),所有的着色器对象都必须通过调用该函数创建

(2) 设置着色器程序的源代码 :gl.shaderSource(shader, source),通过该函数向着色器指定GLSL ES源代码

(3) 编译着色器: gl.compileShader(shader),向着色器传入源代码后,须有对其进行编译才可以使用;将GLSL ES代码变异成二进制的可执行文件供WebGl系统使用

(4) 创建程序对象:gl.createProgram();

(5) 为程序对象分配着色器对象:gl.attachShader(program, vertexShader);gl.attachShader(program, fragmentShader);

(6) 连接程序对象: gl.linkProgram(program);,连接顶点着色器和片元着色器

(7) webgl系统使用程序对象: gl.useProgram(program); 通过该函数告诉WebGl系统绘制时使用哪个程序对象

三:完整代码

全部代码:

                                            
function initShaders(gl, vshader, fshader) {
  let program = createProgram(gl, vshader, fshader);
  if (!program) {
    console.log('无法创建程序对象');
    return false;
  }
  // 7、使用程序对象
  gl.useProgram(program);
  gl.program = program;

  /**
   * 创建程序对象
   * @param {*} gl
   * @param {*} vshader
   * @param {*} fshader
   */
  function createProgram(gl, vshader, fshader) {
    var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
    var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
    if (!vertexShader || !fragmentShader) {
      return null;
    }

    // 4、创建程序对象
    let program = gl.createProgram();
    if (!program) {
      return null;
    }

    // 5、为程序对象分配顶点着色器和片元着色器
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);

    // 6、连接着色器
    gl.linkProgram(program);

    // 检查连接
    var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
    if (!linked) {
      var error = gl.getProgramInfoLog(program);
      console.log('无法连接程序对象: ' + error);
      gl.deleteProgram(program);
      gl.deleteShader(fragmentShader);
      gl.deleteShader(vertexShader);
      return null;
    }
    return program;
  }

  /**
   * 创建着色器对象
   * @param {} gl
   * @param {*} type
   * @param {*} source
   */
  function loadShader(gl, type, source) {
    // 1、创建着色器对象
    var shader = gl.createShader(type);
    if (shader == null) {
      console.log('无法创建着色器');
      return null;
    }
    // 2、设置着色器源代码
    gl.shaderSource(shader, source);

    ///3、编译着色器
    gl.compileShader(shader);

    // 检查着色器的编译状态
    var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    if (!compiled) {
      var error = gl.getShaderInfoLog(shader);
      console.log('编译shader失败: ' + error);
      gl.deleteShader(shader);
      return null;
    }
    return shader;
  }

  return true;
}
                                            
                                        

QQ:3410192267 | 技术支持 微信:popstarqqsmall

Copyright ©2017 xiaobaigis.com . 版权所有 鲁ICP备17027716号