在三维世界中,三角形具有重要的作用。构成三维模型的基本单位就是三角形,任何复杂三维模型都可以用三角形构成。
本章知识点主要包括:
- webgl绘制多个点
- webgl绘制三角形
- 缓冲区对象如何使用
- 类型化数组
- 旋转、缩放、平移矩阵
绘制多个点
/**
* Created by hushhw on 17/12/13.
*/
//MultiPoints.js
//顶点着色器程序
var VSHADER_SOURCE =
'attribute vec4 a_Position;'+
'void main(){'+
'gl_Position=a_Position;'+
'gl_PointSize=10.0;'+
'}';
//片元着色器程序
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.POINTS, 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;
}
效果:
如何使用缓冲区对象
上述代码中
initVertexBuffers
方法使用了缓冲区对象,让我们一起看看吧
缓冲区对象是WebGL系统中一个重要的内容,它是WebGL系统中的一块存储区域,我们可以一次性向缓冲区对象中填充大量的顶点数据,然后将这些数据保存在其中,供顶点着色器使用。
使用缓冲区对象的五个标准流程:
- 创建缓冲区对象 (
gl.createBuffer()
) - 绑定缓冲区对象(
gl.bindBuffer()
) - 将数据写入缓冲区对象(
gl.bufferData()
) - 将缓冲区对象分配给一个attribute变量(
gl.vertexAttribPointer()
) - 开启
attribute
变量(gl.enableVertexAttribArray()
)
执行上述五个步骤的代码示例代码如下:
//一、创建缓冲区对象
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');
//四、将缓冲区对象分配给a_Postion变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
//五、开启attribute变量,连接a_Postion变量与分配给它的缓冲区对象
gl.enableVertexAttribArray(a_Position);
第一步 创建缓冲区对象
WebGLRenderingContext.createBuffer()
方法可创建并初始化一个用于储存顶点数据或着色数据的WebGLBuffer对象
第二步 绑定缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
WebGLRenderingContext.bindBuffer()
方法将给定的WebGLBuffer绑定到目标。 bindBuffer()
的语法: 缓冲区对象绑定到目标上后,webgl系统内部状态如下:
第三步 开辟空间并向缓冲区写入数据
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
将第2个参数vervices
中的数据写入到绑定到第一个参数gl.ARRAY_BUFFER
上的缓冲区对象。 gl.bufferData()
的语法如下: 该方法执行后,WebGL系统的内部状态如下:
第四步 将缓冲区对象分配给attribute变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, _false_, 0, 0);
gl.vertexAttribPointer()
方法可以将整个缓冲区对象的引用分配给attribute
变量。 该方法执行后,WebGL内部状态如下:
第五步 开启分配了缓冲区的attribute变量
gl.enableVertexAttribArray(a_Position);
为了使得顶点着色器能够访问缓冲区内的数据,需要使用gl.enableVertexAttribArray()
开启attribute变量。
gl.drawArrays()
移动、旋转和缩放
平移
要实现上述所示的平移操作,我们只需要将平移距离TX、TY、TZ的值,分别加在顶点坐标的对应分量上就可以。