概念
WebGLProgram 是 WebGL 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 上进行操作的。
网友评论