WebGL笔记:绘制多个点,三角形,以及画各种不同的线条,面

news2024/12/28 4:05:48

绘制多点

1 ) WebGL 缓冲区

  • 我们在用js定点位的时候,肯定是要建立一份顶点数据的,这份顶点数据是给着色器的,因为着色器需要这份顶点数据绘图
  • 然而,我们在js中建立顶点数据,着色器肯定是拿不到的,这是语言不通导致的
  • 为了解决这个问题,webgl 系统就建立了一个能翻译双方语言的缓冲区
  • js 可以用特定的方法把数据存在这个缓冲区中,着色器可以从缓冲区中拿到相应的数据
  • 接下来就看一下这个缓冲区是如何建的,着色器又是如何从其中拿数据的

2 )WebGL 绘制多点步骤

2.1 建立着色器源文件

<script id="vertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    void main(){
        gl_Position = a_Position;
        gl_PointSize = 20.0;
    }
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
    void main(){
        gl_FragColor=vec4(1.0,1.0,0.0,1.0);
    }
</script>

2.2 获取webgl 上下文

const canvas = document.getElementById('canvas');
canvas.width = 200;
canvas.height = 200;
const gl = canvas.getContext('webgl');

2.3 初始化着色器

const vsSource = document.getElementById('vertexShader').innerText;
const fsSource = document.getElementById('fragmentShader').innerText;
initShaders(gl, vsSource, fsSource);

2.4 设置顶点点位

const vertices = new Float32Array([
    0.0,  0.1,
    -0.1,-0.1,
    0.1, -0.1
]);

const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);
  • 建立顶点数据,两个浮点数构成一个顶点,分别代表 x、y 值
    const vertices = new Float32Array([
        // x, y
        0.0,  0.1, // 顶点
        -0.1, -0.1, // 顶点
        0.1, -0.1  // 顶点
    ])
    
  • 现在上面的这些顶点数据是存储在js 缓存里的,着色器拿不到,需要建立一个着色器和js 都能进入的公共区,即缓冲区
  • 建立缓冲对象
    const vertexBuffer = gl.createBuffer();
    
  • 现在上面的这个缓冲区是独立存在的,它只是一个空着的仓库,和谁都没有关系。接下来咱们就让其和着色器建立连接
  • 绑定缓冲对象
    gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    
  • 绑定缓冲区相关api为:gl.bindBuffer(target,buffer)
    • target 要把缓冲区放在 webgl 系统中的什么位置
    • buffer 缓冲区
  • 着色器对象在执行 initShaders() 初始化方法的时候,已经被写入webgl 上下文对象gl 中了,这个 initShaders 方法可查阅之前博文
  • 当缓冲区和着色器建立了绑定关系,我们就可以往这块空间写入数据了
  • 往缓冲区对象中写入数据
    gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
    
  • 相关api为:bufferData(target, data, usage) 将数据写入缓冲区
    • target 要把缓冲区放在 webgl 系统中的什么位置
    • data 数据
    • usage 向缓冲区写入数据的方式,目前使用 gl.STATIC_DRAW 方式,它是向缓冲区中一次性写入数据,着色器会绘制多次
    • 现在着色器虽然绑定了缓冲区,可以访问里面的数据了
    • 但是我们还得让着色器知道这个仓库是给哪个变量的,比如咱们这里用于控制点位的attribute 变量,这样做是为了提高绘图效率
  • 将缓冲区对象分配给 attribute 变量
    const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
    
  • 相关api为:gl.vertexAttribPointer(local, size, type, normalized, stride, offset) 将缓冲区对象分配给 attribute 变量
    • local attribute变量
    • size 顶点分量的个数,比如我们的vertices 数组中,两个数据表示一个顶点,我们定一个 2
    • type 数据类型,比如 gl.FLOAT 浮点型
    • normalized 是否将顶点数据归一
    • stride 相邻两个顶点间的字节数,我的例子里写的是0,那就是顶点之间是紧挨着的
    • offset 从缓冲区的什么位置开始存储变量,我的例子里写的是0,那就是从头开始存储变量
  • 到了这里,着色器就知道缓冲区的数据是给谁的了,因为咱们缓冲区里的顶点数据是数组,里面有多个顶点
  • 所以我们得开启一个让着色器批量处理顶点数据的属性,默认着色器只会一个一个的接收顶点数据,然后一个一个的绘制顶点
  • 开启顶点数据的批处理功能
    gl.enableVertexAttribArray(a_Position);
    
  • 相关api, enableVertexAttribArray(location), location attribute 变量
  • 好, 目前已经是万事俱备,可以着手绘图, 绘图前,先将画布清理下

