深入理解 webgl

2. 深入理解 WebGLProgram 对象

2019-07-20  本文已影响0人  纯爱枫若情

概念

WebGLProgramWebGL API 的一部分,它由两个 WebGLShader (webgl着色器)组成,分别为顶点着色器和片元着色器(两种着色器都是由 GLSL 语言来写的)。

**WebGLProgram **需要调用GL上下文的 createProgram() 方法,然后调用 attachShader() 方法附加上着色器,之后你才能将它们连接到一个可用的程序。

使用方式

构造一个方法,传入 WebGLRenderingContext、vertexShader 和 fragmentShader,返回一个 WebGLProgram。

function createProgram(gl, vertexShader, fragmentShader) {
  // 调用 createProgram api 创建一个 WebGLProgram 对象
  var program = gl.createProgram();
  
  // 给 WebGLProgram 对象关联上两种着色器
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  
  // 链接一个给定的 WebGLProgram 到已附着的顶点着色器和片段着色器。
  gl.linkProgram(program);
  
  // 检测当前程序链接状态
  var success = gl.getProgramParameter(program, gl.LINK_STATUS);
  if (success) {
    return program;
  }

  // 如果不成功,获取返回的报错信息,同时删除掉当前创建的程序
  console.log(gl.getProgramInfoLog(program));
  gl.deleteProgram(program);
}

相关 api

a. gl.isProgram()

这个方法,用来检测目标对象是否为 WebGLProgram 对象。

用法:

gl.isProgram(program)   // true

b. gl.deleteProgram()

删除 WebGLProgram 对象。

使用方式:

gl.deleteProgram(program)   // true

c. gl.attachShader()

附着给定的 shader,一般情况下,要附着 vertexShader 和 fragmentShader,分别是顶点着色器和片元着色器。

使用方式:

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

d. gl.linkProgram()

链接一个给定的 WebGLProgram 到已附着的顶点着色器和片段着色器。

gl.linkProgram(program);

其实这个地方的逻辑我是有点不理解的,明明上一步不是 attach 了么,为什么还要继续 linkProgram,可能是语言使用过程中本身必要的步骤吧。

就像如果先学的是 c\c++ 或者 Java,你再去看 JavaScript 或者 python 的时候,你肯定会觉得他们好奇怪,为什么不用 main 函数当作代码的入口,而是直接上来就按照顺序执行。

总结

看了上面的使用方式和相关的 api,你肯定会说,很简单吧,确实很简单,无非就是先调用 WebGLRenderingContext 上的 api 创建一个 WebGLProgram 对象的实例,然后将 vertexShader 和 FragmentShader 附着到创建好的这个 WebGLProgram 对象上,然后再链接一下这个 program。

但是如果不多细想几遍,多自己敲几遍,习惯了 JavaScript 编程习惯的人一时间还是不太好适应这个过程的,毕竟如果要是我设计这个 api 的话,我说不定就这样设计了:

const program = new gl.Program(vertexShader, fragmentShader);

直接就这样一步到位,后面的什么附着啊,链接啊都给省了。

我想这样写也许更符合 JavaScript 的编程习惯吧。

至于为什么 webgl 这一块要设计的这么复杂,说实话,目前我也搞不懂。

和 WebGLShader 对象一样,这个 WebGLProgram 对象,本身也是没有任何的属性的,所以看到这里就应该明白了,webgl 编程的逻辑了,有些重要的对象,本身相当于就是一个指针,自己根本称不上是一个对象,而大部分对象,就是放在 gl 上进行操作的。

上一篇 下一篇

猜你喜欢

热点阅读