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

绘制多点

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, y0.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.mzph.cn/news/93428.shtml

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

相关文章

基于SpringBoot的反诈宣传平台设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

SpringBoot注册web组件

目录 前言 一、注册Servlet组件 1.1 使用SpringBoot注解加继承HttpServet类注册 1.2 通过继承HttpServet类加配置类来进行注册 二、注册Listener组件 2.1 使用SpringBoot注解和实现ServletContextListener接口注册 2.2 ServletContextListener接口和配置类来进行注册 …

【Spring】Spring 创建和使用

Spring 创建和使用 一. 创建 Spring 项目1. 创建⼀个 Maven 项目2. 添加 Spring 框架⽀持3. 添加启动类 二. 存储 Bean 对象1. 创建 Bean2. 将 Bean 注册到容器 三. 获取并使⽤ Bean 对象1. 创建 Spring 上下文2. 获取指定的 Bean 对象3. 使用 Bean Spring 就是⼀个包含了众多⼯…

【vue3】wacth监听,监听ref定义的数据,监听reactive定义的数据,详解踩坑点

假期第二篇&#xff0c;对于基础的知识点&#xff0c;我感觉自己还是很薄弱的。 趁着假期&#xff0c;再去复习一遍 之前已经记录了一篇【vue3基础知识点-computed和watch】 今天在学习的过程中发现&#xff0c;之前记录的这一篇果然是很基础的&#xff0c;很多东西都讲的不够…

python复习

1.python属于解释型语言&#xff0c;解释器逐行解释每一句代码&#xff0c;然后执行 编译型语言需要由编译器生成最终可执行文件再执行 2. #单行注释""" 多行注释 """ 注释快捷键ctrl/ 3.变量是在计算机语言中能储存计算结果或表示某个数据…

Docker介绍与安装

目录 一、Docker 概述 1、什么时Docker 2、Docker的设计宗旨 4、Docker的优点 5、Docker容器和虚拟机的区别 6、 namespace的隔离&#xff08;命名空间&#xff09; 7、 Docker的三个核心概念 7.1 镜像 7.2 容器 7.3 仓库&#xff08;Docker Hapu&#xff09; 二、D…

Sentinel-2波段合成

Sentinel-2波段合成 在上一篇博客中下载了Sentinel-2数据&#xff0c;他有13个波段的.jp2文件&#xff0c;下面选取需要使用的波段进行合成。 导入了B2&#xff08;蓝色&#xff09;、B3&#xff08;绿色&#xff09;、B4&#xff08;红色&#xff09;、B8&#xff08;近红外&…

Linux--网络编程-字节序

进程间的通信&#xff1a; 管道、消息队列、共享内存、信号、信号量。 特点&#xff1a;都依赖于linux内核。 缺陷&#xff1a;无法多机通信。 一、网络编程&#xff1a; 1、地址&#xff1a;基于网络&#xff0c;ip地址端口号。 端口号作用&#xff1a; 一台拥有ip地址的主机…

Windows11安装MySQL8.1

安装过程中遇到任何问题均可以参考(这个博客只是单纯升级个版本和简化流程) Windows安装MySQL8教程-CSDN博客 到官网下载mysql8数据库软件 MySQL :: Download MySQL Community Server 下载完后,解压到你需要安装的文件夹 其中的配置文件内容了如下 [mysqld]# 设置3306端口po…

(c++)类和对象 下篇

目录 1.再次了解构造函数 2. Static成员 3. 友元 4. 内部类 5.匿名对象 6.拷贝对象时的一些编译器优化 1.再次了解构造函数 1.1 构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数&#xff0c;给对象中各个成员变量一个合适的初始值。 class Date { pub…

WARNING:tensorflow:Your input ran out of data; interrupting training. 解决方法

问题详情&#xff1a; WARNING:tensorflow:Your input ran out of data; interrupting training. Make sure that your dataset or generator can generate at least steps_per_epoch * epochs batches (in this case, 13800 batches). You may need to use the repeat() funct…

1.7.C++项目:仿muduo库实现并发服务器之Poller模块的设计

项目完整在&#xff1a; 文章目录 一、Poller模块&#xff1a;描述符IO事件监控模块二、提供的功能三、实现思想&#xff08;一&#xff09;功能&#xff08;二&#xff09;意义&#xff08;三&#xff09;功能设计 四、封装思想五、代码&#xff08;一&#xff09;框架&#…

Springboo整合Sentinel

Springboo整合Sentinel 1.启动Sentinel java -jar sentinel-dashboard-1.8.6.jar2.访问localhost:8080到Sentinel管理界面(默认账号和密码都是sentinel) 3.引入依赖(注意版本对应) <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spr…

stm32 - 中断/定时器

stm32 - 中断/定时器 概念时钟树定时器类型基准时钟&#xff08;系统时钟&#xff09;预分频器 - 时基单元CNT计数器 - 时基单元自动重装寄存器 - 时基单元基本定时器结构通用定时器计数器模式内外时钟源选择 定时中断基本结构时序预分频器时序计数器时序 概念 时钟树 https:…

Vue中如何进行多语言处理

Vue中的多语言处理 在开发多语言Web应用程序时&#xff0c;处理文本翻译和国际化是一个重要的任务。Vue.js提供了多种方法来实现多语言处理&#xff0c;以确保您的应用程序能够支持不同语言的用户。本文将深入探讨在Vue中进行多语言处理的方法&#xff0c;并提供示例代码来帮助…

WebSocket基础——WebSocket的基本概念 VS Http SpringBoot整合WebSocket vue前端代码和效果展示

前言 WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议。它允许在单个TCP连接上进行双向通信&#xff0c;而不需要通过多个HTTP请求-响应循环来实现。相比传统的HTTP请求&#xff0c;WebSocket提供了更低的延迟和更高的实时性。 本篇博客介绍WebSocket的基本概念…

Linux shell编程学习笔记6:查看和设置变量的常用命令

上节我们介绍了变量的变量命名规则、变量类型、使用变量时要注意的事项&#xff0c;今天我们学习一下查看和设置变量的一些常用命令&#xff0c;包括变量的提升&#xff0c;有些命令在之前的实例中已经使用过了。 一、 echo &#xff1a;查看变量的值 语法格式&#xff1a;ech…

计算机毕业设计 基于SSM的垃圾分类管理系统(以医疗垃圾为例)的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

《发现的乐趣》作者费曼(读书笔记)

目录 一、书简介 二、作者理查德•费曼 费曼式思维 教育与传承 三、个人思考 四、笔记 科学家眼中的花之美 关于偏科 父亲教育我的方式 知道一个概念和真正懂得这个概念有很大区别 我没有义务去成全别人对我的期望 诺贝尔奖——够格吗&#xff1f; 探究世界的游戏规…

2023年汉字小达人市级比赛在线模拟题来了,四种练习助力好成绩

2023年第十届汉字小达人比赛区级自由报名活动已于9月30日结束&#xff0c;尽管最终晋级市级比赛的名单还需要在11月初发布&#xff08;有一些学校的校级选拔还没结束&#xff09;&#xff0c;但是许多小朋友已经开始准备市级比赛了。 根据往年的经验&#xff0c;实际比赛也是在…