• WebGL 绘制矩形


    上一节绘制了圆点,调用的绘制方法如下:gl.drawArrays(gl.POINTS, 0, 1);   第一个参数明显是个枚举类型,肯定还有其他值,如下所示:

    • POINTS 可视的点
    • LINES 单独线段
    • LINE_STRIP 线条
    • LINE_LOOP 闭合线条
    • TRIANGLES 单独三角形
    • TRIANGLE_STRIP 三角带
    • TRIANGLE_FAN 三角扇

    这小节尝试一下 绘制单独线段、线条、闭合线条、三角带(可构成矩形)

    代码如下所示:

    1. <template>
    2. <div class="wrapper">
    3. <div class="point-wrapper">
    4. <div style="margin-bottom: 20px">绘制点div>
    5. <canvas id="point" width="280" height="250">canvas>
    6. div>
    7. <div class="point-mouse">
    8. <div style="margin-bottom: 20px">鼠标绘制点div>
    9. <canvas id="pointByMouse" width="280" height="250">canvas>
    10. div>
    11. div>
    12. template>
    13. <script>
    14. export default {
    15. name: "point",
    16. };
    17. script>
    18. <script setup>
    19. import { onMounted } from "vue";
    20. import { initShaders } from "@/utils/myGL.js";
    21. const vertexShaderSrc = `
    22. attribute vec4 a_Position;
    23. attribute float a_PointSize;
    24. void main() {
    25. gl_Position = a_Position;
    26. gl_PointSize = a_PointSize;
    27. }
    28. `;
    29. const fragmentShaderSrc = `
    30. precision mediump float;
    31. uniform vec4 u_FragColor;
    32. void main() {
    33. gl_FragColor = u_FragColor;
    34. }
    35. `;
    36. const fragmentShaderSrcCircle = `
    37. precision mediump float;
    38. void main() {
    39. float d = distance(gl_PointCoord, vec2(0.5, 0.5));
    40. if(d < 0.5) {
    41. gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
    42. } else {
    43. discard;
    44. }
    45. }
    46. `;
    47. const drawPointStatic = () => {
    48. const canvas = document.getElementById("point");
    49. // webgl画笔
    50. const gl = canvas.getContext("webgl");
    51. // 初始化着色器
    52. initShaders(gl, vertexShaderSrc, fragmentShaderSrc);
    53. const a_position = gl.getAttribLocation(gl.program, "a_Position");
    54. const a_pointSize = gl.getAttribLocation(gl.program, "a_PointSize");
    55. const u_FragColor = gl.getUniformLocation(gl.program, "u_FragColor");
    56. gl.vertexAttrib3f(a_position, 0, 0.0, 0.0);
    57. gl.vertexAttrib1f(a_pointSize, 20.0);
    58. gl.uniform4f(u_FragColor, 1.0, 0.0, 0.0, 1.0);
    59. // 指定将要用来清理绘图区的颜色
    60. gl.clearColor(0.0, 0.0, 0.0, 1.0);
    61. // 清理绘图区
    62. gl.clear(gl.COLOR_BUFFER_BIT);
    63. // 绘制顶点
    64. gl.drawArrays(gl.POINTS, 0, 1);
    65. setTimeout(() => {
    66. initShaders(gl, vertexShaderSrc, fragmentShaderSrcCircle);
    67. // 指定将要用来清理绘图区的颜色
    68. gl.clearColor(0.0, 0.0, 0.0, 1.0);
    69. // 清理绘图区
    70. gl.clear(gl.COLOR_BUFFER_BIT);
    71. // 绘制顶点
    72. gl.drawArrays(gl.POINTS, 0, 1);
    73. }, 2000);
    74. };
    75. const drawPointByMouse = () => {
    76. const canvas = document.getElementById("pointByMouse");
    77. // webgl画笔
    78. const gl = canvas.getContext("webgl");
    79. // 初始化着色器
    80. initShaders(gl, vertexShaderSrc, fragmentShaderSrc);
    81. // // 指定将要用来清理绘图区的颜色
    82. gl.clearColor(0.0, 0.0, 0.0, 1.0);
    83. // // 清理绘图区
    84. gl.clear(gl.COLOR_BUFFER_BIT);
    85. let pointArrs = [];
    86. document.addEventListener("click", (event) => {
    87. const { clientX, clientY } = event;
    88. const { left, top, width, height } = canvas.getBoundingClientRect();
    89. const [cssX, cssY] = [clientX - left, clientY - top];
    90. const [halfWidth, halfHeight] = [width / 2, height / 2];
    91. const [xBaseCenter, yBaseCenter] = [cssX - halfWidth, cssY - halfHeight];
    92. const yBaseCenterTop = -yBaseCenter;
    93. const [x, y] = [xBaseCenter / halfWidth, yBaseCenterTop / halfHeight];
    94. const a_Position = gl.getAttribLocation(gl.program, "a_Position");
    95. const a_pointSize = gl.getAttribLocation(gl.program, "a_PointSize");
    96. const u_FragColor = gl.getUniformLocation(gl.program, "u_FragColor");
    97. pointArrs.push({
    98. x,
    99. y,
    100. z: Math.random() * 50,
    101. color: {
    102. r: Math.random() * 1,
    103. g: Math.random() * 1,
    104. b: Math.random() * 1,
    105. },
    106. });
    107. gl.clear(gl.COLOR_BUFFER_BIT);
    108. pointArrs.forEach((item) => {
    109. gl.vertexAttrib2f(a_Position, item.x, item.y);
    110. gl.vertexAttrib1f(a_pointSize, item.z);
    111. gl.uniform4f(u_FragColor, item.color.r, item.color.g, item.color.b, 1.0);
    112. gl.drawArrays(gl.POINTS, 0, 1);
    113. });
    114. });
    115. };
    116. onMounted(() => {
    117. drawPointStatic();
    118. drawPointByMouse();
    119. });
    120. script>
    121. <style lang="scss" scoped>
    122. .wrapper {
    123. display: flex;
    124. }
    125. .point-wrapper {
    126. width: 300px;
    127. height: 300px;
    128. background-color: gray;
    129. }
    130. .point-mouse {
    131. margin-left: 20px;
    132. width: 300px;
    133. height: 300px;
    134. background-color: gray;
    135. }
    136. style>

    绘制图形如下所示:

    注意在代码中引入了initShaders  方法,如下:

    1. function loadShader(gl, type, source) {
    2. //根据着色类型,建立着色器对象
    3. const shader = gl.createShader(type);
    4. //将着色器源文件传入着色器对象中
    5. gl.shaderSource(shader, source);
    6. //编译着色器对象
    7. gl.compileShader(shader);
    8. //返回着色器对象
    9. return shader;
    10. }
    11. export function initShaders(gl, vsSource, fsSource) {
    12. //创建程序对象
    13. const program = gl.createProgram();
    14. //建立着色对象
    15. const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
    16. const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
    17. //把顶点着色对象装进程序对象中
    18. gl.attachShader(program, vertexShader);
    19. //把片元着色对象装进程序对象中
    20. gl.attachShader(program, fragmentShader);
    21. //连接webgl上下文对象和程序对象
    22. gl.linkProgram(program);
    23. //启动程序对象
    24. gl.useProgram(program);
    25. //将程序对象挂到上下文对象上
    26. gl.program = program;
    27. }

  • 相关阅读:
    【SpringBoot教程】SpringBoot+MybatisPlus数据库连接测试 用户收货信息接口开发
    Helm3模板-内置函数和Values
    极客玩物 | 新手小白家用洗衣机选购指南:双十一必备攻略
    app专项测试:app弱网测试
    科技兴关,荣联与天津海关共建基因组数据库及分析平台
    《在线编程-Python篇》Python入门 01 输入输出
    vue手写提示组件弹窗
    cubeIDE开发, 物联网应用之stm32的蓝牙通信设计
    2023年天津财经大学珠江学院专升本经济学专业课考试大纲
    Java并发编程面试题
  • 原文地址:https://blog.csdn.net/liubangbo/article/details/132777982