前面我们说 webgl 只能画点、线、三角形 3 种基本图形,那么我想画一个球,画一个宇宙飞船怎么办呢?
图形学中复杂的物体都可以由无数个三角形所构成
所以我们要画一个正方形,其实可以由两个三角形组成。
要画这个长方形,我们可以用 6 个顶点 (v0,v1,v2) (v2,v1,v3) 用 gl.drawArrays(gl.TRIANGLES, 0, 6) 来画 2 个三角形。
当然也可以只用 v0,v1,v2,v3 4 个顶点用 gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4) 来画 2 个三角形。
// vertex shader
var VERTEX_SHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'void main() {\n' +
' gl_Position = a_Position;\n' +
'}\n';
// fragment shader
var FRAGMENT_SHADER_SOURCE =
'void main() {\n' +
' gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n' +
'}\n';
var canvas = document.getElementById("canvas");
var gl = canvas.getContext('webgl');
if (!initShaders(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)) {
alert('Failed to init shaders');
}
var vertices = new Float32Array([
-0.5, 0.5, // v0
-0.5, -0.5, // v1
0.5, 0.5, // v2
0.5, -0.5 // v3
]);
initVertexBuffers(gl, vertices);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
如果我把 v2 和 v3 的顺序换一下可以吗?
var vertices = new Float32Array([
-0.5, 0.5, // v0
-0.5, -0.5, // v1
0.5, -0.5 // v3
0.5, 0.5, // v2
]);
效果是这样的
因为 gl.TRIANGLE_STRIP 对顶点的排列顺序是有要求的
构建当前三角形的顶点的连接顺序依赖于要和前面已经出现过的2个顶点组成三角形的当前顶点的序号的奇偶性(如果从0开始):
如果当前顶点是奇数:
组成三角形的顶点排列顺序:T = [n-1 n-2 n]
如果当前顶点是偶数:
组成三角形的顶点排列顺序:T = [n-2 n-1 n]
(v0,v1,v3) 构成第一个三角形,(v2,v1,v3) 构成第二个三角形,叠加在一起构成了上面的效果。
具体请参考: http://blog.csdn.net/xiajun07061225/article/details/7455283
练习:
- 用 6 个顶点画出这个正方形