2.5 清理画布

gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

2.6 绘图

gl.drawArrays(gl.POINTS, 0, 3); // 这是绘制三个顶点
  • 相关api:drawArrays(mode, first, count)
    • mode 绘图模式,比如 gl.POINTS 画点
    • first 从哪个顶点开始绘制
    • count 要画多少个顶点

绘制三角形

  • 绘制完成三个点,那么绘制三角形的工作就简单了
  • 注意:绘制三角形是不需要设置顶点的大小的

1 )顶点着色器移除顶点的配置

<script id="vertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    void main(){
        gl_Position = a_Position;
        // gl_PointSize = 20.0;
    }
</script>
  • 因为 gl_PointSize 这个属性是控制顶点大小的,已经不需要了

2 )js中更改绘制方式

// gl.drawArrays(gl.POINTS, 0, 3);
gl.drawArrays(gl.TRIANGLES, 0, 3);
  • gl.TRIANGLES 就是绘制三角形

画不同的线条

  • 关于 drawArrays 第一个 mode 参数
    • POINTS 可视的点
    • LINES 单独线段
    • LINE_STRIP 线条
    • LINE_LOOP 闭合线条
    • TRIANGLES 单独三角形
    • TRIANGLE_STRIP 三角带
    • TRIANGLE_FAN 三角扇

1 )POINTS

  • 字面理解就是一个个的可以看到的点

  • 上面六个点的绘制顺序是:v0, v1, v2, v3, v4, v5

2 )LINES 单独线段


  • 上面三条有向线段的绘制顺序是
    • v0 > v1
    • v2 > v3
    • v4 > v5

3 )LINE_STRIP 线条


  • 上面线条的绘制顺序是:v0>v1>v2>v3>v4>v5

4 )LINE_LOOP 闭合线条


  • 上面线条的绘制顺序是:v0>v1>v2>v3>v4>v5>v0

5 )TRIANGLES 三角形


  • 这里就是普通的三角形,画了2个,需要6个点
  • 上面两个面的绘制顺序是: v0>v1>v2,v3>v4>v5

6 )TRIANGLE_STRIP 三角带


  • 上面四个面的绘制顺序是:
    • v0>v1>v2:
    • 之后,以上一个三角形的第二条边+下一个点为基础,以和第二条边相反的方向绘制三角形,v2>v1>v3
    • 之后,以上一个三角形的第三条边+下一个点为基础,以和第二条边相反的方向绘制三角形,v2>v3>v4
    • 最后,以上一个三角形的第二条边+下一个点为基础,以和第二条边相反的方向绘制三角形,v4>v3>v5
  • 规律:
    • 第一个三角形:v0>v1>v2
    • 第偶数个三角形:以上一个三角形的第二条边+下一个点为基础,以和第二条边相反的方向绘制三角形
    • 第奇数个三角形:以上一个三角形的第三条边+下一个点为基础,以和第二条边相反的方向绘制三角形

7 )TRIANGLE_FAN 三角扇


  • 上面四个面的绘制顺序是:
    • v0>v1>v2: 以上一个三角形的第三条边+下一个点为基础,按照和第三条边相反的顺序,绘制三角形
    • v0>v2>v3: 同上
    • v0>v3>v4: 同上
    • v0>v4>v5: 同上
  • 注意,如果绘制的点数大于实际的点数
    • gl.drawArrays(gl.TRIANGLES, 0, 6); 这里其实只需要5就行,但是给了6
    • 那么按照上述规律再继续找原点继续绘制出一个三角形

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1051004.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java开源工具库使用之Lombok

