# 2. 示例：绘制多个三角形

## 2.1. Triangle_MVPMatrix.html

<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8" />
<title>Hello Triangle</title>

<canvas id="webgl" width="400" height="400">
Please use a browser that supports "canvas"
</canvas>

<script src="../lib/webgl-utils.js"></script>
<script src="../lib/webgl-debug.js"></script>
<script src="../lib/cuon-utils.js"></script>
<script src="../lib/cuon-matrix.js"></script>
<script src="Triangle_MVPMatrix.js"></script>
</body>
</html>


## 2.2. Triangle_MVPMatrix.js

// 顶点着色器程序
'attribute vec4 a_Position;\n' + // attribute variable
'attribute vec4 a_Color;\n' +
'uniform mat4 u_MvpMatrix;\n' +
'varying vec4 v_Color;\n' +
'void main() {\n' +
'  gl_Position = u_MvpMatrix * a_Position;\n' + // Set the vertex coordinates of the point
'  v_Color = a_Color;\n' +
'}\n';

// 片元着色器程序
'precision mediump float;\n' +
'varying vec4 v_Color;\n' +
'void main() {\n' +
'  gl_FragColor = v_Color;\n' +
'}\n';

function main() {
// 获取 <canvas> 元素
var canvas = document.getElementById('webgl');

// 获取WebGL渲染上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}

// 初始化着色器
return;
}

// 设置顶点位置
var n = initVertexBuffers(gl);
if (n < 0) {
console.log('Failed to set the positions of the vertices');
return;
}

//设置MVP矩阵
setMVPMatrix(gl,canvas);

// 指定清空<canvas>的颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);

// 开启深度测试
gl.enable(gl.DEPTH_TEST);

// 清空颜色和深度缓冲区
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

// 绘制三角形
gl.drawArrays(gl.TRIANGLES, 0, n);
}

//设置MVP矩阵
function setMVPMatrix(gl,canvas) {
// Get the storage location of u_MvpMatrix
var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
if (!u_MvpMatrix) {
console.log('Failed to get the storage location of u_MvpMatrix');
return;
}

//模型矩阵
var modelMatrix = new Matrix4();
modelMatrix.setTranslate(0.75, 0, 0);

//视图矩阵
var viewMatrix = new Matrix4();  // View matrix
viewMatrix.setLookAt(0, 0, 5, 0, 0, -100, 0, 1, 0);

//投影矩阵
var projMatrix = new Matrix4();  // Projection matrix
projMatrix.setPerspective(30, canvas.width / canvas.height, 1, 100);

//MVP矩阵
var mvpMatrix = new Matrix4();
mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix);

//将MVP矩阵传输到着色器的uniform变量u_MvpMatrix
gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
}

//
function initVertexBuffers(gl) {
// 顶点坐标和颜色
var verticesColors = new Float32Array([
0.0, 1.0, -4.0, 0.4, 1.0, 0.4,  //绿色在后
-0.5, -1.0, -4.0, 0.4, 1.0, 0.4,
0.5, -1.0, -4.0, 1.0, 0.4, 0.4,

0.0, 1.0, -2.0, 1.0, 1.0, 0.4, //黄色在中
-0.5, -1.0, -2.0, 1.0, 1.0, 0.4,
0.5, -1.0, -2.0, 1.0, 0.4, 0.4,

0.0, 1.0, 0.0, 0.4, 0.4, 1.0,  //蓝色在前
-0.5, -1.0, 0.0, 0.4, 0.4, 1.0,
0.5, -1.0, 0.0, 1.0, 0.4, 0.4,
]);

//
var n = 9; // 点的个数
var FSIZE = verticesColors.BYTES_PER_ELEMENT;   //数组中每个元素的字节数

// 创建缓冲区对象
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, verticesColors, gl.STATIC_DRAW);

//获取着色器中attribute变量a_Position的地址
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, 3, gl.FLOAT, false, FSIZE * 6, 0);

// 连接a_Position变量与分配给它的缓冲区对象
gl.enableVertexAttribArray(a_Position);

//获取着色器中attribute变量a_Color的地址
var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
if (a_Color < 0) {
console.log('Failed to get the storage location of a_Color');
return -1;
}
// 将缓冲区对象分配给a_Color变量
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
// 连接a_Color变量与分配给它的缓冲区对象
gl.enableVertexAttribArray(a_Color);

// 解除绑定
gl.bindBuffer(gl.ARRAY_BUFFER, null);

return n;
}


1. 数据加入Z值；
2. 加入了深度测试；
3. MVP矩阵设置；

### 2.2.1. 数据加入Z值

  // 顶点坐标和颜色
var verticesColors = new Float32Array([
0.0, 1.0, -4.0, 0.4, 1.0, 0.4,  //绿色在后
-0.5, -1.0, -4.0, 0.4, 1.0, 0.4,
0.5, -1.0, -4.0, 1.0, 0.4, 0.4,

0.0, 1.0, -2.0, 1.0, 1.0, 0.4, //黄色在中
-0.5, -1.0, -2.0, 1.0, 1.0, 0.4,
0.5, -1.0, -2.0, 1.0, 0.4, 0.4,

0.0, 1.0, 0.0, 0.4, 0.4, 1.0,  //蓝色在前
-0.5, -1.0, 0.0, 0.4, 0.4, 1.0,
0.5, -1.0, 0.0, 1.0, 0.4, 0.4,
]);


  // ...

// 将缓冲区对象分配给a_Position变量
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);

// ...
// 将缓冲区对象分配给a_Color变量
gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);


### 2.2.2. 加入深度测试

  // ...

// 开启深度测试
gl.enable(gl.DEPTH_TEST);

// 清空颜色和深度缓冲区
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

// ...


### 2.2.3. MVP矩阵设置

  //...
'uniform mat4 u_MvpMatrix;\n' +
'void main() {\n' +
'  gl_Position = u_MvpMatrix * a_Position;\n' + // Set the vertex coordinates of the point
//...
'}\n';


//设置MVP矩阵
function setMVPMatrix(gl,canvas) {
// Get the storage location of u_MvpMatrix
var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
if (!u_MvpMatrix) {
console.log('Failed to get the storage location of u_MvpMatrix');
return;
}

//模型矩阵
var modelMatrix = new Matrix4();
modelMatrix.setTranslate(0.75, 0, 0);

//视图矩阵
var viewMatrix = new Matrix4();  // View matrix
viewMatrix.setLookAt(0, 0, 5, 0, 0, -100, 0, 1, 0);

//投影矩阵
var projMatrix = new Matrix4();  // Projection matrix
projMatrix.setPerspective(30, canvas.width / canvas.height, 1, 100);

//MVP矩阵
var mvpMatrix = new Matrix4();
mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix);

//将MVP矩阵传输到着色器的uniform变量u_MvpMatrix
gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
}


• 模型矩阵：X方向上平移了0.75个单位。
• 视图矩阵：视点为(0,0,5)，观察点为(0,0,-100)，上方向为(0,1,0)的观察视角。
• 投影矩阵：垂直张角为30，画图视图的宽高比，近截面距离为1，远截面为100的视锥体。

# 4. 参考

posted @ 2019-10-05 21:41  charlee44  阅读(832)  评论(0编辑  收藏