• OPENGL 不同绘制图元的类型,顶点索引的解释方式不同


    先看几个摘抄的代码例子

    1

    1. html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>Documenttitle>
    8. head>
    9. <body>
    10. <canvas id="canvas" width="400" height="400">
    11. Please use a browser that supports "canvas"
    12. canvas>
    13. <script src="../lib/cuon-matrix.js">script>
    14. <script>
    15. var VSHADER_SOURCE =
    16. 'attribute vec4 a_Position;\n' +
    17. 'attribute vec4 a_Color;\n' +
    18. 'uniform mat4 u_ViewProjMatrix;\n' +
    19. 'varying vec4 v_Color;\n' +
    20. 'void main() {\n' +
    21. ' gl_Position = u_ViewProjMatrix * a_Position;\n' +
    22. ' v_Color = a_Color;\n' +
    23. '}\n';
    24. // Fragment shader program
    25. var FSHADER_SOURCE =
    26. '#ifdef GL_ES\n' +
    27. 'precision mediump float;\n' +
    28. '#endif\n' +
    29. 'varying vec4 v_Color;\n' +
    30. 'void main() {\n' +
    31. ' gl_FragColor = v_Color;\n' +
    32. '}\n';
    33. const gl = canvas.getContext('webgl');
    34. const createShader = (type, source) => {
    35. const shader = gl.createShader(type);
    36. gl.shaderSource(shader, source);
    37. gl.compileShader(shader);
    38. const compileState = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
    39. if (!compileState) {
    40. const info = gl.getShaderInfoLog(shader);
    41. console.log('编译白痴信息为' + info)
    42. gl.deleteShader(shader);
    43. return null;
    44. }
    45. return shader
    46. }
    47. const createProgram = (vshader, fshader) => {
    48. const vertexShader = createShader(gl.VERTEX_SHADER, vshader);
    49. const fragementSaher = createShader(gl.FRAGMENT_SHADER, fshader);
    50. if (!vertexShader || !fragementSaher) {
    51. console.log('创建着色器失败')
    52. return null
    53. }
    54. const program = gl.createProgram();
    55. gl.attachShader(program, vertexShader);
    56. gl.attachShader(program, fragementSaher);
    57. gl.linkProgram(program);
    58. const linkState = gl.getProgramParameter(program, gl.LINK_STATUS);
    59. if (!linkState) {
    60. const err = gl.getProgramInfoLog(program);
    61. console.log('链接报错信息为' + err);
    62. gl.deleteShader(vertexShader);
    63. gl.deleteShader(fragementSaher);
    64. gl.deleteProgram(program);
    65. return null
    66. }
    67. return program
    68. }
    69. const program = createProgram(VSHADER_SOURCE, FSHADER_SOURCE)
    70. gl.useProgram(program);
    71. gl.program = program;
    72. const initVertexBuffers = () => {
    73. var verticesColors = new Float32Array([
    74. // Vertex coordinates and color
    75. 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, // v0 White
    76. -1.0, 1.0, 1.0, 1.0, 0.0, 1.0, // v1 Magenta
    77. -1.0, -1.0, 1.0, 1.0, 0.0, 0.0, // v2 Red
    78. 1.0, -1.0, 1.0, 1.0, 1.0, 0.0, // v3 Yellow
    79. 1.0, -1.0, -1.0, 0.0, 1.0, 0.0, // v4 Green
    80. 1.0, 1.0, -1.0, 0.0, 1.0, 1.0, // v5 Cyan
    81. -1.0, 1.0, -1.0, 0.0, 0.0, 1.0, // v6 Blue
    82. -1.0, -1.0, -1.0, 0.0, 0.0, 0.0 // v7 Black
    83. ]);
    84. var indices = new Uint8Array([
    85. 0, 1, 2, 0, 2, 3, // front
    86. 0, 3, 4, 0, 4, 5, // right
    87. 0, 5, 6, 0, 6, 1, // up
    88. 1, 6, 7, 1, 7, 2, // left
    89. 7, 4, 3, 7, 3, 2, // down
    90. 4, 7, 6, 4, 6, 5 // back
    91. ]);
    92. const vertexColorbuffer = gl.createBuffer();
    93. const indexBuffer = gl.createBuffer();
    94. const size = verticesColors.BYTES_PER_ELEMENT;
    95. gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
    96. gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
    97. var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    98. gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, size * 6, 0);
    99. gl.enableVertexAttribArray(a_Position);
    100. var a_Color = gl.getAttribLocation(gl.program, 'a_Color');
    101. gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, size * 6, size * 3);
    102. gl.enableVertexAttribArray(a_Color);
    103. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    104. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
    105. return indices.length;
    106. }
    107. const n = initVertexBuffers();
    108. gl.clearColor(0.0, 0.0, 0.0, 1.0);
    109. gl.enable(gl.DEPTH_TEST);
    110. console.log(n, 'nnn')
    111. var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_ViewProjMatrix');
    112. var mvpMatrix = new Matrix4();
    113. mvpMatrix.setPerspective(30, 1, 1, 100);
    114. mvpMatrix.lookAt(3, 3, 7, 0, 0, 0, 0, 1, 0);
    115. gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
    116. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    117. gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
    118. script>
    119. body>
    120. html>

     2

    1. var canvasElement=document.getElementById('webgl');
    2. var gl=canvasElement.getContext('webgl');
    3. //顶点着色器源码
    4. var vertexShaderSource = '' +
    5. //attribute声明vec4类型变量apos
    6. 'attribute vec4 apos;'+
    7. 'void main(){' +
    8. //设置几何体轴旋转角度为30度,并把角度值转化为浮点值
    9. 'float radian = radians(30.0);'+
    10. //求解旋转角度余弦值
    11. 'float cos = cos(radian);'+
    12. //求解旋转角度正弦值
    13. 'float sin = sin(radian);'+
    14. //引用上面的计算数据,创建绕x轴旋转矩阵
    15. // 1 0 0 0
    16. // 0 cosα sinα 0
    17. // 0 -sinα cosα 0
    18. // 0 0 0 1
    19. 'mat4 mx = mat4(1,0,0,0, 0,cos,-sin,0, 0,sin,cos,0, 0,0,0,1);'+
    20. //引用上面的计算数据,创建绕y轴旋转矩阵
    21. // cosβ 0 sinβ 0
    22. // 0 1 0 0
    23. //-sinβ 0 cosβ 0
    24. // 0 0 0 1
    25. 'mat4 my = mat4(cos,0,-sin,0, 0,1,0,0, sin,0,cos,0, 0,0,0,1);'+
    26. //两个旋转矩阵、顶点齐次坐标连乘
    27. ' gl_Position = mx*my*apos;' +
    28. '}';
    29. //片元着色器源码
    30. var fragShaderSource = '' +
    31. 'void main(){' +
    32. ' gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
    33. '}';
    34. //初始化着色器
    35. var program = initShader(gl,vertexShaderSource,fragShaderSource);
    36. //获取顶点着色器的位置变量apos
    37. var aposLocation = gl.getAttribLocation(program,'apos');
    38. // 8个顶点坐标数组
    39. var data=new Float32Array([
    40. 0.5, 0.5, 0.5,//顶点0
    41. -0.5, 0.5, 0.5,//顶点1
    42. -0.5, -0.5, 0.5,//顶点2
    43. 0.5, -0.5, 0.5,//顶点3
    44. 0.5, 0.5, -0.5,//顶点4
    45. -0.5, 0.5, -0.5,//顶点5
    46. -0.5, -0.5, -0.5,//顶点6
    47. 0.5, -0.5, -0.5,//顶点7
    48. ]);
    49. // 顶点索引数组
    50. var indexes = new Uint8Array([
    51. // 前四个点
    52. 0,1,2,3,
    53. // 后四个顶点
    54. 4,5,6,7,
    55. // 前后对应点
    56. 0,4,
    57. 1,5,
    58. 2,6,
    59. 3,7
    60. ]);
    61. //创建缓冲区对象
    62. var indexesBuffer=gl.createBuffer();
    63. //绑定缓冲区对象
    64. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexesBuffer);
    65. //索引数组indexes数据传入缓冲区
    66. gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indexes,gl.STATIC_DRAW);
    67. //创建缓冲区对象
    68. var buffer=gl.createBuffer();
    69. //绑定缓冲区对象
    70. gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
    71. //顶点数组data数据传入缓冲区
    72. gl.bufferData(gl.ARRAY_BUFFER,data,gl.STATIC_DRAW);
    73. //缓冲区中的数据按照一定的规律传递给位置变量apos
    74. gl.vertexAttribPointer(aposLocation,3,gl.FLOAT,false,0,0);
    75. //允许数据传递
    76. gl.enableVertexAttribArray(aposLocation);
    77. //LINE_LOOP模式绘制前四个点
    78. gl.drawElements(gl.LINE_LOOP,4,gl.UNSIGNED_BYTE,0);
    79. //LINE_LOOP模式从第五个点开始绘制四个点
    80. gl.drawElements(gl.LINE_LOOP,4,gl.UNSIGNED_BYTE,4);
    81. //LINES模式绘制后8个点
    82. gl.drawElements(gl.LINES, 8, gl.UNSIGNED_BYTE, 8);
    83. //声明初始化着色器函数
    84. function initShader(gl,vertexShaderSource,fragmentShaderSource){
    85. var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    86. var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    87. gl.shaderSource(vertexShader,vertexShaderSource);
    88. gl.shaderSource(fragmentShader,fragmentShaderSource);
    89. gl.compileShader(vertexShader);
    90. gl.compileShader(fragmentShader);
    91. var program = gl.createProgram();
    92. gl.attachShader(program,vertexShader);
    93. gl.attachShader(program,fragmentShader);
    94. gl.linkProgram(program);
    95. gl.useProgram(program);
    96. return program;
    97. }

    glDrawElements 和glDrawArrays的GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP, GL_QUADS, and GL_POLYGON这个模式mode,不同的模式对indices顶点索引数组有不同的解释,包含步长和步进方式;

    譬如

    Tips:(一般规定逆时针卷绕为正方向)

    GL_TRIANGLES:每三个顶点绘制一个三角形,如果顶点数量不是3的倍数,则忽略最后一个或两个顶点。

    GL_TRIANGLE_STRIP:有两种情况,

    (1)当前顶点序号n是偶数时,三角形三个顶点的顺序是(n - 2, n - 1, n )。

    (2)当前顶点序号n是奇数时,三角形三个顶点的顺序是(n - 1, n - 2, n)。

    这两种情况,保证了采用此种渲染方式的三角形顶点的卷绕顺序。

    例如:对于v2顶点,其序号为2,此时三个顶点的顺序是(v0, v1, v2);对于v3顶点,其序号为3,此时三个顶点的顺序是(v2, v1, v3),均是逆时针卷绕。

    GL_TRIANGLE_FAN:一系列顶点中的第一个点为中心点,其他顶点为边缘点,绘制一系列组成扇形的相邻三角形。例如三角形(v0, v1, v2)、(v0, v2, v3)。

  • 相关阅读:
    电脑数据同步到APP
    Python面向对象编程
    【Rust 日报】2022-08-28 Rust与GPU、WASM的应用
    Karmada 多云容器编排引擎支持多调度组,助力成本优化
    如何让“ChatGPT自己写出好的Prompt的“脚本在这里
    用echarts显示本年365天每天的数据
    Java面试八股之Redis哨兵机制
    Element UI 实战:跨页保存表格选中状态与判断状态可选性的高效方案
    jeesite添加多数据源
    基于N32G45的OLED驱动
  • 原文地址:https://blog.csdn.net/whl0071/article/details/126318523