注明
该代码源于Interactive Computer Graphics
Edward Angel and Dave Shreiner
Eighth Edition, Pearson Education, 2020
为更好理解此代码,仅添加部分注释
WebGL 按钮控制旋转
大概思路
关于旋转的思路,请移步此处
该代码使用了按钮控制和键盘按键控制,思路都是一样的。
对于实现反向旋转功能:只需要把每次旋转的角度 theta 取反就可以了,这里是设置了Direction布尔值
对于加速还是减速,使用 setTimeout() 方法可以控制延迟时间,当加速时,减少延迟时间 delay,减速时加大delay值
HTML文件
<!DOCTYPE html>
<html>
<title>Rotating Square</title>
<script id="vertex-shader" type="x-shader/x-vertex">
#version 300 es
in vec4 aPosition;
uniform float uTheta;
void main()
{
float s = sin(uTheta);
float c = cos(uTheta);
gl_Position.x = -s*aPosition.y + c*aPosition.x;
gl_Position.y = s*aPosition.x + c*aPosition.y;
gl_Position.z = 0.0;
gl_Position.w = 1.0;
}
</script>
<script id="fragment-shader" type="x-shader/x-fragment">
#version 300 es
precision mediump float;
out vec4 fColor;
void main()
{
fColor = vec4( 1.0, 0.0, 0.0, 1.0 );
}
</script>
<script type="text/javascript" src="../Common/initShaders.js"></script>
<script type="text/javascript" src="../Common/MVnew.js"></script>
<script type="text/javascript" src="rotatingSquare2.js"></script>
</head>
<body>
<button id="Direction">Change Rotation Direction</button>
<select id="Controls" size="3">
<option value="0">Toggle Rotation Direction</option>
<option value="1">Spin Faster</option>
<option value="2">Spin Slower</option>
</select>
<canvas id="gl-canvas" width="512" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>
JavaScript文件
"use strict";
var gl;
var theta = 0.0;
var thetaLoc;
var delay = 100;
var direction = true;
// onload用于在网页加载完毕后立刻执行的操作
window.onload = function init()
{
var canvas = document.getElementById( "gl-canvas");
gl = canvas.getContext('webgl2');
if (!gl) alert("WebGL 2.0 isn't available");
//
// Configure WebGL
//
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clearColor(1.0, 1.0, 1.0, 1.0);
// Load shaders and initialize attribute buffers
var program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
var vertices = [
vec2(0, 1),
vec2(-1, 0),
vec2(1, 0),
vec2(0, -1)
];
// Load the data into the GPU
var vBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vBuffer);
gl.bufferData(gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW);
// Associate out shader variables with our data buffer
var positionLoc = gl.getAttribLocation( program, "aPosition");
gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLoc);
thetaLoc = gl.getUniformLocation( program, "uTheta" );
// Initialize event handlers
//该部分是网页按钮功能
//Direction按键改变了使得theta角度取反,从而反向旋转
document.getElementById("Direction").onclick = function () {
direction = !direction;
};
document.getElementById("Controls" ).onclick = function(event) {
switch(event.target.index) {
case 0:
direction = !direction;
break;
case 1:
delay /= 2.0;
break;
case 2:
delay *= 2.0;
break;
}
};
//该部分是可以使用键盘按键控制
//onkeydown属性返回当前元素上的onKeyDown事件处理程序代码,按下就会执行对应的代码
window.onkeydown = function(event) {
// fromCharCode将 Unicode 编码转为一个字符
// keycode获取按下的键盘按键Unicode值
var key = String.fromCharCode(event.keyCode);
switch(key) {
case '1':
direction = !direction;
break;
case '2':
delay /= 2.0;
break;
case '3':
delay *= 2.0;
break;
}
};
render();
};
function render()
{
gl.clear(gl.COLOR_BUFFER_BIT);
theta += (direction ? 0.1 : -0.1);
gl.uniform1f(thetaLoc, theta);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
//setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。
setTimeout(
function (){requestAnimationFrame(render);}, delay
);
}