WebGL笔记:绘制矩形面的几种方式以及封装封装多边形对象来绘制不同图形

绘制矩形面

  • 可以绘制的面只有三角面,要绘制矩形面的话,只能用两个三角形去拼

1 ) 使用 三角带 TRIANGLE_STRIP 绘制矩形


  • 回顾一下之前的规律:

    • 第一个三角形:v0>v1>v2
    • 第偶数个三角形:以上一个三角形的第二条边+下一个点为基础,以和第二条边相反的方向绘制三角形
    • 第奇数个三角形:以上一个三角形的第三条边+下一个点为基础,以和第二条边相反的方向绘制三角形
  • 关键顶点绘制数据

    const vertices = new Float32Array([-0.2, 0.2,-0.2,-0.2,0.2, 0.2,0.2,-0.2,
    ])
    
  • 绘制: gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)

2 ) 使用 三角带 TRIANGLE_FAN 绘制矩形


  • 回顾一下之前的规律:

    • v0>v1>v2: 以上一个三角形的第三条边+下一个点为基础,按照和第三条边相反的顺序,绘制三角形
    • v0>v2>v3: 同上
    • v0>v3>v4: 同上
    • v0>v4>v5: 同上
  • 基于此,设计顶点关键数据

    const vertices = new Float32Array([-0.2, -0.2,0.2, -0.2,0.2, 0.2,-0.2, 0.2
    ])
    
  • 绘制: gl.drawArrays(gl.TRIANGLE_FAN, 0, 4)

3 )使用独立三角形,绘制矩形


  • 绘制规律

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

    const vertices = new Float32Array([-0.2, 0.2,-0.2, -0.2,0.2, 0.2,0.2, 0.2,-0.2, -0.2,0.2, -0.2
    ])
    

可以根据自己的需求,绘制各种各样的图形

封装多边形对象

1 )封装一个Poly 对象,用于绘制多边形

const defAttr = () => ({gl: null,vertices: [],geoData: [],size: 2,attrName: 'a_Position',count: 0,types: ['POINTS'],
})export default class Poly {constructor(attr) {Object.assign(this,defAttr(),attr)this.init()}init() {const { attrName, size, gl } = this;if(!gl) returnconst vertexBuffer = gl.createBuffer()gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)this.updateBuffer()const a_Position = gl.getAttribLocation(gl.program,attrName)gl.vertexAttribPointer(a_Position, size, gl.FLOAT, false, 0, 0)gl.enableVertexAttribArray(a_Position)}addVertice(...params) {this.vertices.push(...params)this.updateBuffer()}popVertice() {const { vertices, size }=thisconst len = vertices.lengthvertices.splice(len-size,len)this.updateCount()}setVertice(ind,...params) {const { vertices, size }=thisconst i = ind * sizeparams.forEach((param,paramInd) => {vertices[i+paramInd] = param})}updateBuffer() {const { gl,vertices } = thisthis.updateCount()gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)}updateCount() {this.count = this.vertices.length / this.size}updateVertices(params) {const { geoData } = thisconst vertices = []geoData.forEach(data => {params.forEach(key => {vertices.push(data[key])})})this.vertices=vertices}draw(types = this.types) {const { gl, count } = thisfor(let type of types) {gl.drawArrays(gl[type],0,count);}}
}
  • 属性

    • gl webgl上下文对象
    • vertices 顶点数据集合,在被赋值的时候会做两件事
      • 更新count 顶点数量,数据运算尽量不放渲染方法里
      • 向缓冲区内写入顶点数据
    • geoData 模型数据,对象数组,可解析出 vertices 顶点数据
    • size 顶点分量的数目
    • positionName 代表顶点位置的attribute 变量名
    • count 顶点数量
    • types 绘图方式,可以用多种方式绘图
  • 方法

    • init() 初始化方法,建立缓冲对象,并将其绑定到webgl 上下文对象上,然后向其中写入顶点数据。将缓冲对象交给attribute变量,并开启attribute 变量的批处理功能。
    • addVertice() 添加顶点
    • popVertice() 删除最后一个顶点
    • setVertice() 根据索引位置设置顶点
    • updateBuffer() 更新缓冲区数据,同时更新顶点数量
    • updateCount() 更新顶点数量
    • updateVertices() 基于geoData 解析出vetices 数据
    • draw() 绘图方法

