更新于 

附录F:从文件中加载着色器

本案例主要介绍如何将着色器程序从js中提取出来。

LoadShaderFromFiles Code
LoadShaderFromFiles运行效果
LoadShaderFromFiles运行效果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function readShaderFile(gl, fileName, shader) {
let request = new XMLHttpRequest()
request.onreadystatechange = function () {
if (request.readyState === 4 && request !== 404) {
onReadShader(gl, request.responseText, shader)
}
}
request.open('GET', fileName, true)
request.send()
}

function onReadShader(gl, fileString, shader) {
if (shader === 'v') {
VSHADER_SOURCE = fileString
}
if (shader === 'f') {
FSHADER_SOURCE = fileString
}
if(VSHADER_SOURCE && FSHADER_SOURCE) start(gl)
}
ColoredTriangle.vert
1
2
3
4
5
6
7
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main(){
gl_Position = a_Position;
v_Color = a_Color;
}
ColoredTriangle.frag
1
2
3
4
5
6
7
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 v_Color;
void main(){
gl_FragColor = v_Color;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
let VSHADER_SOURCE = null
let FSHADER_SOURCE = null

function main() {
let canvas = document.getElementById('webgl')
let gl = getWebGLContext(canvas)
if (!gl) {
console.log('failed to get webgl context')
return
}
readShaderFile(gl, 'ColoredTriangle.vert', 'v')
readShaderFile(gl, 'ColoredTriangle.frag', 'f')
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
function start(gl) {
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('failed to init shaders')
return
}
let n = initVertexBuffers(gl)
if (n < 0) {
console.log('failed to init vertex buffers')
return
}
gl.clearColor(0, 0, 0, 1)
gl.clear(gl.COLOR_BUFFER_BIT)
gl.drawArrays(gl.TRIANGLES,0,n)
}

function initVertexBuffers(gl) {
let verticesColors = new Float32Array([
0.0, 0.5, 1.0, 0.0, 0.0,
-0.5, -0.5, 0.0, 1.0, 0.0,
0.5, -0.5, 0.0, 0.0, 1.0
])
let n = 3
let FSIZE = verticesColors.BYTES_PER_ELEMENT
let a_Position = gl.getAttribLocation(gl.program, 'a_Position')
let a_Color = gl.getAttribLocation(gl.program, 'a_Color')
if (a_Position < 0 || a_Color < 0) {
return -1
}
let vertexBuffer = gl.createBuffer()
let colorBuffer = gl.createBuffer()
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW)
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 5 * FSIZE, 0)
gl.enableVertexAttribArray(a_Position)

gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer)
gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW)
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, 5 * FSIZE, 2 * FSIZE)
gl.enableVertexAttribArray(a_Color)

return n
}