首先将initShaders()函数的相关代码贴出:

/**
* Create a program object and make current
* @param gl GL context
* @param vshader a vertex shader program (string)
* @param fshader a fragment shader program (string)
* @return true, if the program object was created and successfully made current
*/
function initShaders(gl, vshader, fshader) {
var program = createProgram(gl, vshader, fshader);
if (!program) {
console.log('无法创建程序对象');
return false;
}

gl.useProgram(program);
gl.program = program;

return true;
}

/**
* Create the linked program object
* @param gl GL context
* @param vshader a vertex shader program (string)
* @param fshader a fragment shader program (string)
* @return created program object, or null if the creation has failed
*/
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;
}

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

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

// 连接着色器
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 GL context
* @param type the type of the shader object to be created
* @param source shader program (string)
* @return created shader object, or null if the creation has failed.
*/
function loadShader(gl, type, source) {
// 创建着色器对象
var shader = gl.createShader(type);
if (shader == null) {
console.log('无法创建着色器');
return null;
}

// 设置着色器源代码
gl.shaderSource(shader, source);

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

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

return shader;
}

initShaders()函数将调用createProgram()函数,后者负责创建一个连接好的程序对象。

createProgram()函数则又会调用loadShader()函数,后者负责创建一个编译好的着色器对象。

下面讲解一下这三个函数相关的作用:


initShaders():

首先调用createProgram()函数创建一个连接好的程序对象,然后告诉WebGL系统来使用这个程序对象,最后将程序悐设为gl对象的program属性。


createProgram():

通过调用loadShader()函数,创建顶点着色器和片元着色器的着色器对象。loadShader()函数返回的着色器对象已经制定过源码并已经成功编译了。

createProgram()函数自己负责创建程序对象,然后将前面撞见的顶点着色器和片元着色器分配给程序对象。

接着,该函数连接程序对象,并检查是否连接成功。如果连接成功,就返回程序对象。


loadShader():

loadShader()函数首先创建了一个着色器对象,然后为改着色器对象指定源代码,并进行编译,接着检查编译是否成功,如果编译成功,没有出错,就返回着色器对象。