1.WebGL继承于OpenGL ES 2.0,只能使用可编程渲染管线,所以先创建shader:
function create_shader() {
var vs = gl.createShader(gl.VERTEX_SHADER);
var fs = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(vs, shader_src_vs);
gl.shaderSource(fs, shader_src_ps);
gl.compileShader(vs);
gl.compileShader(fs);
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) { alert(gl.getShaderInfoLog(vs)); return; }
if (!gl.getShaderParameter(fs, gl.COMPILE_STATUS)) { alert(gl.getShaderInfoLog(fs)); return; }
program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { alert(gl.getProgramInfoLog(program)); return; }
}
2.为三角形的顶点创建顶点buffer:
function create_buffer() {
var vertices = [
-0.5, 0.5, 0.0,
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
];
vertex_buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
}
3.新的变量、shader代码:
var vertex_buffer = null;
var program = null;
var shader_src_vs = "\
attribute vec4 a_position;\
void main()\
{\
gl_Position = a_position;\
}\
";
var shader_src_ps = "\
void main()\
{\
gl_FragColor = vec4(1, 0, 0, 1);\
}\
";
4.新的初始化:
function init_gl() {
gl.clearColor(0.0, 0.0, 1.0, 1.0);
create_shader();
create_buffer();
}
5.现在可以渲染了:
function render() {
update_fps();
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
var index_pos = gl.getAttribLocation(program, "a_position");
gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
gl.enableVertexAttribArray(index_pos);
gl.vertexAttribPointer(index_pos, 3, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 3);
window.requestAnimationFrame(render);
}
运行结果:
在屏幕(渲染目标canvas)坐标系中,屏幕四个顶点的坐标:
左上角(-1,1) 右上角(1,1)
左下角(-1,-1) 右下角(1,-1)
在这个例子中,三角形的顶点坐标直接定义在屏幕坐标系下,避免了渲染所需的矩阵变换,所以顶点shader里有
gl_Position = a_position;
然后在片段shader里输出红色
gl_FragColor = vec4(1, 0, 0, 1);