文章目录 前言一、常用注解1.1 AllArgsConstructor/NoArgsConstructor/RequiredArgsConstructor1.2 Builder1.3 Data1.4 EqualsAndHashCode1.5 Getter/Setter1.6 Slf4j/Log4j/Log4j2/Log1.7 ToString 二、踩坑2.1 Getter/Setter 方法名不一样2.2 Builder 不会生成无参构造方法2…

微信小程序开发基础(二)基本组件

本帖开始介绍小程序中的一些基本组件~ 微信小程序是一种轻量、快速、跨平台的应用程序&#xff0c;是微信公众号的重要组成部分。随着微信小程序的普及&#xff0c;越来越多的开发者和企业开始使用微信小程序来搭建自己的应用&#xff0c;但是对于初次接触微信小程序的开发者…

高德地图根据两点的经纬度计算两点之间的距离(修正版)

SQL语句可以用来计算两个经纬度之间的距离。下面是一个示例的SQL语句&#xff1a; SELECT id, ( 6371 * ACOS( COS( RADIANS( lat1 ) ) * COS( RADIANS( lat2 ) ) * COS( RADIANS( lng2 ) - RADIANS( lng1 ) ) SIN( RADIANS( lat1 ) ) * SIN( RADIANS( lat2 ) ) ) ) AS dista…

【切片】基础不扎实引发的问题

本次文章主要是来聊聊关于切片传值需要注意的问题&#xff0c;如果不小心&#xff0c;则很容易引发线上问题&#xff0c;如果不够理解&#xff0c;可能会出现奇奇怪怪的现象 问题情况&#xff1a; 小 A 负责一个模块功能的实现&#xff0c;在调试代码的时候可能不仔细&#x…

使用YOLOv5的backbone网络识别图像天气 - P9

目录 环境步骤环境设置包引用声明一个全局的设备 数据准备收集数据集信息构建数据集在数据集中读取分类名称划分训练、测试数据集数据集划分批次 模型设计编写维持卷积前后图像大小不变的padding计算函数编写YOLOv5中使用的卷积模块编写YOLOv5中使用的Bottleneck模块编写YOLOv5…

【前端】ECMAScript6从入门到进阶

【前端】ECMAScript6从入门到进阶 1.ES6简介及环境搭建 1.1.ECMAScript 6简介 &#xff08;1&#xff09;ECMAScript 6是什么 ECMAScript 6.0&#xff08;以下简称 ES6&#xff09;是 JavaScript 语言的下一代标准&#xff0c;已经在2015年6月正式发布了。它的目标&#xff…

k8s部署gin-vue-admin框架、gitlab-ci、jenkins pipeline 、CICD

测试环境使用的jenkins 正式环境使用的gitlab-ci 测试环境 创建yaml文件 apiVersion: v1 kind: ConfigMap metadata:name: dtk-go-tiktok-admin-configlabels:app.kubernetes.io/name: dtk-go-tiktok-adminapp.kubernetes.io/business: infrastructureapp.kubernetes.io/run…

提升您的Mac文件拖拽体验——Dropzone 4 for mac

大家都知道&#xff0c;在Mac上进行文件拖拽是一件非常方便的事情。然而&#xff0c;随着我们在工作和生活中越来越多地使用电脑&#xff0c;我们对于这个简单操作的需求也越来越高。为了让您的文件拖拽体验更加高效和便捷&#xff0c;今天我们向大家介绍一款强大的工具——Dro…

车载ADB环境搭建

ADB是什么 ADB&#xff0c;即 Android Debug Bridge 是一种允许模拟器或已连接的 Android 设备进行通信的命令行工具&#xff0c;它可为各种设备操作提供便利&#xff0c;如安装和调试应用&#xff0c;并提供对 Unix shell&#xff08;可用来在模拟器或连接的设备上运行各种命…

C语言中柔性数组的讲解与柔性数组的优势

