40 WebGL著色器和著色器程式物件:initShader()函式的內部流程
阿新 • • 發佈:2019-02-10
首先將initShaders()函式的相關程式碼貼出:
initShaders()函式將呼叫createProgram()函式,後者負責建立一個連線好的程式物件。/** * 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; }
createProgram()函式則又會呼叫loadShader()函式,後者負責建立一個編譯好的著色器物件。
下面講解一下這三個函式相關的作用:
initShaders():
首先呼叫createProgram()函式建立一個連線好的程式物件,然後告訴WebGL系統來使用這個程式物件,最後將程式悐設為gl物件的program屬性。
createProgram():
通過呼叫loadShader()函式,建立頂點著色器和片元著色器的著色器物件。loadShader()函式返回的著色器物件已經制定過原始碼並已經成功編譯了。
createProgram()函式自己負責建立程式物件,然後將前面撞見的頂點著色器和片元著色器分配給程式物件。
接著,該函式連線程式物件,並檢查是否連線成功。如果連線成功,就返回程式物件。
loadShader():
loadShader()函式首先建立了一個著色器物件,然後為改著色器物件指定原始碼,並進行編譯,接著檢查編譯是否成功,如果編譯成功,沒有出錯,就返回著色器物件。