在三維程序中,繪製第一個三角形就像寫一個“Hello World”一樣代表的寫三維程序的開始,在以往C&C++裏用OpenGL繪製一個三角化很容易,但在WebGL裏從哪裏入手呢?當然,還是先創建VertexBuffer, 然後BindBuffer後Draw一個三角面就可以,但在WebGL裏,採用了OpenGL ES2.0的接口,那又如何呢?那必須先寫好Shader纔可以,怎麼WebGL像DirectX 10&11一樣囉嗦了?但我覺得這是一個進步,用靈活的可編程Shader代替N多的GL API不是好事麼?我比較喜歡簡單的程序,相信每個優秀的程序員都喜歡。
1. 創建Shader的function
WebGL有Vertex shader和Fragment shader兩種,我們創建一個專門創建和編譯Shader的方法:
function buildShader (gl, type, string) {
var shader;
if (type === "fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
}
else if (type === "vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
}
gl.shaderSource(shader, string);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error(gl.getShaderInfoLog(shader));
console.error(string);
return null;
}
return shader;
}
有了建好的Shader,我們就可以創建和連接一個Program:
function buildProgram (gl, vertexShader, fragmentShader) {
var program = gl.createProgram();
var glVertexShader = buildShader(gl, "vertex", vertexShader);
var glFragmentShader = buildShader(gl, "fragment", fragmentShader);
gl.attachShader(program, glVertexShader);
gl.attachShader(program, glFragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.log(fragmentShader);
console.log(vertexShader);
}
return program;
}
3. 創建一個簡單的Program對像
我們先只寫一個最簡單的Shader,不用任何頂點變化,基本上是不能再簡單了:
var vertexShader =
'attribute vec4 vPosition; \n\
void main() \n\
{ \n\
gl_Position = vPosition; \n\
} \n';
var fragmentShader =
'precision mediump float; \n\
void main() \n\
{ \n\
gl_FragColor = vec4 ( 1.0, 1.0, 0.0, 1.0 );\n\
}\n';
然後用之前定義的buildProgram來創建Program對像:
program = buildProgram(gl, vertexShader, fragmentShader);
4. 創建VertexBuffer
在JavaScript無法直接使用二進制數據比較麻煩,但我們可以用Float32Array來創建定點緩存然後交給WebGL,我們首先創建一個Float3dArray:
var vertices = new Float32Array(
[0.0, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0]);
然後創建WebGL VBO對像,並把頂點數據交給VBO:
vb = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vb);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
記得從Program裏獲得"vPosition"屬性的location:
vb.vertexAttribLoc = gl.getAttribLocation(program, "vPosition");
5. 繪製三角形:
剩下的就是繪製三角形了,在之前定義的updateFrame中添加繪製代碼,首先是綁定Program:
gl.useProgram(program);
然後綁定VertexBuffer:
gl.bindBuffer(gl.ARRAY_BUFFER, vb);
gl.vertexAttribPointer(vb.vertexAttribLoc, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(vb.vertexAttribLoc);
最後繪製一個三角形:
gl.drawArrays(gl.TRIANGLES, 0, 3);
在Shader裏gl_FragColor被設置成了固定的顏色,你可以隨意改,然後只需要刷新下網頁就可以,這就是腳本語言最大的魅力,如果不要求大數據和高性能的話。