前言:也许你从来没有听说过柔性数组&#xff08;flexible array&#xff09;这个概念&#xff0c;但是它确实是存在的。C99 中&#xff0c;结构中的最后一个元素允许是未知大小的数组&#xff0c;这就叫做"柔性数组"成员。 目录标题 柔性数组什么是柔性数组呢&#…

基于SSM的图书商城系统的设计与实现

基于SSM的图书商城系统的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 图书列表 图书详情 个人中心 管理员界面 摘要 本文旨在探讨和展示一种基于Spring、…

PyTorch深度学习实战(18)——目标检测

PyTorch深度学习实战&#xff08;18&#xff09;——目标检测 0. 前言1. 目标检测1.1 基本概念1.2 目标检测应用1.3 模型训练流程 2. 创建自定义目标检测数据集2.1 安装图片标注工具2.2 数据集标注 3. 区域提议3.1 基本概念3.2 利用 SelectiveSearch 生成区域提议3.3 生成区域提…

VBA技术资料MF61:按每行指定字符数自动换行

【分享成果&#xff0c;随喜正能量】人生的旅途&#xff0c;一时的失意&#xff0c;一时的挫折&#xff0c;跌了一跤&#xff0c;不是人生的全部&#xff0c;只是人生的一个逗点&#xff0c;未来的成就、光辉&#xff0c;还有很多的虚线有待你继续去完成。。 我给VBA的定义&am…

JZ31 栈的压入、弹出序列

目录 一、题目 二、代码 一、题目 栈的压入、弹出序列_牛客题霸_牛客网 二、代码 class Solution { public:/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值即可** * param pushV int整型vector * param popV int整型vecto…

你真的知道MyBatisPlus吗?

你真的知道MyBatisPlus吗&#xff1f; 文章目录 你真的知道MyBatisPlus吗&#xff1f;快速入门入门案例常见注解常见配置 核心功能条件构造器AbstractWrapperUpdateWrapper条件构造器的用法 自定义SQLService接口 扩展功能代码生成静态工具逻辑删除枚举处理器JSON处理器 插件功…

【MATLAB-基于直方图优化的图像去雾技术】

【MATLAB-基于直方图优化的图像去雾技术】 1 直方图均衡2 程序实现3 局部直方图处理 1 直方图均衡 直方图是图像的一种统计表达形式。对于一幅灰度图像来说&#xff0c;其灰度统计直方图可以反映该图像中不同灰度级出现的统计情况。一般而言&#xff0c;图像的视觉效果和其直方…

【C++11】完美转发的使用以及万能引用

&#x1f30f;博客主页&#xff1a; 主页 &#x1f516;系列专栏&#xff1a; C ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ &#x1f60d;期待与大家一起进步&#xff01; 文章目录 一、模板中的&& 万能引用右值引用变量的类型会被编译器识别为左值类型 二、完…

ModuleNotFoundError: No module named ‘taming‘

参考&#xff1a;https://stackoverflow.com/questions/69983020/modulenotfounderror-no-module-named-taming 【问题】 缺少taming模块&#xff0c;错误提示&#xff1a;ModuleNotFoundError: No module named ‘taming’ 【解决】 pip install taming-transformers 若发现安…

计算机毕设 基于时间序列的股票预测于分析

文章目录 1 简介2 时间序列的由来2.1 四种模型的名称&#xff1a; 3 数据预览4 理论公式4.1 协方差4.2 相关系数4.3 scikit-learn计算相关性 5 金融数据的时序分析5.1 数据概况5.2 序列变化情况计算 最后 1 简介 Hi&#xff0c;大家好&#xff0c;这里是丹成学长&#xff0c;今…

利用Pycharm将python文件打包为exe文件

前言 要将Python文件打包为可执行的EXE文件&#xff0c;您可以使用第三方工具&#xff0c;如PyInstaller、cx_Freeze或py2exe等。下面是使用PyInstaller来打包Python文件为EXE文件的步骤&#xff1a; 概述: PyInstaller 是一个用于将 Python 应用程序打包成可执行文件的工具…