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

news2024/11/29 5:49:34

绘制矩形面

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

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) return
    const 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 }=this
    const len = vertices.length
    vertices.splice(len-size,len)
    this.updateCount()
  }
  setVertice(ind,...params) {
    const { vertices, size }=this
    const i = ind * size
    params.forEach((param,paramInd) => {
      vertices[i+paramInd] = param
    })
  }
  updateBuffer() {
    const { gl,vertices } = this
    this.updateCount()
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW)
  }
  updateCount() {
    this.count = this.vertices.length / this.size
  }
  updateVertices(params) {
    const { geoData } = this
    const vertices = []
    geoData.forEach(data => {
      params.forEach(key => {
        vertices.push(data[key])
      })
    })
    this.vertices=vertices
  }
  draw(types = this.types) {
    const { gl, count } = this
    for(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.coloradmin.cn/o/1052241.html

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

相关文章

预编译(2)

#和## #运算符: #运算符将宏的⼀个参数转换为字符串字⾯量。它仅允许出现在带参数的宏的替换列表中。 #运算符所执⾏的操作可以理解为“字符串化”。 举例: 当我们有⼀个变量 int a 10; 的时候,我们想打印出: the value of …

volatile修饰数组

结论:volatile修饰对象或数组时,只能保证他们的引用地址的可见性。 非volatile数组的可见性问题 public class Test {static int[] a new int[]{1};public static void main(String[] args) {new Thread(() -> { //线程Atry {Thread.sleep(1000);}…

ElasticSearch一对多关系方案

一、前言 使用MySQL做为存储,表与表之间有很多是一对多关系,比如订单和订单商品明细,客户和客户地址等等,但是因为ES本身是扁平化文档结构,一般不同索引之间是没有关系的,ES在处理这种关系时相比MySQL并不…

Python计算巴氏距离

Python计算巴氏距离 巴氏距离简介 在统计中,巴氏距离(Bhattacharyya Distance)测量两个离散或连续概率分布的相似性。它与衡量两个统计样品或种群之间的重叠量的巴氏系数密切相关。巴氏距离和巴氏系数以20世纪30年代曾在印度统计研究所工作…

分布式事务-TCC异常-幂等性

1、幂等性问题: 二阶段提交时,如果二阶段执行成功通知TC时出现网路或其他问题中断,那么TC没有收到执行成功的通知,TC内部有定时器不断的重试二阶段方法,导致接口出现幂等性问题。 2、解决方法 和空回滚问题一样也是…

Elastic SQL 输入:数据库指标可观测性的通用解决方案

作者:Lalit Satapathy, Ishleen Kaur, Muthukumar Paramasivam Elastic SQL 输入(metricbeat 模块和输入包)允许用户以灵活的方式对许多支持的数据库执行 SQL 查询,并将结果指标提取到 Elasticsearch。 本博客深入探讨了通用 SQL …

基于SpringBoot的课程答疑系统

目录 前言 一、技术栈 二、系统功能介绍 学生信息管理 科目类型管理 老师回答管理 我的收藏管理 学生问题 留言反馈 交流区 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息互联网信息的飞速发展,无纸化作业变成了一种趋势&#x…

SPSS探索性分析

前言: 本专栏参考教材为《SPSS22.0从入门到精通》,由于软件版本原因,部分内容有所改变,为适应软件版本的变化,特此创作此专栏便于大家学习。本专栏使用软件为:SPSS25.0 本专栏所有的数据文件可在个人主页—…

求解平面上物体的有向3d包围盒

算法流程: (1)点云下采样(体素滤波); (2)ransac算法分割拟合地面平面; (3)裁剪工作区域(指定空间中四个点,裁剪点云只保留…

C++_基础语法

一、关键字 常用语法 #include<iostream>using namespace std;// 全局常量 #define DAY 30void main() {/** 变量与输出*/// 局部常量const int year 2023;// 控制台输出cout << "hello world" << endl;cout << "天&#xff1a;"…

国庆加速度!新增功能点锁定功能,敏捷开发新增估算功能,助力项目快速突破!

大家好&#xff0c;CoCode开发云旗下Co-Project V3.6智能项目管理平台正式发布&#xff0c;平台新增功能点锁定功能、敏捷开发模式新增估算板块和两种估算方式。 功能点锁定功能进一步提高了项目估算的灵活性和准确性&#xff0c;有利于提高项目估算效率&#xff1b;而敏捷开发…

Unity2023打包首包从78Mb到3.0Mb-震惊-我做对了什么

&#xff08;全程并没有使用AssetBundle , 历史原因&#xff0c;Resources目录还有不少资源残留&#xff09; 曾经的我在2019打包过最小包10m左右&#xff0c;后来发现到了Unity2020之后暴增到40m&#xff0c;又加上2023版本URP&#xff0c;1个Unity输出包可能至少55M 如下图…

Ubuntu基于Docker快速配置GDAL的Python、C++环境

本文介绍在Linux的Ubuntu操作系统中&#xff0c;基于Docker快速配置Python、C等不同编程语言均可用的地理数据处理库GDAL的方法。 首先&#xff0c;我们访问GDAL库的Docker镜像官方网站&#xff08;https://github.com/OSGeo/gdal/tree/master/docker&#xff09;。其中&#x…

Abstract Factory 抽象工厂模式简介与 C# 示例【创建型】

〇、简介 1、什么是抽象工厂模式&#xff1f; 一句话解释&#xff1a; 提供一个接口&#xff0c;以创建一系列相关或相互依赖的抽象对象&#xff0c;而无需指定它们具体的类。&#xff08;将一系列抽象类装进接口&#xff0c;一次接口实现&#xff0c;就必须实例化这一系列抽象…

如何在Ubuntu中切换root用户和普通用户

问题 大家在新装Ubuntu之后&#xff0c;有没有发现自己进入不了root用户&#xff0c;su root后输入密码根本进入不了&#xff0c;这怎么回事呢&#xff1f; 打开Ubuntu命令终端&#xff1b; 输入命令&#xff1a;su root&#xff1b; 回车提示输入密码&#xff1b; 提示&…

[ubuntu]ubuntu设置虚拟内存

首先查看自己是否加过虚拟内存或者查看虚拟内存当前状态可以命令&#xff1a; free -mh 创建交换分区&#xff1a; sudo mkdir /swap cd /swap sudo dd if/dev/zero ofswapfile bs1024 count12582912 其中count是自己分配内存大小&#xff0c;上面为12GB&#xff0c;你可…

视频异常检测:Human Kinematics-inspired Skeleton-based Video Anomaly Detection

论文作者&#xff1a;Jian Xiao,Tianyuan Liu,Genlin Ji 作者单位&#xff1a;Nanjing Normal University;The Hong Kong Polytechnic University 论文链接&#xff1a;http://arxiv.org/abs/2309.15662v1 内容简介&#xff1a; 1&#xff09;方向&#xff1a;视频异常检测…

Opengl之混合

OpenGL中,混合(Blending)通常是实现物体透明度(Transparency)的一种技术。透明就是说一个物体(或者其中的一部分)不是纯色(Solid Color)的,它的颜色是物体本身的颜色和它背后其它物体的颜色的不同强度结合。一个有色玻璃窗是一个透明的物体,玻璃有它自己的颜色,但它最终的…

rtp流广播吸顶喇叭网络有源吸顶喇叭

SIP-7043 rtp流广播吸顶喇叭网络有源吸顶喇叭 一、描述 SIP-7043是我司的一款SIP网络有源吸顶喇叭&#xff0c;具有10/100M以太网接口&#xff0c;内置有一个高品质扬声器&#xff0c;将网络音源通过自带的功放和喇叭输出播放&#xff0c;可达到功率20W。SIP-7043作为SIP系统的…

【分布式云储存】Springboot微服务接入MinIO实现文件服务

文章目录 前言技术回顾准备工作申请accessKey\secretKey创建数据存储桶公共资源直接访问测试 接入springboot实现文件服务依赖引入配置文件MinIO配置MinIO工具类 OkHttpSSLSocketClient兼容ssl静态资源预览解决方案资源上传预览测试测试结果 前言 上篇博客我们介绍了分布式云存…