40 WebGL着色器和着色器程序对象:initShader()函数的内部流程

2018-03-04 03:18:42 人阅读

案例查看有问题?
全屏试试!

案例解析

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

 

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

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

 

initShaders():

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

 

createProgram():

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

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

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

 

loadShader():

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

案例源代码


                        
/** 
 * 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;  
}  
展开内容

联系我们

一个人的力量不如两个人的,两个人的力量不如一群人的。欢迎加入大家庭一起共同学习,共同进步。

查看更多