构建三维模型的基本单位是三角形。通过创建细小、大量的三角形,可以创建复杂、逼真的三维模型。
-
绘制多个点
缓冲区对象:可以一次性地向着色器传入多个顶点的数据
-
设置点的坐标信息
步骤:
- 创建缓冲区对象
- 绑定缓冲区对象
- 将数据写入缓冲区对象
- 将缓冲区对象分配给一个attribute变量
- 开启attribute变量
关键代码:
function initVertexBuffers(gl) { var vertices = new Float32Array([ 0.0, 0.5, -0.5, -0.5, 0.5, -0.5 ]); var n = 3; // 点的个数 // 创建缓冲区对象 // gl.deleteBuffer(buffer)-->删除缓冲区对象 var vertexBuffer = gl.createBuffer(); if (!vertexBuffer) { console.log('Failed to create the 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_Position变量 gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0); // 连接a_Position变量与分配给它的缓冲区对象 gl.enableVertexAttribArray(a_Position); return n; }
类型化数组
gl.drawArrays()的第2和第3个参数
-
绘制三角形
-
关键代码
var VSHADER_SOURCE = 'attribute vec4 a_Position;\n' + 'void main() {\n' + ' gl_Position = a_Position;\n' + '}\n';// 删除了gl_PointSize = 10.0; // gl.drawArrays()的第一个参数变化了 gl.drawArrays(gl.TRIANGLES, 0, n);
-
-
绘制矩形
-
关键代码
// 设置四个顶点 var vertices = new Float32Array([ -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5 ]); // 定义顶点个数 var n = 4; // 绘制矩形 gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
-
-
变换(仿射变换)
-
平移
逐顶点操作:为顶点坐标的每个分量加上一个常量
关键代码
// 将平移距离的值传人顶点着色器,然后分别加在顶点坐标的对应分量上,再赋值给gl_Position var VSHADER_SOURCE = 'attribute vec4 a_Position;\n' + 'uniform vec4 u_Translation;\n' + 'void main() {\n' + ' gl_Position = a_Position + u_Translation;\n' + '}\n'; var Tx = 0.5, Ty = 0.5, Tz = 0.0; var u_Translation = gl.getUniformLocation(gl.program, 'u_Translation'); gl.uniform4f(u_Translation, Tx, Ty, Tz, 0.0);
-
旋转
- 旋转轴
- 旋转方向
- 旋转角度
关键代码:
var VSHADER_SOURCE = // x' = x cosβ - y sinβ // y' = x sinβ + y cosβ // z' = z 'attribute vec4 a_Position;\n' + 'uniform float u_CosB, u_SinB;\n' + 'void main() {\n' + ' gl_Position.x = a_Position.x * u_CosB - a_Position.y * u_SinB;\n' + ' gl_Position.y = a_Position.x * u_SinB + a_Position.y * u_CosB;\n' + ' gl_Position.z = a_Position.z;\n' + ' gl_Position.w = 1.0;\n' + '}\n'; var ANGLE = 90.0; var radian = Math.PI * ANGLE / 180.0; // 转换为弧度制 var cosB = Math.cos(radian); var sinB = Math.sin(radian); var u_CosB = gl.getUniformLocation(gl.program, 'u_CosB'); var u_SinB = gl.getUniformLocation(gl.program, 'u_SinB'); if (!u_CosB || !u_SinB) { console.log('Failed to get the storage location of u_CosB or u_SinB'); return; } gl.uniform1f(u_CosB, cosB); gl.uniform1f(u_SinB, sinB);
-
变换矩阵
-
旋转矩阵:
原理
公式
-
关键代码
var VSHADER_SOURCE = 'attribute vec4 a_Position;\n' + 'uniform mat4 u_xformMatrix;\n' + 'void main() {\n' + ' gl_Position = u_xformMatrix * a_Position;\n' + '}\n'; //创建旋转矩阵 var radian = Math.PI * ANGLE / 180.0; var cosB = Math.cos(radian), sinB = Math.sin(radian); // 注意WebGL中矩阵是列主序的 var xformMatrix = new Float32Array([ cosB, sinB, 0.0, 0.0, -sinB, cosB, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ]); // 将旋转矩阵传输给顶点着色器 var u_xformMatrix = gl.getUniformLocation(gl.program, 'u_xformMatrix'); gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);
-
-
-
平移矩阵:
- 原理
- 公式
- 关键代码:
var xformMatrix = new Float32Array([ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, Tx, Ty, Tz, 1.0 ]);
-
缩放矩阵:
原理
公式
-
关键代码
var Sx = 1.0,Sy = 1.5,Sz = 1.0 var xformMatrix = new Float32Array([ Sx, 0.0, 0.0, 0.0, 0.0, Sy, 0.0, 0.0, 0.0, 0.0, Sz, 0.0, 0.0, 0.0, 0.0, 1.0 ]);