7、视点,观察目标点,上方向

模型视图矩阵 = 视图矩阵 模型矩阵
从视点看上去的“旋转后的顶点坐标”=模型视图矩阵
原顶点坐标

移动视点与移动被观察对象等效,不过他们的移动方向正好相反
{“eyeX”:0,”eyeY”:0,”eyeZ”:0,”atX”:-0.25,”atY”:-0.25,”atZ”:-0.25,”upX”:0,”upY”:1,”upZ”:0}
=
{“eyeX”:0.25,”eyeY”:0.25,”eyeZ”:0.25,”atX”:0,”atY”:0,”atZ”:0,”upX”:0,”upY”:1,”upZ”:0}

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8" />
  5. <title>Clear canvas</title>
  6. </head>
  7. <body>
  8. <canvas id="webgl" width="400" height="400">
  9. Please use the browser supporting "canvas"
  10. </canvas>
  11. <div>
  12. <button onclick="change('add', 'eyeX')">eyeX+</button>
  13. <button onclick="change('remove', 'eyeX')">eyeX-</button>
  14. <br />
  15. <button onclick="change('add', 'eyeY')">eyeY+</button>
  16. <button onclick="change('remove', 'eyeY')">eyeY-</button>
  17. <br />
  18. <button onclick="change('add', 'eyeZ')">eyeZ+</button>
  19. <button onclick="change('remove', 'eyeZ')">eyeZ-</button>
  20. <br />
  21. <button onclick="change('add', 'atX')">atX+</button>
  22. <button onclick="change('remove', 'atX')">atX-</button>
  23. <br />
  24. <button onclick="change('add', 'atY')">atY+</button>
  25. <button onclick="change('remove', 'atY')">atY-</button>
  26. <br />
  27. <button onclick="change('add', 'atZ')">atZ+</button>
  28. <button onclick="change('remove', 'atZ')">atZ-</button>
  29. <br />
  30. <button onclick="change('add', 'upX')">upX+</button>
  31. <button onclick="change('remove', 'upX')">upX-</button>
  32. <br />
  33. <button onclick="change('add', 'upY')">upY+</button>
  34. <button onclick="change('remove', 'upY')">upY-</button>
  35. <br />
  36. <button onclick="change('add', 'upZ')">upZ+</button>
  37. <button onclick="change('remove', 'upZ')">upZ-</button>
  38. <br />
  39. <div>
  40. <div id="content"></div>
  41. </div>
  42. </div>
  43. <script src="../lib/webgl-utils.js"></script>
  44. <script src="../lib/webgl-debug.js"></script>
  45. <script src="../lib/cuon-utils.js"></script>
  46. <script src="../lib/cuon-matrix.js"></script>
  47. <script>
  48. const obj = {
  49. eyeX: 0.25,
  50. eyeY: 0.25,
  51. eyeZ: 0.25,
  52. atX: 0,
  53. atY: 0,
  54. atZ: 0,
  55. upX: 0,
  56. upY: 1,
  57. upZ: 0
  58. }
  59. function innerHtml() {
  60. document.getElementById("content").innerHTML = JSON.stringify(obj)
  61. }
  62. function change(type, name) {
  63. if (type === 'add') {
  64. obj[name] += 0.01;
  65. } else {
  66. obj[name] -= 0.01;
  67. }
  68. if (obj[name] > 1) {
  69. obj[name] = 0;
  70. } else if (obj[name] < 0) {
  71. obj[name] = 1
  72. }
  73. main()
  74. innerHtml()
  75. }
  76. // Vertex shader program
  77. var VSHADER_SOURCE =
  78. 'attribute vec4 a_Position;\n' +
  79. 'attribute vec4 a_Color;\n' +
  80. 'uniform mat4 u_ViewMatrix;\n' + // 视图矩阵
  81. 'varying vec4 v_Color;\n' +
  82. 'void main() {\n' +
  83. ' gl_Position = u_ViewMatrix * a_Position;\n' + // 视图矩阵 * 原始顶点坐标
  84. ' v_Color = a_Color;\n' +
  85. '}\n';
  86. // Fragment shader program
  87. var FSHADER_SOURCE =
  88. '#ifdef GL_ES\n' +
  89. 'precision mediump float;\n' +
  90. '#endif\n' +
  91. 'varying vec4 v_Color;\n' +
  92. 'void main() {\n' +
  93. ' gl_FragColor = v_Color;\n' +
  94. '}\n';
  95. function main() {
  96. // Retrieve <canvas> element
  97. var canvas = document.getElementById('webgl');
  98. // Get the rendering context for WebGL
  99. var gl = getWebGLContext(canvas);
  100. if (!gl) {
  101. console.log('Failed to get the rendering context for WebGL');
  102. return;
  103. }
  104. // Initialize shaders
  105. if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
  106. console.log('Failed to intialize shaders.');
  107. return;
  108. }
  109. // Set the vertex coordinates and color (the blue triangle is in the front)
  110. var n = initVertexBuffers(gl);
  111. if (n < 0) {
  112. console.log('Failed to set the vertex information');
  113. return;
  114. }
  115. gl.clearColor(0, 0, 0, 1);
  116. // 获取试图矩阵变量
  117. var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
  118. if (!u_ViewMatrix) {
  119. console.log('Failed to get the storage locations of u_ViewMatrix');
  120. return;
  121. }
  122. // 视图矩阵
  123. var viewMatrix = new Matrix4();
  124. // viewMatrix.setLookAt(v1, v2, v3, v4, v5, v6, v7, v8, v9)
  125. // v1 ~ v3 视点 默认是0,0,0
  126. // v4 ~ v6 观察目标点,默认是0,0,1
  127. // v7 ~ v9 上方向,默认是0,1,0
  128. viewMatrix.setLookAt(
  129. obj.eyeX, obj.eyeY, obj.eyeZ,
  130. obj.atX, obj.atY, obj.atZ,
  131. obj.upX, obj.upY, obj.upZ,
  132. );
  133. // 模型矩阵,(平移,旋转)
  134. var modalMatrix = new Matrix4();
  135. // angle, x, y, z
  136. modalMatrix.setRotate(0, 0, 0, 1);
  137. var modalViewMatrix = viewMatrix.multiply(modalMatrix)
  138. gl.uniformMatrix4fv(u_ViewMatrix, false, modalViewMatrix.elements);
  139. gl.clear(gl.COLOR_BUFFER_BIT);
  140. gl.drawArrays(gl.TRIANGLES, 0, n);
  141. }
  142. function initVertexBuffers(gl) {
  143. var verticesColors = new Float32Array([
  144. // 前三个点是顶点坐标,后三个点是颜色坐标
  145. 0.0, 0.5, -0.4, 0.4, 1.0, 0.4, // 绿色三角形在最后面
  146. -0.5, -0.5, -0.4, 0.4, 1.0, 0.4,
  147. 0.5, -0.5, -0.4, 1.0, 0.4, 0.4,
  148. 0.5, 0.4, -0.2, 1.0, 0.4, 0.4, // 黄色三角形在中间
  149. -0.5, 0.4, -0.2, 1.0, 1.0, 0.4,
  150. 0.0, -0.6, -0.2, 1.0, 1.0, 0.4,
  151. 0.0, 0.5, 0.0, 0.4, 0.4, 1.0, // 蓝色三角形在最前面
  152. -0.5, -0.5, 0.0, 0.4, 0.4, 1.0,
  153. 0.5, -0.5, 0.0, 1.0, 0.4, 0.4,
  154. ]);
  155. var n = 9;
  156. var vertexColorbuffer = gl.createBuffer();
  157. if (!vertexColorbuffer) {
  158. console.log('Failed to create the buffer object');
  159. return -1;
  160. }
  161. gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
  162. gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
  163. var FSIZE = verticesColors.BYTES_PER_ELEMENT;
  164. var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  165. if (a_Position < 0) {
  166. console.log('Failed to get the storage location of a_Position');
  167. return -1;
  168. }
  169. gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);
  170. gl.enableVertexAttribArray(a_Position);
  171. var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
  172. if (a_Color < 0) {
  173. console.log('Failed to get the storage location of a_Color');
  174. return -1;
  175. }
  176. gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
  177. gl.enableVertexAttribArray(a_Color);
  178. gl.bindBuffer(gl.ARRAY_BUFFER, null);
  179. return n;
  180. }
  181. main();
  182. </script>
  183. </body>
  184. </html>

