前言
上一节中,我们学习了缓冲区对象,可以一次性向顶点着色器传递大量的数据,这样就可以画出复杂的图形。这节我们就利用缓冲区对象绘制三角形。
三角形绘制
和上节所使用的代码基本上一致,
// Vertex shader program
var VSHADER_SOURCE = ```
attribute vec4 a_Position;
void main() {
gl_Position = a_Position;
}```
// Fragment shader program
var FSHADER_SOURCE =```
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}```
function main() {
var canvas = document.getElementById('webgl');
var gl = getWebGLContext(canvas);
// 初始化着色器
initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE);
// 设置顶点位置
var n = initVertexBuffers(gl);
// 设置背景色
gl.clearColor(0, 0, 0, 1);
// 清空 <canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, n);
}
function initVertexBuffers(gl) {
var vertices = new Float32Array([
0, 0.5, -0.5, -0.5, 0.5, -0.5
]);
var n = 3; // 顶点个数
// 创建缓冲区对象
var vertexBuffer = gl.createBuffer();
// 将缓冲区对象绑定到目标
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// 向缓冲区对象中写入数据
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
// 将缓冲区对象分配给 a_Position 变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
// 连接 a_Position 变量与分配给它的缓冲区对象
gl.enableVertexAttribArray(a_Position);
return n;
}
其中最主要的改动是将 drawArrays 中的 mode 改为 gl.TRIANGLES,这样缓冲区中存储的三个点便不是独立的了,而是三角形中的三个顶点了:
gl.drawArrays(gl.TRIANGLES, 0, n);
基本图形
在 WebGL 中的 gl.drawArrays() 既强大又灵活,通过第一个参数 mode 指定不同的值,我们就可以绘制7中不同的图形。
| 基本图形 | 参数 mode | 描述 |
|---|---|---|
| 点 | gl.POINTS | 一系列点,绘制在 v0、v1、v2 .... 处。 |
| 线段 | gl.LINES | 一系列单独的线段,绘制在 (v0, v1)、(v2, v3)、(v4, v5) ...... 处,如果点的个数是奇数,最后一个点被忽略。 |
| 线条 | gl.LINE_STRIP | 一系列连接的线段,被绘制在(v0, v1)、(v1, v2)、(v2, v3) ... (vn-1, vn) 处。vn是最后一个点。 |
| 回路 | gl.LINE_LOOP | 一系列连接的线段,被绘制在(v0, v1)、(v1, v2)、(v2, v3) ... (vn-1, vn)、(vn, v0) 处。和 gl.LINE_STRIP 相似,增加了最后一个点和第一个点的连线。 |
| 三角形 | gl.TRIANGLES | 一系列单独的三角形,绘制在(v0, v1, v2)、(v3, v4, v5)、 ... 处,若点的个数不是3的倍数,最后剩余的1个或2个点被忽略。 |
| 三角带 | gl.TRIANGLE_STRIP | 一系列条带状的三角形,前3个点构成了第1个三角形,从2个点开始的3个点构成了第2个三角形(该三角形和一个三角形共享一条边),以此类推。这些三角形被绘制在 (v0, v1, v2)、(v2, v1, v3)、(v2, v3, v4)、 ... 处(注意点的顺序) |
| 三角扇 | gl.TRIANGLE_FAN | 一系列三角形组成的类似扇形的图形。前3个点构成第1个三角形,接下来的一个点和前一个三角形的最后一条边组成接下来的一个三角形。这些三角形被绘制在 (v0, v1, v2)、(v0, v2, v3)、(v0, v3, v4)、 ...处。 |
在 gl.TRIANGLE_STRIP 中,第2个三角形是 (v2, v1, v3) ,而不是 (v1, v2, v3) ,这是为了保证第2个三角形的绘制也是按照逆时针的顺序。
这张图展示了这些基本图形: