WebGL旋轉
在本章中,我們將舉一個例子來演示如何使用WebGL的來旋轉三角形。
示例 - 旋轉三角形
下面的程序展示瞭如何使用 WebGL 來旋轉三角形。
<script>
/\*=================Creating a canvas=========================\*/
var canvas = document.getElementById('my\_Canvas');
gl = canvas.getContext('experimental-webgl');
/\*===========Defining and storing the geometry==============\*/
var vertices = \[ -1,-1,-1, 1,-1,-1, 1, 1,-1 \];
var colors = \[ 1,1,1, 1,1,1, 1,1,1 \];
var indices = \[ 0,1,2 \];
//Create and store data into vertex buffer
var vertex\_buffer = gl.createBuffer ();
gl.bindBuffer(gl.ARRAY\_BUFFER, vertex\_buffer);
gl.bufferData(gl.ARRAY\_BUFFER, new Float32Array(vertices), gl.STATIC\_DRAW);
//Create and store data into color buffer
var color\_buffer = gl.createBuffer ();
gl.bindBuffer(gl.ARRAY\_BUFFER, color\_buffer);
gl.bufferData(gl.ARRAY\_BUFFER, new Float32Array(colors), gl.STATIC\_DRAW);
//Create and store data into index buffer
var index\_buffer = gl.createBuffer ();
gl.bindBuffer(gl.ELEMENT\_ARRAY\_BUFFER, index\_buffer);
gl.bufferData(gl.ELEMENT\_ARRAY\_BUFFER, new Uint16Array(indices), gl.STATIC\_DRAW);
/\*==========================Shaders=========================\*/
var vertCode = 'attribute vec3 position;'+
'uniform mat4 Pmatrix;'+
'uniform mat4 Vmatrix;'+
'uniform mat4 Mmatrix;'+
'attribute vec3 color;'+//the color of the point
'varying vec3 vColor;'+
'void main(void) { '+//pre-built function
'gl\_Position = Pmatrix\*Vmatrix\*Mmatrix\*vec4(position, 1.);'+
'vColor = color;'+
'}';
var fragCode = 'precision mediump float;'+
'varying vec3 vColor;'+
'void main(void) {'+
'gl\_FragColor = vec4(vColor, 1.);'+
'}';
var vertShader = gl.createShader(gl.VERTEX\_SHADER);
gl.shaderSource(vertShader, vertCode);
gl.compileShader(vertShader);
var fragShader = gl.createShader(gl.FRAGMENT\_SHADER);
gl.shaderSource(fragShader, fragCode);
gl.compileShader(fragShader);
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertShader);
gl.attachShader(shaderProgram, fragShader);
gl.linkProgram(shaderProgram);
/\*===========associating attributes to vertex shader ============\*/
var Pmatrix = gl.getUniformLocation(shaderProgram, "Pmatrix");
var Vmatrix = gl.getUniformLocation(shaderProgram, "Vmatrix");
var Mmatrix = gl.getUniformLocation(shaderProgram, "Mmatrix");
gl.bindBuffer(gl.ARRAY\_BUFFER, vertex\_buffer);
var position = gl.getAttribLocation(shaderProgram, "position");
gl.vertexAttribTutorialser(position, 3, gl.FLOAT, false,0,0) ; //position
gl.enableVertexAttribArray(position);
gl.bindBuffer(gl.ARRAY\_BUFFER, color\_buffer);
var color = gl.getAttribLocation(shaderProgram, "color");
gl.vertexAttribTutorialser(color, 3, gl.FLOAT, false,0,0) ; //color
gl.enableVertexAttribArray(color);
gl.useProgram(shaderProgram);
/\*========================= MATRIX ========================= \*/
function get\_projection(angle, a, zMin, zMax) {
var ang = Math.tan((angle\*.5)\*Math.PI/180);//angle\*.5
return \[
0.5/ang, 0 , 0, 0,
0, 0.5\*a/ang, 0, 0,
0, 0, -(zMax+zMin)/(zMax-zMin), -1,
0, 0, (-2\*zMax\*zMin)/(zMax-zMin), 0
\];
}
var proj\_matrix = get\_projection(40, canvas.width/canvas.height, 1, 100);
var mov\_matrix = \[1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1\];
var view\_matrix = \[1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1\];
//translating z
view\_matrix\[14\] = view\_matrix\[14\]-6; //zoom
/\*=======================rotation========================\*/
function rotateZ(m, angle) {
var c = Math.cos(angle);
var s = Math.sin(angle);
var mv0 = m\[0\], mv4 = m\[4\], mv8 = m\[8\];
m\[0\] = c\*m\[0\]-s\*m\[1\];
m\[4\] = c\*m\[4\]-s\*m\[5\];
m\[8\] = c\*m\[8\]-s\*m\[9\];
m\[1\] = c\*m\[1\]+s\*mv0;
m\[5\] = c\*m\[5\]+s\*mv4;
m\[9\] = c\*m\[9\]+s\*mv8;
}
/\*=================Drawing===========================\*/
var time\_old = 0;
var animate = function(time) {
var dt = time-time\_old;
rotateZ(mov\_matrix, dt\*0.002);
time\_old = time;
gl.enable(gl.DEPTH\_TEST);
gl.depthFunc(gl.LEQUAL);
gl.clearColor(0.5, 0.5, 0.5, 0.9);
gl.clearDepth(1.0);
gl.viewport(0.0, 0.0, canvas.width, canvas.height);
gl.clear(gl.COLOR\_BUFFER\_BIT | gl.DEPTH\_BUFFER\_BIT);
gl.uniformMatrix4fv(Pmatrix, false, proj\_matrix);
gl.uniformMatrix4fv(Vmatrix, false, view\_matrix);
gl.uniformMatrix4fv(Mmatrix, false, mov\_matrix);
gl.bindBuffer(gl.ELEMENT\_ARRAY\_BUFFER, index\_buffer);
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED\_SHORT, 0);
window.requestAnimationFrame(animate);
}
animate(0);
</script>
這將產生以下結果(這裏只能放靜態圖片,具體旋轉效果可自己運行代碼觀察) -