7.1 调整盒子的可视空间

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8" />
  5. <title>Clear canvas</title>
  6. </head>
  7. <body>
  8. <canvas id="webgl" width="400" height="400">
  9. Please use the browser supporting "canvas"
  10. </canvas>
  11. <p id="nearFar">The near and far values are displayed here.</p>
  12. <p id="nearFar">The near and far values are displayed here.</p>
  13. <script src="../lib/webgl-utils.js"></script>
  14. <script src="../lib/webgl-debug.js"></script>
  15. <script src="../lib/cuon-utils.js"></script>
  16. <script src="../lib/cuon-matrix.js"></script>
  17. <script>
  18. // OrthoView.js (c) 2012 matsuda
  19. // Vertex shader program
  20. var VSHADER_SOURCE =
  21. 'attribute vec4 a_Position;\n' +
  22. 'attribute vec4 a_Color;\n' +
  23. 'uniform mat4 u_ProjMatrix;\n' +
  24. 'varying vec4 v_Color;\n' +
  25. 'void main() {\n' +
  26. ' gl_Position = u_ProjMatrix * a_Position;\n' +
  27. ' v_Color = a_Color;\n' +
  28. '}\n';
  29. // Fragment shader program
  30. var FSHADER_SOURCE =
  31. '#ifdef GL_ES\n' +
  32. 'precision mediump float;\n' +
  33. '#endif\n' +
  34. 'varying vec4 v_Color;\n' +
  35. 'void main() {\n' +
  36. ' gl_FragColor = v_Color;\n' +
  37. '}\n';
  38. function main() {
  39. // Retrieve <canvas> element
  40. var canvas = document.getElementById('webgl');
  41. // Retrieve the nearFar element
  42. var nf = document.getElementById('nearFar');
  43. // Get the rendering context for WebGL
  44. var gl = getWebGLContext(canvas);
  45. if (!gl) {
  46. console.log('Failed to get the rendering context for WebGL');
  47. return;
  48. }
  49. // Initialize shaders
  50. if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
  51. console.log('Failed to intialize shaders.');
  52. return;
  53. }
  54. // Set the vertex coordinates and color (the blue triangle is in the front)
  55. var n = initVertexBuffers(gl);
  56. if (n < 0) {
  57. console.log('Failed to set the vertex information');
  58. return;
  59. }
  60. // Specify the color for clearing <canvas>
  61. gl.clearColor(0, 0, 0, 1);
  62. // get the storage location of u_ProjMatrix
  63. var u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
  64. if (!u_ProjMatrix) {
  65. console.log('Failed to get the storage location of u_ProjMatrix');
  66. return;
  67. }
  68. // Create the matrix to set the eye point, and the line of sight
  69. var projMatrix = new Matrix4();
  70. // Register the event handler to be called on key press
  71. document.onkeydown = function(ev){ keydown(ev, gl, n, u_ProjMatrix, projMatrix, nf); };
  72. draw(gl, n, u_ProjMatrix, projMatrix, nf); // Draw the triangles
  73. }
  74. function initVertexBuffers(gl) {
  75. var verticesColors = new Float32Array([
  76. // Vertex coordinates and color
  77. 0.0, 0.6, -0.4, 0.4, 1.0, 0.4, // The back green one
  78. -0.5, -0.4, -0.4, 0.4, 1.0, 0.4,
  79. 0.5, -0.4, -0.4, 1.0, 0.4, 0.4,
  80. 0.5, 0.4, -0.2, 1.0, 0.4, 0.4, // The middle yellow one
  81. -0.5, 0.4, -0.2, 1.0, 1.0, 0.4,
  82. 0.0, -0.6, -0.2, 1.0, 1.0, 0.4,
  83. 0.0, 0.5, 0.0, 0.4, 0.4, 1.0, // The front blue one
  84. -0.5, -0.5, 0.0, 0.4, 0.4, 1.0,
  85. 0.5, -0.5, 0.0, 1.0, 0.4, 0.4,
  86. ]);
  87. var n = 9;
  88. // Create a buffer object
  89. var vertexColorbuffer = gl.createBuffer();
  90. if (!vertexColorbuffer) {
  91. console.log('Failed to create the buffer object');
  92. return -1;
  93. }
  94. // Write the vertex coordinates and color to the buffer object
  95. gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
  96. gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
  97. var FSIZE = verticesColors.BYTES_PER_ELEMENT;
  98. // Assign the buffer object to a_Position and enable the assignment
  99. var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  100. if(a_Position < 0) {
  101. console.log('Failed to get the storage location of a_Position');
  102. return -1;
  103. }
  104. gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);
  105. gl.enableVertexAttribArray(a_Position);
  106. // Assign the buffer object to a_Color and enable the assignment
  107. var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
  108. if(a_Color < 0) {
  109. console.log('Failed to get the storage location of a_Color');
  110. return -1;
  111. }
  112. gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
  113. gl.enableVertexAttribArray(a_Color);
  114. return n;
  115. }
  116. // The distances to the near and far clipping plane
  117. var g_near = 0.0, g_far = 0.5;
  118. function keydown(ev, gl, n, u_ProjMatrix, projMatrix, nf) {
  119. switch(ev.keyCode){
  120. case 39: g_near += 0.01; break; // The right arrow key was pressed
  121. case 37: g_near -= 0.01; break; // The left arrow key was pressed
  122. case 38: g_far += 0.01; break; // The up arrow key was pressed
  123. case 40: g_far -= 0.01; break; // The down arrow key was pressed
  124. default: return; // Prevent the unnecessary drawing
  125. }
  126. draw(gl, n, u_ProjMatrix, projMatrix, nf);
  127. }
  128. function draw(gl, n, u_ProjMatrix, projMatrix, nf) {
  129. // projMatrix.setOrtho(left, right, bottom, top, near, far) 调整可视空间
  130. // projMatrix.setOrtho(-1.0, 1.0, -1.0, 1.0, g_near, g_far); // 将视点置于原点处
  131. projMatrix.setOrtho(-1.0, 1.0, -1.0, 1.0, g_near, g_far);
  132. // Pass the projection matrix to u_ProjMatrix
  133. gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
  134. gl.clear(gl.COLOR_BUFFER_BIT); // Clear <canvas>
  135. // Display the current near and far values
  136. nf.innerHTML = 'near: ' + Math.round(g_near * 100)/100 + ', far: ' + Math.round(g_far*100)/100;
  137. gl.drawArrays(gl.TRIANGLES, 0, n); // Draw the triangles
  138. }
  139. main();
  140. </script>
  141. </body>
  142. </html>