2 )应用1

const poly = new Poly({gl,vertices:[0, 0.2]
})poly.draw(['POINTS'])setTimeout(()=>{poly.addVertice(-0.2, -0.1);gl.clear(gl.COLOR_BUFFER_BIT);poly.draw(['POINTS'])
}, 1000)setTimeout(()=>{gl.clear(gl.COLOR_BUFFER_BIT);poly.draw(['POINTS','LINE_STRIP'])
}, 2000)

3 )应用2

// 实例化多边形
const poly = new Poly({gl,types:['POINTS','LINE_STRIP']
})// 鼠标点击事件
canvas.addEventListener("click", (event) => {const { x,y } = getMousePosInWebgl(event, canvas);poly.addVertice(x,y);gl.clear(gl.COLOR_BUFFER_BIT);poly.draw();
});

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

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

相关文章

在移动固态硬盘上安装Ubuntu系统和ROS2

目录 原视频准备烧录 原视频 b站鱼香ros 准备 1.在某宝上买一个usb移动固态硬盘或固态U盘,至少64G 2.下载鱼香ros烧录工具 下载第二个就行了,不然某网盘的速度下载全部要一天 下载后,选择FishROS2OS制作工具压缩包,进行解压…

【分布式微服务】feign 异步调用获取不到ServletRequestAttributes

公司调用接口的时候使用feign,但是服务之间还是使用了鉴权,需要通过RequestInterceptor 去传递uuid 概念 OpenFeign是一个声明式的Web服务客户端,它使得编写HTTP客户端变得更简单。在使用OpenFeign进行异步调用时,你可以通过配置来实现。但是,如果你在配置或调用过程中遇…

【vue3】toRef与toRefs的使用,toRef与ref的区别

