WebGL比canvas2d 绘图爽的地方就在于性能,性能,性能!经过简单对比之后,就发现性能不是一个数量级的。
入门函数 gl.drawArrays
而从最简单的gl.drawArrays
函数入手,应该是最简单有趣的学习方式吧。 gl.drawArrays
这个函数是最终负责渲染的webgl核心函数,参数定义为:
gl.drawArrays(mode: gl.mode, start:number, count:number)
直接上最简单的代码,然后慢慢体会其中奥秘
var gl = getWebglContext(canvas); // : WebGLRenderingContext
// extern method, bind gl with Shaders..
if (!initShaders(gl, vshader, fshader)) {
console.log("failed to init shaders..");
return;
}
// 获取 Attribute 变量的存储位置
var a_Position = gl.getAttribLocation(gl.program, "a_Position");
var u_FragColor = gl.getUniformLocation(gl.program, "u_FragColor");
if (a_Position < 0 || u_FragColor < 0) {
console.log("failed to get the storage location of a_Position");
return;
}
var positions = [];
var num = 10000;
for (var j = 0; j < num; j +=1) {
// 1w points
positions.push([Math.random() * 2 - 1, Math.random() * 2 - 1]);
}
gl.clearColor(0.1, 0.1, 0.1, 1);
// use previous clearColor to clear canvas ! if no clearColor, default.
gl.clear(gl.COLOR_BUFFER_BIT);
for (var ii = 0; ii < positions.length; ii++) {
// 给顶点渲染器传递点坐标,2f表示两个浮点型数值作为一个顶点的x, y坐标..
gl.vertexAttrib2f(a_Position, positions[ii][0], positions[ii][1]);
if (positions[ii] instanceof Array && positions[ii].length > 1) {
if (positions[ii][0] > positions[ii][1]) {
// uniform4f , pass vec4 to u_FragColor in FragShader.
//// uniform4f 给片元着色器传颜色值,0~1 对应与0~255 RGBA 4个波段
gl.uniform4f(u_FragColor, 0.9, 0.6, 0.3, 1);
} else {
gl.uniform4f(u_FragColor, 0.6, 0.8, 0.9, 1);
}
}
// 每次渲染一个点,看看最开始的函数定义,第二个参数表明从哪个数值开始画,第三个参数表明画几个点。
gl.drawArrays(gl.POINTS, 0, 1);
}
稍加解释
每次经过 gl.vertextAttrib2f
函数之后,gl顶点内存中只有顶点。此时再调用 gl.drawArrays(gl.POINTS, 0, 1)
,第二个参数表明从哪个顶点开始画,第三个参数表明画几个点(有没有觉得用法像 Array.slice(start, end) ?! )。针对gl.POINTS
模式,画一个点只需要一个顶点。所以就传入0,1.效果如下图:
可以看出来,1万个顶点渲染,没用到glBuffer 的情况下,可以跑到30Fps的动画帧率,还是不错的。用glBuffer的形式可以让*帧率达到60Fps, 而同样画1万个顶点,用canvas2d 只能在20Fps左右。所以还是web GL 爽啊!!!
这么简单,下次还是继续学点有意思的,比如gl.TRIANGLES
和 gl.LINE_LOOP
.
参考
《WebGL 编程指南》