7.2 通过可视空间修复缺掉的角

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8" />
  5. <title>Clear canvas</title>
  6. </head>
  7. <body>
  8. <canvas id="webgl" width="400" height="400">
  9. Please use the browser supporting "canvas"
  10. </canvas>
  11. <div>
  12. <button onclick="change('add', 'eyeX')">eyeX+</button>
  13. <button onclick="change('remove', 'eyeX')">eyeX-</button>
  14. <br />
  15. <button onclick="change('add', 'eyeY')">eyeY+</button>
  16. <button onclick="change('remove', 'eyeY')">eyeY-</button>
  17. <br />
  18. <button onclick="change('add', 'eyeZ')">eyeZ+</button>
  19. <button onclick="change('remove', 'eyeZ')">eyeZ-</button>
  20. <br />
  21. <button onclick="change('add', 'atX')">atX+</button>
  22. <button onclick="change('remove', 'atX')">atX-</button>
  23. <br />
  24. <button onclick="change('add', 'atY')">atY+</button>
  25. <button onclick="change('remove', 'atY')">atY-</button>
  26. <br />
  27. <button onclick="change('add', 'atZ')">atZ+</button>
  28. <button onclick="change('remove', 'atZ')">atZ-</button>
  29. <br />
  30. <button onclick="change('add', 'upX')">upX+</button>
  31. <button onclick="change('remove', 'upX')">upX-</button>
  32. <br />
  33. <button onclick="change('add', 'upY')">upY+</button>
  34. <button onclick="change('remove', 'upY')">upY-</button>
  35. <br />
  36. <button onclick="change('add', 'upZ')">upZ+</button>
  37. <button onclick="change('remove', 'upZ')">upZ-</button>
  38. <br />
  39. <div>
  40. <div id="content"></div>
  41. </div>
  42. </div>
  43. <script src="../lib/webgl-utils.js"></script>
  44. <script src="../lib/webgl-debug.js"></script>
  45. <script src="../lib/cuon-utils.js"></script>
  46. <script src="../lib/cuon-matrix.js"></script>
  47. <script>
  48. const obj = {
  49. eyeX: 0.25,
  50. eyeY: 0.25,
  51. eyeZ: 0.25,
  52. atX: 0,
  53. atY: 0,
  54. atZ: 0,
  55. upX: 0,
  56. upY: 1,
  57. upZ: 0
  58. }
  59. function innerHtml() {
  60. document.getElementById("content").innerHTML = JSON.stringify(obj)
  61. }
  62. function change(type, name) {
  63. if (type === 'add') {
  64. obj[name] += 0.01;
  65. } else {
  66. obj[name] -= 0.01;
  67. }
  68. if (obj[name] > 1) {
  69. obj[name] = 0;
  70. } else if (obj[name] < 0) {
  71. obj[name] = 1
  72. }
  73. main()
  74. innerHtml()
  75. }
  76. // Vertex shader program
  77. var VSHADER_SOURCE =
  78. 'attribute vec4 a_Position;\n' +
  79. 'attribute vec4 a_Color;\n' +
  80. 'uniform mat4 u_ViewMatrix;\n' + // 视图矩阵
  81. 'uniform mat4 u_ProjMatrix;\n'+
  82. 'varying vec4 v_Color;\n' +
  83. 'void main() {\n' +
  84. ' gl_Position = u_ProjMatrix * u_ViewMatrix * a_Position;\n' + // 视图矩阵 * 原始顶点坐标
  85. ' v_Color = a_Color;\n' +
  86. '}\n';
  87. // Fragment shader program
  88. var FSHADER_SOURCE =
  89. '#ifdef GL_ES\n' +
  90. 'precision mediump float;\n' +
  91. '#endif\n' +
  92. 'varying vec4 v_Color;\n' +
  93. 'void main() {\n' +
  94. ' gl_FragColor = v_Color;\n' +
  95. '}\n';
  96. function main() {
  97. // Retrieve <canvas> element
  98. var canvas = document.getElementById('webgl');
  99. // Get the rendering context for WebGL
  100. var gl = getWebGLContext(canvas);
  101. if (!gl) {
  102. console.log('Failed to get the rendering context for WebGL');
  103. return;
  104. }
  105. // Initialize shaders
  106. if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
  107. console.log('Failed to intialize shaders.');
  108. return;
  109. }
  110. // Set the vertex coordinates and color (the blue triangle is in the front)
  111. var n = initVertexBuffers(gl);
  112. if (n < 0) {
  113. console.log('Failed to set the vertex information');
  114. return;
  115. }
  116. gl.clearColor(0, 0, 0, 1);
  117. // 获取视图矩阵变量
  118. var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
  119. // 获取投影矩阵变量
  120. var u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
  121. if (!u_ViewMatrix) {
  122. console.log('Failed to get the storage locations of u_ViewMatrix');
  123. return;
  124. }
  125. // 视图矩阵
  126. var viewMatrix = new Matrix4();
  127. // viewMatrix.setLookAt(v1, v2, v3, v4, v5, v6, v7, v8, v9)
  128. // v1 ~ v3 视点 默认是0,0,0
  129. // v4 ~ v6 观察目标点,默认是0,0,1
  130. // v7 ~ v9 上方向,默认是0,1,0
  131. viewMatrix.setLookAt(
  132. obj.eyeX, obj.eyeY, obj.eyeZ,
  133. obj.atX, obj.atY, obj.atZ,
  134. obj.upX, obj.upY, obj.upZ,
  135. );
  136. // 模型矩阵,(平移,旋转)
  137. var modalMatrix = new Matrix4();
  138. // angle, x, y, z
  139. modalMatrix.setRotate(0, 0, 0, 1);
  140. var modalViewMatrix = viewMatrix.multiply(modalMatrix)
  141. gl.uniformMatrix4fv(u_ViewMatrix, false, modalViewMatrix.elements);
  142. var projMatrix = new Matrix4();
  143. // 设置可视空间,定义正射投影矩阵
  144. // projMatrix.setOrtho(left, right, top, bottom, near, far);
  145. // near,far 指定近裁剪面和远裁剪面的位置,即可视空间的近边界和远边界
  146. projMatrix.setOrtho(-1.0, 1.0, -1.0, 1.0, 0.0, 2.0);
  147. gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
  148. gl.clear(gl.COLOR_BUFFER_BIT);
  149. gl.drawArrays(gl.TRIANGLES, 0, n);
  150. }
  151. function initVertexBuffers(gl) {
  152. var verticesColors = new Float32Array([
  153. // 前三个点是顶点坐标,后三个点是颜色坐标
  154. 0.0, 0.5, -0.4, 0.4, 1.0, 0.4, // 绿色三角形在最后面
  155. -0.5, -0.5, -0.4, 0.4, 1.0, 0.4,
  156. 0.5, -0.5, -0.4, 1.0, 0.4, 0.4,
  157. 0.5, 0.4, -0.2, 1.0, 0.4, 0.4, // 黄色三角形在中间
  158. -0.5, 0.4, -0.2, 1.0, 1.0, 0.4,
  159. 0.0, -0.6, -0.2, 1.0, 1.0, 0.4,
  160. 0.0, 0.5, 0.0, 0.4, 0.4, 1.0, // 蓝色三角形在最前面
  161. -0.5, -0.5, 0.0, 0.4, 0.4, 1.0,
  162. 0.5, -0.5, 0.0, 1.0, 0.4, 0.4,
  163. ]);
  164. var n = 9;
  165. var vertexColorbuffer = gl.createBuffer();
  166. if (!vertexColorbuffer) {
  167. console.log('Failed to create the buffer object');
  168. return -1;
  169. }
  170. gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
  171. gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
  172. var FSIZE = verticesColors.BYTES_PER_ELEMENT;
  173. var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  174. if (a_Position < 0) {
  175. console.log('Failed to get the storage location of a_Position');
  176. return -1;
  177. }
  178. gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);
  179. gl.enableVertexAttribArray(a_Position);
  180. var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
  181. if (a_Color < 0) {
  182. console.log('Failed to get the storage location of a_Color');
  183. return -1;
  184. }
  185. gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
  186. gl.enableVertexAttribArray(a_Color);
  187. gl.bindBuffer(gl.ARRAY_BUFFER, null);
  188. return n;
  189. }
  190. main();
  191. </script>
  192. </body>
  193. </html>

