WebGl 旋转(矩阵变换)

时间:2024-03-12 20:33:51

代码1:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>WebGl 旋转(矩阵变换)</title>
  6 </head>
  7 <body>
  8 <canvas id="myCanvas" width="500" height="300" style="border: 1px solid red"></canvas>
  9 </body>
 10 <script>
 11 
 12     window.onload = function () {
 13 
 14         //第1步 - 准备Canvas和获取WebGL的渲染上下文
 15         var canvas = document.getElementById(\'myCanvas\'),
 16             gl = canvas.getContext(\'webgl\');
 17 
 18         //第2步 - 定义几何并将其存储在缓冲区对象
 19         var vertices = [
 20                 -0.5,0.5,0.0,
 21                 0.0,0.5,0.0,
 22                 -0.25,0.25,0.0,
 23             ],
 24             colors = [
 25                 0,0,1,
 26                 1,0,0,
 27                 0,1,0,],
 28             indices =[0,1,2];
 29 
 30         var vertex_buffer = gl.createBuffer();
 31         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
 32         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
 33 
 34         var color_buffer = gl.createBuffer ();
 35         gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
 36         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
 37 
 38         var index_buffer = gl.createBuffer();
 39         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
 40         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
 41 
 42         //第3步 - 创建和编译着色器程序
 43         var vertCode =
 44             \'attribute vec3 coordinates;\' +
 45             \'uniform mat4 rotate;\'+
 46             \'attribute vec3 color;\'+
 47             \'varying vec3 vColor;\'+
 48             \'void main(void) {\' +
 49             \' gl_Position = rotate*vec4(coordinates,1.0);\' +
 50             \'vColor = color;\'+
 51             \'}\';
 52 
 53         var fragCode =
 54             \'precision mediump float;\'+
 55             \'varying vec3 vColor;\'+
 56             \'void main(void) {\' +
 57             \' gl_FragColor = vec4(vColor, 1);\' +
 58             \'}\';
 59 
 60         var vertShader = gl.createShader(gl.VERTEX_SHADER);
 61         var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
 62         gl.shaderSource(vertShader, vertCode);
 63         gl.shaderSource(fragShader, fragCode);
 64         gl.compileShader(vertShader);
 65         gl.compileShader(fragShader);
 66         var shaderProgram = gl.createProgram();
 67         gl.attachShader(shaderProgram, vertShader);
 68         gl.attachShader(shaderProgram, fragShader);
 69         gl.linkProgram(shaderProgram);
 70         gl.useProgram(shaderProgram);
 71 
 72 
 73         //第4步 - 关联着色器程序到缓冲区对象
 74 
 75 
 76         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
 77         var coord = gl.getAttribLocation(shaderProgram, \'coordinates\');
 78         gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
 79         gl.enableVertexAttribArray(coord);
 80 
 81         gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
 82         var color = gl.getAttribLocation(shaderProgram, "color");
 83         gl.vertexAttribPointer(color, 3, gl.FLOAT, false,0,0) ; //color
 84         gl.enableVertexAttribArray(color);
 85 
 86         //绕着Z轴旋转
 87         var init_angle = 0.0;//初始角度
 88         var angle_step = 1;//旋转步伐
 89         var current_angle = init_angle;
 90         var radian = Math.PI * (current_angle % 360) / 180.0;
 91         var cosB = Math.cos(radian);
 92         var sinB = Math.sin(radian);
 93         var xformMatrix = new Float32Array([
 94             cosB,  sinB, 0.0, 0.0,
 95             -sinB, cosB, 0.0, 0.0,
 96             0.0,    0.0, 1.0, 0.0,
 97             0.0,    0.0, 0.0, 1.0
 98         ]);
 99         var rotate = gl.getUniformLocation(shaderProgram, "rotate");
100         gl.uniformMatrix4fv(rotate, false, xformMatrix);
101 
102         //第5步 - 绘制所需的对象
103         setInterval(function () {
104             radian = Math.PI * (current_angle % 360) / 180.0;
105             cosB = Math.cos(radian);
106             sinB = Math.sin(radian);
107             xformMatrix = new Float32Array([
108                 cosB,  sinB, 0.0, 0.0,
109                 -sinB, cosB, 0.0, 0.0,
110                 0.0,    0.0, 1.0, 0.0,
111                 0.0,    0.0, 0.0, 1.0
112             ]);
113             gl.uniformMatrix4fv(rotate, false, xformMatrix);
114 
115             gl.enable(gl.DEPTH_TEST);
116             gl.depthFunc(gl.LEQUAL);
117             gl.clearColor(0.5, 0.5, 0.5, 0.9);
118             gl.clearDepth(1.0);
119             gl.viewport(0.0, 0.0, canvas.width, canvas.height);
120             gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
121             gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
122 
123 
124             //当前角度
125             current_angle = current_angle + angle_step;
126 
127         },10);
128 
129 
130 
131 
132 
133     }
134 
135 </script>
136 </html>

 

代码2:

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>WebGl 旋转(矩阵变换)</title>
  6 </head>
  7 <body>
  8 <canvas id="myCanvas" width="500" height="300" style="border: 1px solid red"></canvas>
  9 </body>
 10 <script>
 11 
 12     window.onload = function () {
 13 
 14         //第1步 - 准备Canvas和获取WebGL的渲染上下文
 15         var canvas = document.getElementById(\'myCanvas\'),
 16             gl = canvas.getContext(\'webgl\');
 17 
 18         //第2步 - 定义几何并将其存储在缓冲区对象
 19         var vertices = [
 20                 -0.5,0.5,0.0,
 21                 0.0,0.5,0.0,
 22                 -0.25,0.25,0.0,
 23             ],
 24             colors = [
 25                 0,0,1,
 26                 1,0,0,
 27                 0,1,0,],
 28             indices =[0,1,2];
 29 
 30         var vertex_buffer = gl.createBuffer();
 31         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
 32         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
 33 
 34         var color_buffer = gl.createBuffer ();
 35         gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
 36         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
 37 
 38         var index_buffer = gl.createBuffer();
 39         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index_buffer);
 40         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
 41 
 42         //第3步 - 创建和编译着色器程序
 43         var vertCode =
 44             \'attribute vec3 coordinates;\' +
 45             \'uniform mat4 Pmatrix;\'+
 46             \'uniform mat4 Vmatrix;\'+
 47             \'uniform mat4 Mmatrix;\'+
 48             \'attribute vec3 color;\'+
 49             \'varying vec3 vColor;\'+
 50             \'void main(void) {\' +
 51             \' gl_Position = Pmatrix*Vmatrix*Mmatrix*vec4(coordinates,1.0);\' +
 52             \'vColor = color;\'+
 53             \'}\';
 54 
 55         var fragCode =
 56             \'precision mediump float;\'+
 57             \'varying vec3 vColor;\'+
 58             \'void main(void) {\' +
 59             \' gl_FragColor = vec4(vColor, 1);\' +
 60             \'}\';
 61 
 62         var vertShader = gl.createShader(gl.VERTEX_SHADER);
 63         var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
 64         gl.shaderSource(vertShader, vertCode);
 65         gl.shaderSource(fragShader, fragCode);
 66         gl.compileShader(vertShader);
 67         gl.compileShader(fragShader);
 68         var shaderProgram = gl.createProgram();
 69         gl.attachShader(shaderProgram, vertShader);
 70         gl.attachShader(shaderProgram, fragShader);
 71         gl.linkProgram(shaderProgram);
 72         gl.useProgram(shaderProgram);
 73 
 74 
 75         //第4步 - 关联着色器程序到缓冲区对象
 76         var Pmatrix = gl.getUniformLocation(shaderProgram, "Pmatrix");
 77         var Vmatrix = gl.getUniformLocation(shaderProgram, "Vmatrix");
 78         var Mmatrix = gl.getUniformLocation(shaderProgram, "Mmatrix");
 79 
 80         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
 81         var coord = gl.getAttribLocation(shaderProgram, \'coordinates\');
 82         gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);
 83         gl.enableVertexAttribArray(coord);
 84 
 85         gl.bindBuffer(gl.ARRAY_BUFFER, color_buffer);
 86         var color = gl.getAttribLocation(shaderProgram, "color");
 87         gl.vertexAttribPointer(color, 3, gl.FLOAT, false,0,0) ; //color
 88         gl.enableVertexAttribArray(color);
 89 
 90 
 91         //
 92         var proj_matrix = get_projection(40, canvas.width/canvas.height, 1, 100);
 93         var mov_matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1];
 94         var view_matrix = [1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1];
 95 
 96         //translating z
 97         view_matrix[14] = view_matrix[14]-2; //zoom
 98 
 99         //第5步 - 绘制所需的对象
100         var time_old = 0;
101         var animate = function(time) {
102             var dt = time-time_old;
103             rotateZ(mov_matrix, dt*0.002);
104             time_old = time;
105 
106             gl.enable(gl.DEPTH_TEST);
107             gl.depthFunc(gl.LEQUAL);
108             gl.clearColor(0.5, 0.5, 0.5, 0.9);
109             gl.clearDepth(1.0);
110             gl.viewport(0.0, 0.0, canvas.width, canvas.height);
111             gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
112 
113             // 将旋转矩阵传输给顶点着色器
114             gl.uniformMatrix4fv(Pmatrix, false, proj_matrix);
115             gl.uniformMatrix4fv(Vmatrix, false, view_matrix);
116             gl.uniformMatrix4fv(Mmatrix, false, mov_matrix);
117 
118             gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
119             window.requestAnimationFrame(animate);
120         }
121 
122         animate(0);
123 
124         /*========================= MATRIX ========================= */
125 
126         function get_projection(angle, a, zMin, zMax) {
127             var ang = Math.tan((angle*.5)*Math.PI/180);//angle*.5
128             return [
129                 0.5/ang, 0 , 0, 0,
130                 0, 0.5*a/ang, 0, 0,
131                 0, 0, -(zMax+zMin)/(zMax-zMin), -1,
132                 0, 0, (-2*zMax*zMin)/(zMax-zMin), 0
133             ];
134         }
135 
136 
137 
138         //z轴旋转
139         function rotateZ(m, angle) {
140             var c = Math.cos(angle);
141             var s = Math.sin(angle);
142             var mv0 = m[0], mv4 = m[4], mv8 = m[8];
143 
144             m[0] = c*m[0]-s*m[1];
145             m[4] = c*m[4]-s*m[5];
146             m[8] = c*m[8]-s*m[9];
147             m[1] = c*m[1]+s*mv0;
148             m[5] = c*m[5]+s*mv4;
149             m[9] = c*m[9]+s*mv8;
150         }
151 
152 
153 
154 
155     }
156 
157 </script>
158 </html>