webgl-画任意多边形
注意:
let canvas = document.getElementById('webgl')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
let radio = window.innerWidth/window.innerHeight;
let ctx = canvas.getContext('webgl')

由于屏幕长宽像素不一样,导致了长宽像素比不是1,进而导致每个像素四边形不是正方形,画出来的图形有误差
需要let radio = window.innerWidth/window.innerHeight;计算
关键代码
for (let index = 0; index < n; index++) {
let angle = Math.PI*2/n * index;
let x = 0.5 * Math.cos(angle)/radio //解决像素比不是1的问题,导致画出的图形与预期不一致,如画圆可能画出来的时椭圆
let y = 0.5 * Math.sin(angle)
vertexs.push(x, y, (Math.random() -0.5) * 2, (Math.random() -0.5) * 2, (Math.random() -0.5) * 2)
}
控制多边形
let n = 3;
html
<!DOCTYPE html>
<head>
<style>
*{
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas id = 'webgl'>
您的浏览器不支持HTML5,请更换浏览器
</canvas>
<script src="./main.js"></script>
</body>
main.js
let canvas = document.getElementById('webgl')
canvas.width = window.innerWidth
canvas.height = window.innerHeight
let radio = window.innerWidth/window.innerHeight;
let ctx = canvas.getContext('webgl')
//创建顶点资源和像素资源(颜色)
let vertexSource = `
attribute vec2 a_Position;
attribute vec3 a_Position_color;
varying vec3 a_color;
void main() {
a_color = a_Position_color;
gl_Position = vec4(a_Position, 0.0, 1.0);
gl_PointSize = 10.0;
}
`
let fragmentSource = `
precision mediump float;
uniform vec3 u_color;
varying vec3 a_color;
void main (){
gl_FragColor = vec4(a_color, 1.0);
}
`
if (initShader(ctx, vertexSource, fragmentSource)) {
//设置颜色
let color = ctx.getUniformLocation(ctx.program, "u_color2")
ctx.uniform3f(color, 1.0, 0.0, 0.0)
//画三角形
let vertexs = []
let n = 3;
for (let index = 0; index < n; index++) {
let angle = Math.PI*2/n * index;
let x = 0.5 * Math.cos(angle)/radio
let y = 0.5 * Math.sin(angle)
vertexs.push(x, y, (Math.random() -0.5) * 2, (Math.random() -0.5) * 2, (Math.random() -0.5) * 2)
}
// //画三角形
// let vertexs = [
// // x y R G B
// -0.5, 0.5, 1.0, 0.0, 0.0, //第一个点的信息
// -0.5, -0.5, 0.0, 1.0, 0.0, //第二个点的信息
// 0.5, -0.5, 0.0, 0.0, 1.0,//第三个点的信息
// 0.5, 0.5, 1.0, 1.0, 1.0 //第三个点的信息
// ]
let float32Array = new Float32Array(vertexs)
//创建buffer
let buffer = ctx.createBuffer()
//绑定buffer
ctx.bindBuffer(ctx.ARRAY_BUFFER, buffer)
//往buffer中填充值,并指定数据用途
ctx.bufferData(ctx.ARRAY_BUFFER, float32Array, ctx.STATIC_DRAW)
//获取vertexShader指定变量内存
let a_Position = ctx.getAttribLocation(ctx.program, "a_Position")
//指定每两个数组元素为一个点
/*
* 当数组元素不需进行分割拆分的时候最后两位可以指定为0,0
*
*
*/
ctx.vertexAttribPointer(
a_Position, //location: vertex Shader里面的attributes变量的location
2, ctx.FLOAT, //size: attribute变量的长度 vec2长度2 vec3长度3
false, //normalized: 正交化 true或false , [1, 2] => [1/根号5, 2/根号5]
5 * float32Array.BYTES_PER_ELEMENT, //stride: 每个点的信息所占的BYTES
0 //offset: 每个点的信息,从第几个BYTES开始数
)
ctx.enableVertexAttribArray(a_Position);
//获取vertexShader指定变量内存
let a_Position_color = ctx.getAttribLocation(ctx.program, "a_Position_color")
ctx.vertexAttribPointer(
a_Position_color, //location: vertex Shader里面的attributes变量的location
3, ctx.FLOAT, //size: attribute变量的长度 vec2长度2 vec3长度3
false, //normalized: 正交化 true或false , [1, 2] => [1/根号5, 2/根号5]
5 * float32Array.BYTES_PER_ELEMENT, //stride: 每个点的信息所占的BYTES
2 * float32Array.BYTES_PER_ELEMENT //offset: 每个点的信息,从第几个BYTES开始数
)
//确认吧带有数据的buffer赋值给a_Position
ctx.enableVertexAttribArray(a_Position_color);
ctx.drawArrays(ctx.TRIANGLE_FAN, 0, n)
}
//创建顶点阴影和像素阴影
function createShader(ctx, type, source) {
//创建shader
let shader = ctx.createShader(type)
//绑定
ctx.shaderSource(shader, source)
//编译shader
ctx.compileShader(shader)
//获取编译结果
let compiler = ctx.getShaderParameter(shader, ctx.COMPILE_STATUS)
if (compiler) {
return shader
} else {
let log = ctx.getShaderInfoLog(shader)
console.log("compile shaders error", log)
//删除异常的shader,防止内存泄露
ctx.deleteShader(shader)
return null
}
}
function createProgram(ctx, vertexShader, fragmentShader) {
//创建program
let program = ctx.createProgram()
if (!program) {
return null
}
//点资源和像素资源合并
ctx.attachShader(program, vertexShader)
ctx.attachShader(program, fragmentShader)
ctx.linkProgram(program)
//获取linked的结果
let linked = ctx.getProgramParameter(program, ctx.LINK_STATUS)
if (linked) {
return program
} else {
//获取link错误信息
let log = ctx.getProgramInfoLog(program)
console.log("link program error", log)
//删除防止内存泄漏
ctx.delete(program)
ctx.deleteShader(vertexShader)
ctx.deleteShader(fragmentShader)
return null
}
}
function initShader(ctx, vertexSource, fragmentSource) {
let vertexShader = createShader(ctx, ctx.VERTEX_SHADER, vertexSource)
let fragmentShader = createShader(ctx, ctx.FRAGMENT_SHADER, fragmentSource)
let program = createProgram(ctx, vertexShader, fragmentShader)
if (program) {
ctx.useProgram(program)
//挂载到ctx
ctx.program = program
return true
} else {
return false
}
}
效果
n=3

n=4

n=6
n=50

相关文章:
webgl-画任意多边形
注意: let canvas document.getElementById(webgl) canvas.width window.innerWidth canvas.height window.innerHeight let radio window.innerWidth/window.innerHeight; let ctx canvas.getContext(webgl) 由于屏幕长宽像素不一样,导致了长宽像素…...
代码随想录打卡第51天|309.最佳买卖股票时机含冷冻期;714.买卖股票的最佳时机含手续费
309.最佳买卖股票时机含冷冻期 关键点1:dp数组的含义 1-1:dp[i][0] 第i天持有股票的最大金钱 1-2:dp[i][1] 第i天卖出股票的最大金钱 1-3:dp[i][2] 第i天处于冷冻期的最大金钱 1-4:dp[i][3] 第i天保持卖出股票的最大金…...
Spark Shuffle介绍
文章目录1. 简介2. Hash Shuffle和Sort Shuffle2.1 Hash Shuffle2.1.1 未经优化的hashShuffleManager2.1.2 经优化的hashShuffleManager2.1.3 优化前后磁盘文件数对比2.2 Srot Shuffle Manager3. Shuffle配置选项1. 简介 Spark在DAG调度阶段会将一个Job划分为多个Stage&#x…...
【数据库原理 • 三】关系数据库标准语言SQL
前言 数据库技术是计算机科学技术中发展最快,应用最广的技术之一,它是专门研究如何科学的组织和存储数据,如何高效地获取和处理数据的技术。它已成为各行各业存储数据、管理信息、共享资源和决策支持的最先进,最常用的技术。 当前…...
ThreeJS-战争导弹飞行演示(三十四)
关键代码: function animate() { requestAnimationFrame(animate); // 使用渲染器渲染相机看这个场景的内容渲染出来 renderer.render(scene, camera); // controls.update(); // 获取delay时间 const delay clock.getDelta(); // 获取总共耗时 const time clock.…...
代码随想录_226翻转二叉树、101对称二叉树
leetcode 226. 翻转二叉树 226. 翻转二叉树 给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]示例 2: 输入:r…...
Docker 容器日志查看
1、容器日志查看命令 Usage: docker logs [OPTIONS] CONTAINERFetch the logs of a containerOptions:--details Show extra details provided to logs-f, --follow Follow log output--since string Show logs since timestamp (e.g. 2013-01-02T13:23:37Z…...
【Maven】1—Maven概述下载配置
⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记链接👉https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以,麻烦各位看官顺手点个star~😊 如果文章对你有所帮助,可以点赞👍…...
【Spark】RDD缓存机制
1. RDD缓存机制是什么? 把RDD的数据缓存起来,其他job可以从缓存中获取RDD数据而无需重复加工。 2. 如何对RDD进行缓存? 有两种方式,分别调用RDD的两个方法:persist 或 cache。 注意:调用这两个方法后并不…...
学成在线:第六天(p94-p102)
1、面试:为什么要用 Freemarker 静态化?如何做的? 页面静态化是指使用模板引擎技术将一个动态网页生成 html 静态页面。 满足下边的条件可以考虑使用静态化: 1、该页面被访问频率高,比如:商品信息展示、专家介绍页面等…...
读懂AUTOSAR:PduR模块--使用FIFO
简介: 现在的汽车越来越智能化和复杂化,这得益于汽车软件和电子控制系统的发展。为了帮助汽车制造商和供应商更好地开发和管理汽车软件,全球性的汽车软件开发标准——AUTOSAR(AUTomotive Open System ARchitecture)应…...
对象的比较(数据结构系列12)
目录 前言: 1.PriorityQueue 1.1PriorityQueue的特性 1.2PriorityQueue的构造器 1.3大根堆的创建 1.4PriorityQueue中函数的说明 2.java中对象的比较 2.1基本类型的比较 2.2对象的比较 2.2.1覆写基类的equals 2.2.2基于Comparable接口类的比较 2.2.3基于…...
31.下一个排列
1. 题目 整数数组的一个 排列 就是将其所有成员以序列或线性顺序排列。 例如,arr [1,2,3] ,以下这些都可以视作 arr 的排列:[1,2,3]、[1,3,2]、[3,1,2]、[2,3,1] 。 整数数组的 下一个排列 是指其整数的下一个字典序更大的排列。更正式地&…...
ToBeWritten之理解嵌入式Web HTTP协议
也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 转移发布平台通知:将不再在CSDN博客发布新文章,敬…...
顶级程序员的成长之路1
本文关注的问题是程序员的水平究竟应该按照什么样的不同层级而逐渐提高?或者说,在学习编程的过程中,每一个阶段究竟应当设定什么样的目标才比较合理?本文的内容主要借鉴了周伟明先生的专栏文章《程序员的十层楼》[86]。注意本文讨…...
第三代api自动化测试框架使用教程(pytest+allure+sql+yaml)
使用教程一、配置1、环境配置2、框架配置3、启动入口二、用例编写1、用例模板2、参数依赖写法2、函数(方法插件)写法3、接口上传文件和表单参数4、接口上传json参数5、接口无数据填写6、code断言7、body断言7、json断言8、sql断言9、完整断言写法&#x…...
Qt——实现一个获取本机网络信息的界面
效果展现 代码实现 networkinformation.h: #ifndef NETWORKINFORMATION_H #define NETWORKINFORMATION_H#include <QMainWindow> #include <QLabel> #include <QLineEdit> #include <QPushButton>class NetworkInformation : public QMai…...
全面深入了解接口自动化,看完还不会我报地址
一、自动化分类 (1)接口自动化 python/javarequestsunittest框架来实现 python/javaRF(RobotFramework)框架来实现——对于编程要求不高 (2)Web UI功能自动化 python/javaseleniumunittestddtPO框架来实…...
Python 小型项目大全 61~65
六十一、ROT13 密码 原文:http://inventwithpython.com/bigbookpython/project61.html ROT13 密码是最简单的加密算法之一,代表“旋转 13 个空格”密码将字母A到Z表示为数字 0 到 25,加密后的字母距离明文字母 13 个空格: A变成N&…...
Hlog
Hlog 简介 Hlog是Hbase实现WAL(Write ahead log )方式产生的日志信息 , 内部是一个简单的顺序日志。每个RegionServer对应1个Hlog(备注:1.X版本的可以开启MultiWAL功能,允许对应多个Hlog),所有对于该RegionServer的写入都会被记录到Hlog中。H…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