7.3透视投影矩阵

  1. // PerspectiveView.js (c) 2012 matsuda
  2. // Vertex shader program
  3. var VSHADER_SOURCE =
  4. 'attribute vec4 a_Position;\n' +
  5. 'attribute vec4 a_Color;\n' +
  6. 'uniform mat4 u_ViewMatrix;\n' +
  7. 'uniform mat4 u_ProjMatrix;\n' +
  8. 'varying vec4 v_Color;\n' +
  9. 'void main() {\n' +
  10. ' gl_Position = u_ProjMatrix * u_ViewMatrix * a_Position;\n' +
  11. ' v_Color = a_Color;\n' +
  12. '}\n';
  13. // Fragment shader program
  14. var FSHADER_SOURCE =
  15. '#ifdef GL_ES\n' +
  16. 'precision mediump float;\n' +
  17. '#endif\n' +
  18. 'varying vec4 v_Color;\n' +
  19. 'void main() {\n' +
  20. ' gl_FragColor = v_Color;\n' +
  21. '}\n';
  22. function main() {
  23. // Retrieve <canvas> element
  24. var canvas = document.getElementById('webgl');
  25. // Get the rendering context for WebGL
  26. var gl = getWebGLContext(canvas);
  27. if (!gl) {
  28. console.log('Failed to get the rendering context for WebGL');
  29. return;
  30. }
  31. // Initialize shaders
  32. if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
  33. console.log('Failed to intialize shaders.');
  34. return;
  35. }
  36. // Set the vertex coordinates and color (the blue triangle is in the front)
  37. var n = initVertexBuffers(gl);
  38. if (n < 0) {
  39. console.log('Failed to set the vertex information');
  40. return;
  41. }
  42. // Specify the color for clearing <canvas>
  43. gl.clearColor(0, 0, 0, 1);
  44. var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
  45. var u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
  46. if (!u_ViewMatrix || !u_ProjMatrix) {
  47. console.log('Failed to get the storage location of u_ViewMatrix and/or u_ProjMatrix');
  48. return;
  49. }
  50. var viewMatrix = new Matrix4(); // 视图矩阵
  51. var projMatrix = new Matrix4(); // 投影矩阵,这里是透视投影矩阵
  52. // 旋转,平移,缩放,的矩阵被称为模型矩阵
  53. // 视点(0,0,0),观察点(0,0,-1),上方向(如果上方向是y轴的正方向,那么upX,upY,upZ就是0,1,0) 组成 视图矩阵
  54. // 在平面直角坐标系中, y轴正方向 是指 从原点沿纵轴向上的方向.”
  55. // 模型视图矩阵 = 视图矩阵 * 模型矩阵
  56. // 模型视图矩阵 * 顶点坐标
  57. // 投影矩阵 * 模型视图矩阵 * 顶点坐标
  58. // 投影矩阵 * 视图矩阵 * 模型矩阵 * 顶点坐标
  59. // 定义 eyeX,eyeY,eyeZ,atX,atY,atX,upX,upY,upZ
  60. viewMatrix.setLookAt(0, 0, 5, 0, 0, -100, 0, 1, 0);
  61. // 设置可视空间,定义透视投影矩阵
  62. // projMatrix.setPerspective(fov, aspect, near, far)
  63. // fov:指定垂直视角,即可视空间顶面和地面间的夹角,必须大于0
  64. // aspect:指定近裁剪面的宽高比
  65. // near:近裁剪面的位置,必须大于0
  66. // far:远裁剪面的位置,必须大于0
  67. projMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
  68. gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements);
  69. gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
  70. // Clear <canvas>
  71. gl.clear(gl.COLOR_BUFFER_BIT);
  72. // Draw the triangles
  73. gl.drawArrays(gl.TRIANGLES, 0, n);
  74. }
  75. function initVertexBuffers(gl) {
  76. // 三角形的位置x,y完全相同
  77. // 渲染出的三角形距离远的看上去变小了,其次,三角形被不同程度地平移以贴近中心线(即视线),
  78. // 使他们看上去在视线的左右排出了两列
  79. var verticesColors = new Float32Array([
  80. // 右侧三个三角形
  81. 0.75, 1.0, -4.0, 0.4, 1.0, 0.4, // 绿色
  82. 0.25, -1.0, -4.0, 0.4, 1.0, 0.4,
  83. 1.25, -1.0, -4.0, 1.0, 0.4, 0.4,
  84. 0.75, 1.0, -2.0, 1.0, 1.0, 0.4, //黄色
  85. 0.25, -1.0, -2.0, 1.0, 1.0, 0.4,
  86. 1.25, -1.0, -2.0, 1.0, 0.4, 0.4,
  87. 0.75, 1.0, 0.0, 0.4, 0.4, 1.0, // 蓝色
  88. 0.25, -1.0, 0.0, 0.4, 0.4, 1.0,
  89. 1.25, -1.0, 0.0, 1.0, 0.4, 0.4,
  90. // 左侧三个三角形
  91. -0.75, 1.0, -4.0, 0.4, 1.0, 0.4, // 绿色
  92. -1.25, -1.0, -4.0, 0.4, 1.0, 0.4,
  93. -0.25, -1.0, -4.0, 1.0, 0.4, 0.4,
  94. -0.75, 1.0, -2.0, 1.0, 1.0, 0.4, // 黄色
  95. -1.25, -1.0, -2.0, 1.0, 1.0, 0.4,
  96. -0.25, -1.0, -2.0, 1.0, 0.4, 0.4,
  97. -0.75, 1.0, 0.0, 0.4, 0.4, 1.0, // 蓝色
  98. -1.25, -1.0, 0.0, 0.4, 0.4, 1.0,
  99. -0.25, -1.0, 0.0, 1.0, 0.4, 0.4,
  100. ]);
  101. var n = 18; // Three vertices per triangle * 6
  102. // Create a buffer object
  103. var vertexColorbuffer = gl.createBuffer();
  104. if (!vertexColorbuffer) {
  105. console.log('Failed to create the buffer object');
  106. return -1;
  107. }
  108. // Write the vertex coordinates and color to the buffer object
  109. gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
  110. gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
  111. var FSIZE = verticesColors.BYTES_PER_ELEMENT;
  112. // Assign the buffer object to a_Position and enable the assignment
  113. var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  114. if(a_Position < 0) {
  115. console.log('Failed to get the storage location of a_Position');
  116. return -1;
  117. }
  118. gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);
  119. gl.enableVertexAttribArray(a_Position);
  120. // Assign the buffer object to a_Color and enable the assignment
  121. var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
  122. if(a_Color < 0) {
  123. console.log('Failed to get the storage location of a_Color');
  124. return -1;
  125. }
  126. gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
  127. gl.enableVertexAttribArray(a_Color);
  128. return n;
  129. }

7.4 在上一个例子,绘制中间的三个三角形,通过模型矩阵,绘制两次,一次偏移0.75,一次偏移-0.75,达到和上个例子一样的效果

  1. // PerspectiveView.js (c) 2012 matsuda
  2. // Vertex shader program
  3. var VSHADER_SOURCE =
  4. 'attribute vec4 a_Position;\n' +
  5. 'attribute vec4 a_Color;\n' +
  6. 'uniform mat4 u_ViewMatrix;\n' +
  7. 'uniform mat4 u_ProjMatrix;\n' +
  8. 'uniform mat4 u_ModelMatrix;\n' +
  9. 'varying vec4 v_Color;\n' +
  10. 'void main() {\n' +
  11. // 投影矩阵 * 视图矩阵 * 模型矩阵 * 顶点位置
  12. ' gl_Position = u_ProjMatrix * u_ViewMatrix * u_ModelMatrix * a_Position;\n' +
  13. ' v_Color = a_Color;\n' +
  14. '}\n';
  15. // Fragment shader program
  16. var FSHADER_SOURCE =
  17. '#ifdef GL_ES\n' +
  18. 'precision mediump float;\n' +
  19. '#endif\n' +
  20. 'varying vec4 v_Color;\n' +
  21. 'void main() {\n' +
  22. ' gl_FragColor = v_Color;\n' +
  23. '}\n';
  24. function main() {
  25. // Retrieve <canvas> element
  26. var canvas = document.getElementById('webgl');
  27. // Get the rendering context for WebGL
  28. var gl = getWebGLContext(canvas);
  29. if (!gl) {
  30. console.log('Failed to get the rendering context for WebGL');
  31. return;
  32. }
  33. // Initialize shaders
  34. if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
  35. console.log('Failed to intialize shaders.');
  36. return;
  37. }
  38. // Set the vertex coordinates and color (the blue triangle is in the front)
  39. var n = initVertexBuffers(gl);
  40. if (n < 0) {
  41. console.log('Failed to set the vertex information');
  42. return;
  43. }
  44. // Specify the color for clearing <canvas>
  45. gl.clearColor(0, 0, 0, 1);
  46. var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
  47. var u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
  48. var u_ModelMatrix = gl.getUniformLocation(gl.program, "u_ModelMatrix")
  49. if (!u_ViewMatrix || !u_ProjMatrix || !u_ModelMatrix) {
  50. throw new TypeError("获取uniform变量失败")
  51. }
  52. var viewMatrix = new Matrix4(); // 视图矩阵
  53. var projMatrix = new Matrix4(); // 透视投影矩阵
  54. var modelMatrix = new Matrix4(); // 模型矩阵
  55. // 旋转,平移,缩放,的矩阵被称为模型矩阵
  56. // 视点(0,0,0),观察点(0,0,-1),上方向(如果上方向是y轴的正方向,那么upX,upY,upZ就是0,1,0) 组成 视图矩阵
  57. // 在平面直角坐标系中, y轴正方向 是指 从原点沿纵轴向上的方向.”
  58. // 模型视图矩阵 = 视图矩阵 * 模型矩阵
  59. // 模型视图矩阵 * 顶点坐标
  60. // 透视投影矩阵 * 模型视图矩阵 * 顶点坐标
  61. // 透视投影矩阵 * 视图矩阵 * 模型矩阵 * 顶点坐标
  62. // 模型矩阵,平移0.75
  63. modelMatrix.setTranslate(0.75, 0, 0);
  64. // 定义 eyeX,eyeY,eyeZ,atX,atY,atX,upX,upY,upZ
  65. viewMatrix.setLookAt(0, 0, 5, 0, 0, -100, 0, 1, 0);
  66. // 定义透视投影矩阵
  67. // projMatrix.setPerspective(fov, aspect, near, far)
  68. // fov:指定垂直视角,即可视空间顶面和地面间的夹角,必须大于0
  69. // aspect:指定近裁剪面的宽高比
  70. // near:近裁剪面的位置,必须大于0
  71. // far:远裁剪面的位置,必须大于0
  72. projMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
  73. gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
  74. gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements);
  75. gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
  76. // Clear <canvas>
  77. gl.clear(gl.COLOR_BUFFER_BIT);
  78. // Draw the triangles
  79. gl.drawArrays(gl.TRIANGLES, 0, n);
  80. // 设置矩阵
  81. modelMatrix.setTranslate(-0.75, 0, 0);
  82. gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
  83. gl.drawArrays(gl.TRIANGLES, 0, n);
  84. }
  85. function initVertexBuffers(gl) {
  86. // 三角形的位置x,y完全相同
  87. // 渲染出的三角形距离远的看上去变小了,其次,三角形被不同程度地平移以贴近中心线(即视线),
  88. // 使他们看上去在视线的左右排出了两列
  89. var verticesColors = new Float32Array([
  90. // Vertex coordinates and color
  91. 0.0, 1.0, -4.0, 0.4, 1.0, 0.4, // The back green one
  92. -0.5, -1.0, -4.0, 0.4, 1.0, 0.4,
  93. 0.5, -1.0, -4.0, 1.0, 0.4, 0.4,
  94. 0.0, 1.0, -2.0, 1.0, 1.0, 0.4, // The middle yellow one
  95. -0.5, -1.0, -2.0, 1.0, 1.0, 0.4,
  96. 0.5, -1.0, -2.0, 1.0, 0.4, 0.4,
  97. 0.0, 1.0, 0.0, 0.4, 0.4, 1.0, // The front blue one
  98. -0.5, -1.0, 0.0, 0.4, 0.4, 1.0,
  99. 0.5, -1.0, 0.0, 1.0, 0.4, 0.4,
  100. ]);
  101. var n = 9;
  102. var vertexColorbuffer = gl.createBuffer();
  103. if (!vertexColorbuffer) {
  104. console.log('Failed to create the buffer object');
  105. return -1;
  106. }
  107. // Write the vertex coordinates and color to the buffer object
  108. gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
  109. gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
  110. var FSIZE = verticesColors.BYTES_PER_ELEMENT;
  111. // Assign the buffer object to a_Position and enable the assignment
  112. var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  113. if(a_Position < 0) {
  114. console.log('Failed to get the storage location of a_Position');
  115. return -1;
  116. }
  117. gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);
  118. gl.enableVertexAttribArray(a_Position);
  119. // Assign the buffer object to a_Color and enable the assignment
  120. var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
  121. if(a_Color < 0) {
  122. console.log('Failed to get the storage location of a_Color');
  123. return -1;
  124. }
  125. gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
  126. gl.enableVertexAttribArray(a_Color);
  127. return n;
  128. }

