目标:
- 绘制一个简单的二维图形:三角形
- 利用三角形画一个矩形
结果:
HelloTriangle.js
//顶点着色器程序
var VSHADER_SOURCE =
'attribute vec4 a_Position;'+
'void main(){'+
'gl_Position=a_Position;'+
'}';
//片元着色器程序
var FSHADER_SOURCE=
'void main(){'+
'gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);'+
'}';
function main() {
//获取canvas元素
var canvas = document.getElementById("webgl");
if(!canvas){
console.log("Failed to retrieve the <canvas> element");
return;
}
//获取WebGL绘图上下文
var gl = getWebGLContext(canvas);
if(!gl){
console.log("Failed to get the rendering context for WebGL");
return;
}
//初始化着色器
if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){
console.log("Failed to initialize shaders.");
return;
}
//设置顶点位置
var n = initVertexBuffers(gl);
if (n < 0) {
console.log('Failed to set the positions of the vertices');
return;
}
//指定清空<canvas>颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
//清空<canvas>
gl.clear(gl.COLOR_BUFFER_BIT);
//绘制三个点
gl.drawArrays(gl.TRIANGLES, 0, n);
}
function initVertexBuffers(gl) {
var vertices = new Float32Array([
0.0, 0.5, -0.5, -0.5, 0.5, -0.5
]);
var n=3; //点的个数
//创建缓冲区对象
var vertexBuffer = gl.createBuffer();
if(!vertexBuffer){
console.log("Failed to create thie buffer object");
return -1;
}
//将缓冲区对象保存到目标上
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
//向缓存对象写入数据
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if(a_Position < 0){
console.log("Failed to get the storage location of a_Position");
return -1;
}
//将缓冲区对象分配给a_Postion变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
//连接a_Postion变量与分配给它的缓冲区对象
gl.enableVertexAttribArray(a_Position);
return n;
}
与上一节的 MultiPoint.js 相比,两处关键的改动在于:
- 在顶点着色器中,指定点的尺寸的一行 gl_pointSize = 10.0; 被删去了。该语句只有在绘制单个点的时候才起作用。
- gl.drawArray()方法的第1个参数从 gl.POINTS 被改为了 gl.TRIANGLES。
gl.drawArray()的第1个参数 mode 十分强大。在这个参数上指定不同的值,我们可以按照不同的规则绘制图形。下面详细了解一下。
基本图形
将gl.drawArrays()方法的第1个参数 mode 改为 gl.TRAINGLES,就相当于告诉WebGL,“从缓冲区的第1个顶点开始,使顶点着色器执行3次,用这3个点绘制出一个三角形”:
这样,缓冲区的3个点就不再是相互独立的,而是同一个三角形中的3个顶点。
WebGL 方法 gl.drawArray()即强大又灵活,通过给第1个参数指定不同的值,我们就能以7种不同的方式来绘制图形。下表对此进行了详细介绍,其中 v0,v1,v2等等表示缓冲区中的顶点,顶点的顺序将影响绘制的结果。
如图所示,WebGL 只能绘制三种图形:点、线段和三角形。但是,从球体到立方体,再到游戏中的三维角色,都可以由小的三角形组成。实际上,你可以用以上这些最基本的图形来绘制出任何东西。
运行下结果:
Hello Rectangle
让我们使用这个最基本的方法来试着绘制一个矩形。
下图显示了矩形的顶点。当然,顶点的个数为4,因为这是一个矩形。如上一节所述,WebGL不能直接绘制矩形,你需要将其划分为两个三角形(v0,v1,v2)和(v2,v1,v3),然后通过 gl.TRIANGLE、gl.TRIANGLE_STRIP或者gl.TRIANGLE_FAN 将其绘制出来。本例使用 gl.TRIANGLE_STRIP 进行绘制,只需要用到4个顶点。如果用 gl.TRIANGLES,就要用到6个。
运行一下: