# WebGL创建鼠标事件控制的旋转立方体

691 阅读2分钟

#### 1、常规方式实现旋转

• `init`方法中添加键盘事件，通过键盘事件来控制立方体向左、向右、向下和向上运动。
``````let rotate = false;
let xaxis = 0, yaxis = 0;
function init() {
...
const keyCode = event.keyCode;
switch (keyCode) {
case 38:
//向上旋转
xaxis = 1;
yaxis=0;
break;
case 40:
//向下旋转
xaxis = -1;
yaxis=0;
break;
case 37:
//想左旋转
yaxis = -1;
xaxis = 0;
break;
case 39:
//想右旋转
yaxis = 1;
xaxis = 0;
break;
}
})
rotate=!rotate;
render(gl,program);
})
}
``````
• `render`函数中添加动画
``````function render(gl, program, count = 36) {
tranlate(gl, program);
//设置清屏颜色为黑色。
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);

gl.drawElements(gl.TRIANGLES, count, gl.UNSIGNED_SHORT, 0);
if(!rotate) return;
requestAnimationFrame(() => {
render(gl, program, count);
})
}
``````
• 在旋转函数中修改旋转角度
``````let angley = 30.0, anglex = 30;;
function tranlate(gl, program, unit = 1) {
const radx = anglex * Math.PI / 180;
const mx = gl.getUniformLocation(program, 'mx');
const mxArr = new Float32Array([
1, 0, 0, 0, 0, cosx, -sinx, 0, 0, sinx, cosx, 0, 0, 0, 0, 1
])
gl.uniformMatrix4fv(mx, false, mxArr);

const rady = angley * Math.PI / 180;
const my = gl.getUniformLocation(program, 'my');
const myArr = new Float32Array([
cosy, 0, -siny, 0, 0, 1, 0, 0, siny, 0, cosy, 0, 0, 0, 0, 1
])
gl.uniformMatrix4fv(my, false, myArr);
angley += yaxis;
anglex += xaxis;
}
``````

#### 2、通过矩阵来实现立方体的旋转

• 顶点着色器中的代码。这里就直接将矩阵相乘后的矩阵传递到顶点着色器中。
``````<script id="vertexShader" type="x-shader/x-vertex">
//浮点数设置为中等精度
precision mediump float;
attribute vec3 apos;
attribute vec4 acolor;
varying vec4 vcolor;
//uniform mat4 mx;
//uniform mat4 my;
uniform mat4 proj;
void main() {
//两个旋转矩阵、顶点齐次坐标连乘
//gl_Position = mx*my*vec4(apos, 1);
gl_Position = proj*vec4(apos, 1);
vcolor=acolor;
}
</script>
``````
• `init`函数中的不同
``````let isrotate = false;
let xaxis = 0, yaxis = 0;
let projectionMatrix;
function init() {
...
//创建正交投影矩阵
const aspect = canvas.width / canvas.height;
projectionMatrix = matrix.ortho(-aspect * 1, aspect * 1, -1, 1, 200, -200);
...
}
``````
• `rotate`函数，通过矩阵运算来实现立方体的旋转。
``````let angley = 30, anglex = 30;
//单位矩阵
let mvp = matrix.identity();
function rotate(gl, program) {
//先绕 Y 轴旋转矩阵。
matrix.rotationY(angley * Math.PI / 180, mvp);
//再绕 X 轴旋转
matrix.multiply(
mvp,
matrix.rotationX(anglex * Math.PI / 180),
mvp
);
//矩阵相乘
matrix.multiply(projectionMatrix, mvp, mvp);
const proj = gl.getUniformLocation(program, 'proj');
gl.uniformMatrix4fv(proj, false, mvp);
angley += yaxis;
anglex += xaxis;
}
``````