7.5 在7.4的例子上,合并了 投影矩阵,视图矩阵,模型矩阵

  1. // PerspectiveView.js (c) 2012 matsuda
  2. // Vertex shader program
  3. var VSHADER_SOURCE =
  4. 'attribute vec4 a_Position;\n' +
  5. 'attribute vec4 a_Color;\n' +
  6. // 'uniform mat4 u_ViewMatrix;\n' +
  7. // 'uniform mat4 u_ProjMatrix;\n' +
  8. // 'uniform mat4 u_ModelMatrix;\n' +
  9. 'uniform mat4 u_MvpMatrix;\n' +
  10. 'varying vec4 v_Color;\n' +
  11. 'void main() {\n' +
  12. // 投影矩阵 * 视图矩阵 * 模型矩阵 * 顶点位置
  13. // ' gl_Position = u_ProjMatrix * u_ViewMatrix * u_ModelMatrix * a_Position;\n' +
  14. // 合并 投影矩阵 * 视图矩阵 * 模型矩阵 这三个矩阵
  15. ' gl_Position = u_MvpMatrix * a_Position;\n' +
  16. ' v_Color = a_Color;\n' +
  17. '}\n';
  18. // Fragment shader program
  19. var FSHADER_SOURCE =
  20. '#ifdef GL_ES\n' +
  21. 'precision mediump float;\n' +
  22. '#endif\n' +
  23. 'varying vec4 v_Color;\n' +
  24. 'void main() {\n' +
  25. ' gl_FragColor = v_Color;\n' +
  26. '}\n';
  27. function main() {
  28. // Retrieve <canvas> element
  29. var canvas = document.getElementById('webgl');
  30. // Get the rendering context for WebGL
  31. var gl = getWebGLContext(canvas);
  32. if (!gl) {
  33. console.log('Failed to get the rendering context for WebGL');
  34. return;
  35. }
  36. // Initialize shaders
  37. if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
  38. throw new TypeError("着色器初始化失败")
  39. return;
  40. }
  41. // Set the vertex coordinates and color (the blue triangle is in the front)
  42. var n = initVertexBuffers(gl);
  43. if (n < 0) {
  44. console.log('Failed to set the vertex information');
  45. return;
  46. }
  47. // Specify the color for clearing <canvas>
  48. gl.clearColor(0, 0, 0, 1);
  49. // var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
  50. // var u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
  51. // var u_ModelMatrix = gl.getUniformLocation(gl.program, "u_ModelMatrix")
  52. var u_MvpMatrix = gl.getUniformLocation(gl.program, "u_MvpMatrix")
  53. if (!u_MvpMatrix) {
  54. throw new TypeError("获取uniform变量失败")
  55. }
  56. var viewMatrix = new Matrix4(); // 视图矩阵
  57. var projMatrix = new Matrix4(); // 透视投影矩阵
  58. var modelMatrix = new Matrix4(); // 模型矩阵
  59. var mvpMatrix = new Matrix4();
  60. // 旋转,平移,缩放,的矩阵被称为模型矩阵
  61. // 视点(0,0,0),观察点(0,0,-1),上方向(如果上方向是y轴的正方向,那么upX,upY,upZ就是0,1,0) 组成 视图矩阵
  62. // 在平面直角坐标系中, y轴正方向 是指 从原点沿纵轴向上的方向.”
  63. // 模型视图矩阵 = 视图矩阵 * 模型矩阵
  64. // 模型视图矩阵 * 顶点坐标
  65. // 透视投影矩阵 * 模型视图矩阵 * 顶点坐标
  66. // 透视投影矩阵 * 视图矩阵 * 模型矩阵 * 顶点坐标
  67. // 模型矩阵,平移0.75
  68. modelMatrix.setTranslate(0.75, 0, 0);
  69. // 定义 eyeX,eyeY,eyeZ,atX,atY,atX,upX,upY,upZ
  70. viewMatrix.setLookAt(0, 0, 5, 0, 0, -100, 0, 1, 0);
  71. // 定义透视投影矩阵
  72. // projMatrix.setPerspective(fov, aspect, near, far)
  73. // fov:指定垂直视角,即可视空间顶面和地面间的夹角,必须大于0
  74. // aspect:指定近裁剪面的宽高比
  75. // near:近裁剪面的位置,必须大于0
  76. // far:远裁剪面的位置,必须大于0
  77. projMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
  78. mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix)
  79. gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
  80. // gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
  81. // gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements);
  82. // gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
  83. // Clear <canvas>
  84. gl.clear(gl.COLOR_BUFFER_BIT);
  85. // Draw the triangles
  86. gl.drawArrays(gl.TRIANGLES, 0, n);
  87. // 设置矩阵
  88. modelMatrix.setTranslate(-0.75, 0, 0);
  89. mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix)
  90. gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
  91. gl.drawArrays(gl.TRIANGLES, 0, n);
  92. }
  93. function initVertexBuffers(gl) {
  94. // 三角形的位置x,y完全相同
  95. // 渲染出的三角形距离远的看上去变小了,其次,三角形被不同程度地平移以贴近中心线(即视线),
  96. // 使他们看上去在视线的左右排出了两列
  97. var verticesColors = new Float32Array([
  98. // Vertex coordinates and color
  99. 0.0, 1.0, -4.0, 0.4, 1.0, 0.4, // The back green one
  100. -0.5, -1.0, -4.0, 0.4, 1.0, 0.4,
  101. 0.5, -1.0, -4.0, 1.0, 0.4, 0.4,
  102. 0.0, 1.0, -2.0, 1.0, 1.0, 0.4, // The middle yellow one
  103. -0.5, -1.0, -2.0, 1.0, 1.0, 0.4,
  104. 0.5, -1.0, -2.0, 1.0, 0.4, 0.4,
  105. 0.0, 1.0, 0.0, 0.4, 0.4, 1.0, // The front blue one
  106. -0.5, -1.0, 0.0, 0.4, 0.4, 1.0,
  107. 0.5, -1.0, 0.0, 1.0, 0.4, 0.4,
  108. ]);
  109. var n = 9;
  110. var vertexColorbuffer = gl.createBuffer();
  111. if (!vertexColorbuffer) {
  112. console.log('Failed to create the buffer object');
  113. return -1;
  114. }
  115. // Write the vertex coordinates and color to the buffer object
  116. gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
  117. gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
  118. var FSIZE = verticesColors.BYTES_PER_ELEMENT;
  119. // Assign the buffer object to a_Position and enable the assignment
  120. var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  121. if(a_Position < 0) {
  122. console.log('Failed to get the storage location of a_Position');
  123. return -1;
  124. }
  125. gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);
  126. gl.enableVertexAttribArray(a_Position);
  127. // Assign the buffer object to a_Color and enable the assignment
  128. var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
  129. if(a_Color < 0) {
  130. console.log('Failed to get the storage location of a_Color');
  131. return -1;
  132. }
  133. gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
  134. gl.enableVertexAttribArray(a_Color);
  135. return n;
  136. }