假期第四篇,对于基础的知识点,我感觉自己还是很薄弱的。 趁着假期,再去复习一遍 1、toRef与toRefs 创建一个ref对象,其value值指向另一个对象中的某个属性 语法:const name toRef(person,‘name’&#xf…

(四)动态阈值分割

文章目录 一、基本概念二、实例解析 一、基本概念 基于局部阈值分割的dyn_threshold()算子,适用于一些无法用单一灰度进行分割的情况,如背景比较复杂,有的部分比前景目标亮,或者有的部分比前景目标暗;又比如前景目标包…

【postgresql 基础入门】多表联合查询 join与union 并,交,差等集合操作,两者的区别之处

多表数据联合查询 ​专栏内容: postgresql内核源码分析手写数据库toadb并发编程 ​开源贡献: toadb开源库 个人主页:我的主页 管理社区:开源数据库 座右铭:天行健,君子以自强不息;地势坤&#x…

数据结构与算法基础(青岛大学-王卓)(8)

哎呀呀,sorry艾瑞波地,这次真的断更一个月了,又发生了很多很多事情,秋风开始瑟瑟了,老父亲身体查出肿瘤了,有病请及时就医,愿每一个人都有一个健康的身体,God bless U and FAMILY. 直…

实用调试技巧

引言:一个完美的代码离不开程序员的调试,所谓三分编写七分调试,今天我们给大家介绍几种实用的调试技巧。 1️⃣Bug的由来: 原意是指,小虫子,昆虫等,而人们也通常将电脑程序中的一些隐藏的缺陷或…

ThreeJS - 封装一个GLB模型展示组件(TypeScript)

一、引言 最近基于Three.JS,使用class封装了一个GLB模型展示,支持TypeScript、支持不同框架使用,具有多种功能。 (下图展示一些基础的功能,可以自行扩展,比如光源等) 二、主要代码 本模块依赖…

聊聊常见的IO模型 BIO/NIO/AIO 、DIO、多路复用等IO模型

聊聊常见的IO模型 BIO/NIO/AIO/DIO、IO多路复用等IO模型 文章目录 一、前言1. 什么是IO模型2. 为什么需要IO模型 二、常见的IO模型1. 同步阻塞IO(Blocking IO,BIO)2. 同步非阻塞IO(Non-blocking IO,NIO)3.…

C++--位图和布隆过滤器

1.什么是位图 所谓位图,就是用每一位来存放某种状态,适用于海量数据,数据无重复的场景。通常是用来判断某个数据存不存在的。比如int 有32位,就可以存放0到31这32个数字在不在某个文件中。当然,其他类型也可以。 2.位…

数据结构-哈希表

系列文章目录 1.集合-Collection-CSDN博客​​​​​​ 2.集合-List集合-CSDN博客 3.集合-ArrayList源码分析(面试)_喜欢吃animal milk的博客-CSDN博客 4.数据结构-哈希表_喜欢吃animal milk的博客-CSDN博客 文章目录 目录 系列文章目录 文章目录 前言 一 . 什么是哈希表&a…

Linux- fg命令 bg命令

fg fg是Unix-like操作系统(如Linux和macOS)中的一个shell内建命令,用于将后台作业带到前台执行。这个命令常用于与bg(后台执行)命令和jobs(列出当前作业)命令一起,进行shell中的作业…

Linux系统之部署Linux命令大全搜索工具

Linux系统之部署Linux命令大全搜索工具 一、linux-command介绍二、本次实践介绍2.1 本地环境规划2.2 本次实践介绍 三、安装httpd软件3.1 检查yum仓库3.2 安装httpd软件3.3 启动httpd服务3.4 查看httpd服务状态3.5 防火墙和selinux设置3.6 浏览器测试web服务 四、安装linux-com…

LabVIEW开发虚拟与现实融合的数字电子技术渐进式实验系统

LabVIEW开发虚拟与现实融合的数字电子技术渐进式实验系统 数字电子技术是所有电气专业的重要学科基础,具有很强的理论性和实践性。其实验是提高学生分析、设计和调试数字电路能力,培养学生解决实际问题的工程实践能力,激发学生创新意识&…

Echarts 教程一

Echarts 教程一 可视化大屏幕适配方案可视化大屏幕布局方案Echart 图表通用配置部分解决方案1. titile2. tooltip3. xAxis / yAxis 常用配置4. legend5. grid6. series7.color Echarts API 使用全局echarts对象echarts实例对象 可视化大屏幕适配方案 rem flexible.js 关于flex…

Elasticsearch:与多个 PDF 聊天 | LangChain Python 应用教程(免费 LLMs 和嵌入)

在本博客中,你将学习创建一个 LangChain 应用程序,以使用 ChatGPT API 和 Huggingface 语言模型与多个 PDF 文件聊天。 如上所示,我们在最最左边摄入 PDF 文件,并它们连成一起,并分为不同的 chunks。我们可以通过使用 …

QA 云计算实验问题汇总

Q Win11中VMware虚拟网卡有感叹号 2023-9-27一位同学的win11的两个VMware17的虚拟网卡都有感叹号 A 清除注册表 步骤1 关闭VMWare虚拟化软件 步骤2 使用CCleaner pro 清理注册表 步骤3 重启系统 步骤4 VMware虚拟网卡上的感叹号消失。 Q Win11上的VisualBox的网卡消失了…

DBA数据库运维-MySQL安装篇(glibc,源码)

1. MySQL数据库版本 版本说明社区版: MySQL Community Edition (GPL)1.可以看做是企业版的“广泛体验版(小白鼠版)",未经各个专有系统平台的压力和性能测试 2.基于GPL协议发布,可以随意下载使用 3.没有任何官方技术支持服务企业版:MySQL Enterpris…

JUC中的设计模式

文章目录 1. 终止模式之两阶段终止模式 1. 终止模式之两阶段终止模式 需求:用一个线程每两秒检测***状态,当不想检测时,用另一个线程将其停止 在一个线程 T1 中如何“优雅”终止线程 T2?这里的【优雅】指的是给 T2 一个料理后事…

解决AndroidStudio 2022.3.1版本 引入maven报错的问题

升级新版Android Studio 2022.3.1后发现引入maven报错: 1、报错的日志 ^ Unexpected tokens (use ‘;’ to separate expressions on the same line)。 2、解决问题 2.1 新版本的引入方式: repositories {maven { url uri("https://maven.aliy…