@@ -204,4 +204,174 @@ function initVertexBuffers(gl) {
204204| Matrix4.rotate(angle,x,y,z) | 将Matrix4实例乘以一个旋转变换矩阵(该旋转矩阵旋转的角度为angle,旋转轴为<br />(x,y,z)。旋转轴(x,y,z)无须归一化),所得的结果还存储在Matrix4中 |
205205| Matrix4.scale(x,y,z) | 将Matrix4实例乘以一个缩放变换矩阵(该缩放矩阵在三个轴上的缩放因子分别为x,y和z),所得的结果还储存在Matrix4中 |
206206| Matrix4.set(m) | 将Matrix4实例设置为m,m必须也是一个Matrix4实例 |
207- | Matrix4.elements | 类型化数组(Float32Array)包含了Matrix4 实例的矩阵元素 |
207+ | Matrix4.elements | 类型化数组(Float32Array)包含了Matrix4 实例的矩阵元素 |
208+
209+ ** 单位阵在矩阵乘法中的行为,就像数字1在乘法中的行为一样。将一个矩阵乘以单位阵,得到的结果和原矩阵完全相同。在单位阵中,对角线上的元素为1.0,其余的元素为0.0**
210+
211+ 包含set前缀的方法会根据参数计算处变换矩阵,然后将变换矩阵写入到自身中;不含set前缀的方法,会先根据参数计算出变换矩阵,然后将自身与刚刚计算得到的变换矩阵相乘,然后把最终得到的结果再写入到Matrix4对象中
212+
213+ ## 复合变换
214+ 平移 旋转
215+
216+ ### 先平移后旋转
217+
218+ 平移后的坐标 = 平移矩阵 * 原始坐标
219+
220+ 旋转后的坐标 = 旋转矩阵 * 平移后的坐标
221+
222+ 即:
223+
224+ 平移后旋转的坐标 = 旋转矩阵 * (平移矩阵 * 原始坐标) = (旋转矩阵 * 平移矩阵) * 原始坐标
225+
226+ 在` javascript ` 中,计算 ` 旋转矩阵 ` * ` 平移矩阵 ` ,将得到的矩阵传入顶点着色器。这样就可以把多个变换复合起来。一个模型可能经过了多次变换
227+ 将这些变换全部复合成一个等效的变换,就得到了` 模型变换(model transformation) ` 或称` 建模变换(modeling transformation) ` ,相应地,模型变换
228+ 的矩阵称为` 模型矩阵(model matrix) `
229+
230+ ``` js
231+ const VSHADER_SOURCE =
232+ ' attribute vec4 a_Position;\n ' +
233+ ' uniform mat4 u_xformMatrix;\n ' + // [!code --]
234+ ' uniform mat4 u_ModelMatrix;\n ' + // [!code ++]
235+ ' void main() {\n ' +
236+ ' gl_Position = u_xformMatrix * a_Position;\n ' + // [!code --]
237+ ' gl_Position = u_ModelMatrix * a_Position;\n ' + // [!code ++]
238+ // 'gl_PointSize = 10.0;\n' +
239+ ' }\n '
240+ const FSHADER_SOURCE =
241+ ' void main() {\n ' +
242+ ' gl_FragColor = vec4(1.0, 1.0, 0.0,1.0);\n ' +
243+ ' }\n '
244+
245+
246+ var ANGLE = 90.0
247+
248+ function main () {
249+ var canvas = document .getElementById (' webgl' )
250+ var gl = getWebGLContext (canvas)
251+ if (! gl) {
252+ console .error (' Failed to get the rendering context for WebGL' )
253+ return ;
254+ }
255+
256+ // 初始化着色器
257+ if (! initShaders (gl, VSHADER_SOURCE , FSHADER_SOURCE )) {
258+ console .error (' Failed to initialize shaders.' )
259+ return ;
260+ }
261+
262+ // 设置顶点着色器
263+ var n = initVertexBuffers (gl);
264+
265+ if (n < 0 ) {
266+ console .error (' Failed to set the positions of the vertices' )
267+ return ;
268+ }
269+
270+ var u_xformMatrix = gl .getUniformLocation (gl .program , ' u_xformMatrix' ) // [!code --]
271+
272+ var u_ModelMatrix = gl .getUniformLocation (gl .program , ' u_ModelMatrix' ) // [!code ++]
273+
274+ var modelMatrix = new Matrix4 ()
275+
276+ xformMatrix .setRotate (ANGLE , 0 , 0 , 1 ) // [!code --]
277+
278+ gl .uniformMatrix4fv (u_xformMatrix, false , xformMatrix .elements ) // [!code --]
279+
280+ var Tx = 0.5 // [!code ++]
281+
282+
283+ modelMatrix .setRotate (ANGLE , 0 , 0 , 1 ) // [!code ++]
284+ modelMatrix .translate (Tx, 0.5 , 1 ) // [!code ++]
285+
286+ gl .uniformMatrix4fv (u_ModelMatrix, false , modelMatrix .elements ) // [!code ++]
287+
288+
289+
290+ // // 获取attribut变量的存储位置
291+ var a_Position = gl .getAttribLocation (gl .program , ' a_Position' )
292+ //
293+ // var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
294+ if (a_Position < 0 ) {
295+ console .error (' Failed to get the storage location of a_Position' )
296+ return ;
297+ }
298+ //
299+ // canvas.onmousedown = function (ev) {click(ev, gl, canvas, a_Position, u_FragColor)}
300+
301+
302+ // gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0)
303+
304+ // 设置canvas背景色
305+ gl .clearColor (0.0 , 0.0 , 0.0 , 1.0 )
306+
307+ // 清空canvas
308+ gl .clear (gl .COLOR_BUFFER_BIT );
309+
310+ // 绘制三个点
311+ gl .drawArrays (gl .TRIANGLE_FAN , 0 , n)
312+
313+ }
314+
315+ function initVertexBuffers (gl ) {
316+ var vertices = new Float32Array ([
317+ - 0.5 , 0.5 , - 0.5 , - 0.5 , 0.5 , 0.5 , 0.5 , - 0.5
318+ ])
319+ var n = 4 // 点的个数
320+
321+ // 创建缓冲区对象
322+ var vertexBuffer = gl .createBuffer ();
323+ if (! vertexBuffer) {
324+ console .error (' Failed to create the buffer object' )
325+ return - 1 ;
326+ }
327+
328+ // 将缓冲区对象绑定到目标
329+ gl .bindBuffer (gl .ARRAY_BUFFER , vertexBuffer)
330+
331+ // 向缓冲区对象中写入数据
332+ gl .bufferData (gl .ARRAY_BUFFER , vertices, gl .STATIC_DRAW );
333+
334+ var a_Position = gl .getAttribLocation (gl .program , ' a_Position' );
335+
336+ // 将缓冲区对象分配给a_Position变量
337+ gl .vertexAttribPointer (a_Position, 2 , gl .FLOAT , false , 0 , 0 )
338+
339+ // 连接a_Position变量与分配给它的缓冲对象
340+ gl .enableVertexAttribArray (a_Position)
341+ return n
342+ }
343+ ```
344+
345+ modelMatrix.setRotate(ANGLE, 0, 0, 1) // 设置模型矩阵为旋转矩阵
346+ modelMatrix.translate(Tx, 0, 0) // 将模型矩阵乘以平移矩阵
347+
348+ ** 先平移后旋转的顺序与构造模型矩阵 旋转矩阵 * 平移矩阵 的顺序是相反的,这是因为变换矩阵最终要与三角形的三个顶点的原始坐标矢量相乘**
349+
350+
351+ ** 平移旋转**
352+
353+ ``` js
354+ // 平移旋转
355+ modelMatrix .setRotate (ANGLE , 0 , 0 , 1 )
356+ modelMatrix .translate (Tx, 0.5 , 1 )
357+ ```
358+
359+ ![ 效果图] ( ./images/translateAndRotate.png )
360+
361+
362+ ** 旋转平移**
363+ ``` js
364+ // 旋转平移
365+ modelMatrix .setTranslate (Tx, 0.5 , 1 )
366+ modelMatrix .rotate (ANGLE , 0 , 0 , 1 )
367+ ```
368+
369+ ![ 效果图] ( ./images/rotateAndTranslate.png )
370+
371+
372+ ** 平移个旋转的次序不一样 导致的结果页不一样**
373+
374+
375+ ## 动画
376+
377+ 将矩阵变换运用到动画图形中去
0 commit comments