7.6 隐藏面清除功能开启

原来的例子是先画远的,在画近处的内容,这样有一个问题,后面画的内容会出现在画布中,他应该被挡住才是的,开启隐藏面清除功能,可以解决此问题
// 开启隐藏面消除功能
gl.enable(gl.DEPTH_TEST);
// 清除默认颜色和深度缓冲区
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

  1. // PerspectiveView.js (c) 2012 matsuda
  2. // Vertex shader program
  3. var VSHADER_SOURCE =
  4. 'attribute vec4 a_Position;\n' +
  5. 'attribute vec4 a_Color;\n' +
  6. // 'uniform mat4 u_ViewMatrix;\n' +
  7. // 'uniform mat4 u_ProjMatrix;\n' +
  8. // 'uniform mat4 u_ModelMatrix;\n' +
  9. 'uniform mat4 u_MvpMatrix;\n' +
  10. 'varying vec4 v_Color;\n' +
  11. 'void main() {\n' +
  12. // 投影矩阵 * 视图矩阵 * 模型矩阵 * 顶点位置
  13. // ' gl_Position = u_ProjMatrix * u_ViewMatrix * u_ModelMatrix * a_Position;\n' +
  14. // 合并 投影矩阵 * 视图矩阵 * 模型矩阵 这三个矩阵
  15. ' gl_Position = u_MvpMatrix * a_Position;\n' +
  16. ' v_Color = a_Color;\n' +
  17. '}\n';
  18. // Fragment shader program
  19. var FSHADER_SOURCE =
  20. '#ifdef GL_ES\n' +
  21. 'precision mediump float;\n' +
  22. '#endif\n' +
  23. 'varying vec4 v_Color;\n' +
  24. 'void main() {\n' +
  25. ' gl_FragColor = v_Color;\n' +
  26. '}\n';
  27. function main() {
  28. // Retrieve <canvas> element
  29. var canvas = document.getElementById('webgl');
  30. // Get the rendering context for WebGL
  31. var gl = getWebGLContext(canvas);
  32. if (!gl) {
  33. console.log('Failed to get the rendering context for WebGL');
  34. return;
  35. }
  36. // Initialize shaders
  37. if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
  38. throw new TypeError("着色器初始化失败")
  39. return;
  40. }
  41. // Set the vertex coordinates and color (the blue triangle is in the front)
  42. var n = initVertexBuffers(gl);
  43. if (n < 0) {
  44. console.log('Failed to set the vertex information');
  45. return;
  46. }
  47. // Specify the color for clearing <canvas>
  48. gl.clearColor(0, 0, 0, 1);
  49. // var u_ViewMatrix = gl.getUniformLocation(gl.program, 'u_ViewMatrix');
  50. // var u_ProjMatrix = gl.getUniformLocation(gl.program, 'u_ProjMatrix');
  51. // var u_ModelMatrix = gl.getUniformLocation(gl.program, "u_ModelMatrix")
  52. var u_MvpMatrix = gl.getUniformLocation(gl.program, "u_MvpMatrix")
  53. if (!u_MvpMatrix) {
  54. throw new TypeError("获取uniform变量失败")
  55. }
  56. var viewMatrix = new Matrix4(); // 视图矩阵
  57. var projMatrix = new Matrix4(); // 透视投影矩阵
  58. var modelMatrix = new Matrix4(); // 模型矩阵
  59. var mvpMatrix = new Matrix4();
  60. // 旋转,平移,缩放,的矩阵被称为模型矩阵
  61. // 视点(0,0,0),观察点(0,0,-1),上方向(如果上方向是y轴的正方向,那么upX,upY,upZ就是0,1,0) 组成 视图矩阵
  62. // 在平面直角坐标系中, y轴正方向 是指 从原点沿纵轴向上的方向.”
  63. // 模型视图矩阵 = 视图矩阵 * 模型矩阵
  64. // 模型视图矩阵 * 顶点坐标
  65. // 透视投影矩阵 * 模型视图矩阵 * 顶点坐标
  66. // 透视投影矩阵 * 视图矩阵 * 模型矩阵 * 顶点坐标
  67. // 模型矩阵,平移0.75
  68. modelMatrix.setTranslate(0.75, 0, 0);
  69. // 定义 eyeX,eyeY,eyeZ,atX,atY,atX,upX,upY,upZ
  70. viewMatrix.setLookAt(0, 0, 5, 0, 0, -100, 0, 1, 0);
  71. // 定义透视投影矩阵
  72. // projMatrix.setPerspective(fov, aspect, near, far)
  73. // fov:指定垂直视角,即可视空间顶面和地面间的夹角,必须大于0
  74. // aspect:指定近裁剪面的宽高比
  75. // near:近裁剪面的位置,必须大于0
  76. // far:远裁剪面的位置,必须大于0
  77. projMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
  78. mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix)
  79. gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
  80. // gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
  81. // gl.uniformMatrix4fv(u_ViewMatrix, false, viewMatrix.elements);
  82. // gl.uniformMatrix4fv(u_ProjMatrix, false, projMatrix.elements);
  83. // 开启隐藏面消除功能
  84. gl.enable(gl.DEPTH_TEST);
  85. // 清除默认颜色和深度缓冲区
  86. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  87. // Draw the triangles
  88. gl.drawArrays(gl.TRIANGLES, 0, n);
  89. // 设置矩阵
  90. modelMatrix.setTranslate(-0.75, 0, 0);
  91. mvpMatrix.set(projMatrix).multiply(viewMatrix).multiply(modelMatrix)
  92. gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
  93. gl.drawArrays(gl.TRIANGLES, 0, n);
  94. }
  95. function initVertexBuffers(gl) {
  96. // 三角形的位置x,y完全相同
  97. // 渲染出的三角形距离远的看上去变小了,其次,三角形被不同程度地平移以贴近中心线(即视线),
  98. // 使他们看上去在视线的左右排出了两列
  99. var verticesColors = new Float32Array([
  100. // Vertex coordinates and color
  101. 0.0, 1.0, 0.0, 0.4, 1.0, 0.4, // 绿色,在最前面
  102. -0.5, -1.0, 0.0, 0.4, 1.0, 0.4,
  103. 0.5, -1.0, 0.0, 1.0, 0.4, 0.4,
  104. 0.0, 1.0, -2.0, 1.0, 1.0, 0.4, // 黄色,在中间
  105. -0.5, -1.0, -2.0, 1.0, 1.0, 0.4,
  106. 0.5, -1.0, -2.0, 1.0, 0.4, 0.4,
  107. 0.0, 1.0, -4.0, 0.4, 0.4, 1.0, // 蓝色,在最后面
  108. -0.5, -1.0, -4.0, 0.4, 0.4, 1.0,
  109. 0.5, -1.0, -4.0, 1.0, 0.4, 0.4,
  110. ]);
  111. var n = 9;
  112. var vertexColorbuffer = gl.createBuffer();
  113. if (!vertexColorbuffer) {
  114. console.log('Failed to create the buffer object');
  115. return -1;
  116. }
  117. // Write the vertex coordinates and color to the buffer object
  118. gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
  119. gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
  120. var FSIZE = verticesColors.BYTES_PER_ELEMENT;
  121. // Assign the buffer object to a_Position and enable the assignment
  122. var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  123. if(a_Position < 0) {
  124. console.log('Failed to get the storage location of a_Position');
  125. return -1;
  126. }
  127. gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);
  128. gl.enableVertexAttribArray(a_Position);
  129. // Assign the buffer object to a_Color and enable the assignment
  130. var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
  131. if(a_Color < 0) {
  132. console.log('Failed to get the storage location of a_Color');
  133. return -1;
  134. }
  135. gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
  136. gl.enableVertexAttribArray(a_Color);
  137. return n;
  138. }

7.7 z值相同,会产生深度冲突,解决深度冲突

  1. // Zfighting.js (c) 2012 matsuda
  2. // Vertex shader program
  3. var VSHADER_SOURCE =
  4. 'attribute vec4 a_Position;\n' +
  5. 'attribute vec4 a_Color;\n' +
  6. 'uniform mat4 u_ViewProjMatrix;\n' +
  7. 'varying vec4 v_Color;\n' +
  8. 'void main() {\n' +
  9. ' gl_Position = u_ViewProjMatrix * a_Position;\n' +
  10. ' v_Color = a_Color;\n' +
  11. '}\n';
  12. // Fragment shader program
  13. var FSHADER_SOURCE =
  14. '#ifdef GL_ES\n' +
  15. 'precision mediump float;\n' +
  16. '#endif\n' +
  17. 'varying vec4 v_Color;\n' +
  18. 'void main() {\n' +
  19. ' gl_FragColor = v_Color;\n' +
  20. '}\n';
  21. function main() {
  22. // Retrieve <canvas> element
  23. var canvas = document.getElementById('webgl');
  24. // Get the rendering context for WebGL
  25. var gl = getWebGLContext(canvas);
  26. if (!gl) {
  27. console.log('Failed to get the rendering context for WebGL');
  28. return;
  29. }
  30. // Initialize shaders
  31. if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
  32. console.log('Failed to intialize shaders.');
  33. return;
  34. }
  35. // Set the vertex coordinates and color (the blue triangle is in the front)
  36. var n = initVertexBuffers(gl);
  37. if (n < 0) {
  38. console.log('Failed to set the vertex information');
  39. return;
  40. }
  41. //Set clear color and enable the hidden surface removal function
  42. gl.clearColor(0, 0, 0, 1);
  43. gl.enable(gl.DEPTH_TEST);
  44. // Get the storage locations of u_ViewProjMatrix
  45. var u_ViewProjMatrix = gl.getUniformLocation(gl.program, 'u_ViewProjMatrix');
  46. if (!u_ViewProjMatrix) {
  47. console.log('Failed to get the storage locations of u_ViewProjMatrix');
  48. return;
  49. }
  50. var viewProjMatrix = new Matrix4();
  51. // Set the eye point, look-at point, and up vector.
  52. viewProjMatrix.setPerspective(30, canvas.width/canvas.height, 1, 100);
  53. viewProjMatrix.lookAt(3.06, 2.5, 10.0, 0, 0, -2, 0, 1, 0);
  54. // Pass the view projection matrix to u_ViewProjMatrix
  55. gl.uniformMatrix4fv(u_ViewProjMatrix, false, viewProjMatrix.elements);
  56. // Clear color and depth buffer
  57. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  58. // 启用多边形偏移,这个会自动偏移z值,给每个多边形自动加上一个偏移值
  59. gl.enable(gl.POLYGON_OFFSET_FILL);
  60. gl.drawArrays(gl.TRIANGLES, 0, n/2); // The green triangle
  61. // gl.polygonOffset(factor, units);
  62. // m * factor + r * units
  63. // m 表示顶点所在表面相对于观察者的视线的角度
  64. // r 表示 硬件能够区分两个z值之差的最小值
  65. gl.polygonOffset(1.0, 1.0); // 指定加到每个顶点绘制后z值上的偏移量
  66. gl.drawArrays(gl.TRIANGLES, n/2, n/2); // The yellow triangle
  67. }
  68. function initVertexBuffers(gl) {
  69. var verticesColors = new Float32Array([
  70. // Vertex coordinates and color
  71. 0.0, 2.5, -5.0, 0.4, 1.0, 0.4, // The green triangle
  72. -2.5, -2.5, -5.0, 0.4, 1.0, 0.4,
  73. 2.5, -2.5, -5.0, 1.0, 0.4, 0.4,
  74. 0.0, 3.0, -5.0, 1.0, 0.4, 0.4, // The yellow triagle
  75. -3.0, -3.0, -5.0, 1.0, 1.0, 0.4,
  76. 3.0, -3.0, -5.0, 1.0, 1.0, 0.4,
  77. ]);
  78. var n = 6;
  79. // Create a buffer object
  80. var vertexColorbuffer = gl.createBuffer();
  81. if (!vertexColorbuffer) {
  82. console.log('Failed to create the buffer object');
  83. return -1;
  84. }
  85. // Write the vertex coordinates and color to the buffer object
  86. gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
  87. gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
  88. var FSIZE = verticesColors.BYTES_PER_ELEMENT;
  89. // Assign the buffer object to a_Position and enable the assignment
  90. var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  91. if(a_Position < 0) {
  92. console.log('Failed to get the storage location of a_Position');
  93. return -1;
  94. }
  95. gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);
  96. gl.enableVertexAttribArray(a_Position);
  97. // Assign the buffer object to a_Color and enable the assignment
  98. var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
  99. if(a_Color < 0) {
  100. console.log('Failed to get the storage location of a_Color');
  101. return -1;
  102. }
  103. gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
  104. gl.enableVertexAttribArray(a_Color);
  105. return n;
  106. }

7.7 通过顶点索引绘制立方体

  1. // 顶点着色器
  2. var VSHADER_SOURCE =
  3. 'attribute vec4 a_Position;\n' +
  4. 'attribute vec4 a_Color;\n' +
  5. 'uniform mat4 u_MvpMatrix;\n' +
  6. 'varying vec4 v_Color;\n' +
  7. 'void main() {\n' +
  8. ' gl_Position = u_MvpMatrix * a_Position;\n' +
  9. ' v_Color = a_Color;\n' +
  10. '}\n';
  11. // 片源着色器
  12. var FSHADER_SOURCE =
  13. '#ifdef GL_ES\n' +
  14. 'precision mediump float;\n' +
  15. '#endif\n' +
  16. 'varying vec4 v_Color;\n' +
  17. 'void main() {\n' +
  18. ' gl_FragColor = v_Color;\n' +
  19. '}\n';
  20. function main() {
  21. // canvas对象
  22. var canvas = document.getElementById('webgl');
  23. // 创建webgl对象
  24. var gl = getWebGLContext(canvas);
  25. if (!gl) {
  26. throw new TypeError("创建webgl对象失败")
  27. }
  28. if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
  29. throw new TypeError("初始化着色器失败");
  30. }
  31. var n = initVertexBuffers(gl);
  32. if (n < 0) {
  33. throw new TypeError("初始化Buffer失败");
  34. }
  35. // 设置默认颜色
  36. gl.clearColor(0.0, 0.0, 0.0, 1.0);
  37. // 开启隐藏面消除
  38. gl.enable(gl.DEPTH_TEST);
  39. // 获取 矩阵对象变量
  40. var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
  41. if (!u_MvpMatrix) {
  42. console.log('Failed to get the storage location of u_MvpMatrix');
  43. return;
  44. }
  45. // 创建矩阵对象
  46. var mvpMatrix = new Matrix4();
  47. // 定义透视投影矩阵
  48. mvpMatrix.setPerspective(30, 1, 1, 100);
  49. // 设置视点,观察点,上方向
  50. mvpMatrix.lookAt(3, 3, 7, 0, 0, 0, 0, 1, 0);
  51. // 矩阵对象变量赋值
  52. gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
  53. // 清除默认颜色和深度缓冲区
  54. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  55. // 按索引值来绘制顶点
  56. gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
  57. }
  58. function initVertexBuffers(gl) {
  59. // Create a cube
  60. // v6----- v5
  61. // /| /|
  62. // v1------v0|
  63. // | | | |
  64. // | |v7---|-|v4
  65. // |/ |/
  66. // v2------v3
  67. var verticesColors = new Float32Array([
  68. // Vertex coordinates and color
  69. 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, // v0 White
  70. -1.0, 1.0, 1.0, 1.0, 0.0, 1.0, // v1 Magenta
  71. -1.0, -1.0, 1.0, 1.0, 0.0, 0.0, // v2 Red
  72. 1.0, -1.0, 1.0, 1.0, 1.0, 0.0, // v3 Yellow
  73. 1.0, -1.0, -1.0, 0.0, 1.0, 0.0, // v4 Green
  74. 1.0, 1.0, -1.0, 0.0, 1.0, 1.0, // v5 Cyan
  75. -1.0, 1.0, -1.0, 0.0, 0.0, 1.0, // v6 Blue
  76. -1.0, -1.0, -1.0, 0.0, 0.0, 0.0 // v7 Black
  77. ]);
  78. // 生成索引顶点坐标,12个三角形的顶点
  79. var indices = new Uint8Array([
  80. 0, 1, 2, 0, 2, 3, // front
  81. 0, 3, 4, 0, 4, 5, // right
  82. 0, 5, 6, 0, 6, 1, // up
  83. 1, 6, 7, 1, 7, 2, // left
  84. 7, 4, 3, 7, 3, 2, // down
  85. 4, 7, 6, 4, 6, 5 // back
  86. ]);
  87. // 创建buffer对象
  88. var vertexColorBuffer = gl.createBuffer();
  89. var indexBuffer = gl.createBuffer();
  90. if (!vertexColorBuffer || !indexBuffer) {
  91. return -1;
  92. }
  93. // 绑定颜色Buffer变量
  94. gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);
  95. gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
  96. var FSIZE = verticesColors.BYTES_PER_ELEMENT;
  97. // 获取顶点位置变量
  98. var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
  99. if(a_Position < 0) {
  100. console.log('Failed to get the storage location of a_Position');
  101. return -1;
  102. }
  103. gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 6, 0);
  104. gl.enableVertexAttribArray(a_Position);
  105. // 设置顶点颜色
  106. var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
  107. if(a_Color < 0) {
  108. throw new TypeError("获取Attribute变量失败");
  109. }
  110. gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 6, FSIZE * 3);
  111. gl.enableVertexAttribArray(a_Color);
  112. // 绑定变量,设置变量
  113. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
  114. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
  115. // 顶点索引值的长度 36
  116. return indices.length;
  117. }

7.8 通过索引绘制每个面颜色值固定的立方体,相同顶点需要应用不同颜色值

7.7例子有一个问题,就是相同顶点需要应用不同颜色

  1. // ColoredCube.js (c) 2012 matsuda
  2. // Vertex shader program
  3. var VSHADER_SOURCE =
  4. 'attribute vec4 a_Position;\n' +
  5. 'attribute vec4 a_Color;\n' +
  6. 'uniform mat4 u_MvpMatrix;\n' +
  7. 'varying vec4 v_Color;\n' +
  8. 'void main() {\n' +
  9. ' gl_Position = u_MvpMatrix * a_Position;\n' +
  10. ' v_Color = a_Color;\n' +
  11. '}\n';
  12. // Fragment shader program
  13. var FSHADER_SOURCE =
  14. '#ifdef GL_ES\n' +
  15. 'precision mediump float;\n' +
  16. '#endif\n' +
  17. 'varying vec4 v_Color;\n' +
  18. 'void main() {\n' +
  19. ' gl_FragColor = v_Color;\n' +
  20. '}\n';
  21. function main() {
  22. // Retrieve <canvas> element
  23. var canvas = document.getElementById('webgl');
  24. // Get the rendering context for WebGL
  25. var gl = getWebGLContext(canvas);
  26. if (!gl) {
  27. console.log('Failed to get the rendering context for WebGL');
  28. return;
  29. }
  30. // Initialize shaders
  31. if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
  32. console.log('Failed to intialize shaders.');
  33. return;
  34. }
  35. // Set the vertex information
  36. var n = initVertexBuffers(gl);
  37. if (n < 0) {
  38. console.log('Failed to set the vertex information');
  39. return;
  40. }
  41. // Set the clear color and enable the depth test
  42. gl.clearColor(0.0, 0.0, 0.0, 1.0);
  43. gl.enable(gl.DEPTH_TEST);
  44. // Get the storage location of u_MvpMatrix
  45. var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
  46. if (!u_MvpMatrix) {
  47. console.log('Failed to get the storage location of u_MvpMatrix');
  48. return;
  49. }
  50. // Set the eye point and the viewing volume
  51. var mvpMatrix = new Matrix4();
  52. mvpMatrix.setPerspective(30, 1, 1, 100);
  53. mvpMatrix.lookAt(3, 3, 7, 0, 0, 0, 0, 1, 0);
  54. // Pass the model view projection matrix to u_MvpMatrix
  55. gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
  56. // Clear color and depth buffer
  57. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  58. // Draw the cube
  59. gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
  60. }
  61. function initVertexBuffers(gl) {
  62. // Create a cube
  63. // v6----- v5
  64. // /| /|
  65. // v1------v0|
  66. // | | | |
  67. // | |v7---|-|v4
  68. // |/ |/
  69. // v2------v3
  70. // 六个面的顶点
  71. var vertices = new Float32Array([
  72. 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0,-1.0, 1.0, 1.0,-1.0, 1.0, // v0-v1-v2-v3 front
  73. 1.0, 1.0, 1.0, 1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0, // v0-v3-v4-v5 right
  74. 1.0, 1.0, 1.0, 1.0, 1.0,-1.0, -1.0, 1.0,-1.0, -1.0, 1.0, 1.0, // v0-v5-v6-v1 up
  75. -1.0, 1.0, 1.0, -1.0, 1.0,-1.0, -1.0,-1.0,-1.0, -1.0,-1.0, 1.0, // v1-v6-v7-v2 left
  76. -1.0,-1.0,-1.0, 1.0,-1.0,-1.0, 1.0,-1.0, 1.0, -1.0,-1.0, 1.0, // v7-v4-v3-v2 down
  77. 1.0,-1.0,-1.0, -1.0,-1.0,-1.0, -1.0, 1.0,-1.0, 1.0, 1.0,-1.0 // v4-v7-v6-v5 back
  78. ]);
  79. // 六个面的顶点颜色坐标
  80. var colors = new Float32Array([ // Colors
  81. 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, // v0-v1-v2-v3 front(blue)
  82. 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, // v0-v3-v4-v5 right(green)
  83. 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, // v0-v5-v6-v1 up(red)
  84. 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, // v1-v6-v7-v2 left
  85. 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, // v7-v4-v3-v2 down
  86. 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0 // v4-v7-v6-v5 back
  87. ]);
  88. // 两个三角形一个面,一共六个面
  89. var indices = new Uint8Array([
  90. 0, 1, 2, 0, 2, 3, // front
  91. 4, 5, 6, 4, 6, 7, // right
  92. 8, 9,10, 8,10,11, // up
  93. 12,13,14, 12,14,15, // left
  94. 16,17,18, 16,18,19, // down
  95. 20,21,22, 20,22,23 // back
  96. ]);
  97. // Create a buffer object
  98. var indexBuffer = gl.createBuffer();
  99. if (!indexBuffer)
  100. return -1;
  101. // Write the vertex coordinates and color to the buffer object
  102. if (!initArrayBuffer(gl, vertices, 3, gl.FLOAT, 'a_Position'))
  103. return -1;
  104. if (!initArrayBuffer(gl, colors, 3, gl.FLOAT, 'a_Color'))
  105. return -1;
  106. // Write the indices to the buffer object
  107. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
  108. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
  109. return indices.length;
  110. }
  111. function initArrayBuffer(gl, data, num, type, attribute) {
  112. var buffer = gl.createBuffer(); // Create a buffer object
  113. if (!buffer) {
  114. console.log('Failed to create the buffer object');
  115. return false;
  116. }
  117. // Write date into the buffer object
  118. gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  119. gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
  120. // Assign the buffer object to the attribute variable
  121. var a_attribute = gl.getAttribLocation(gl.program, attribute);
  122. if (a_attribute < 0) {
  123. console.log('Failed to get the storage location of ' + attribute);
  124. return false;
  125. }
  126. gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);
  127. // Enable the assignment of the buffer object to the attribute variable
  128. gl.enableVertexAttribArray(a_attribute);
  129. return true;
  130. }