webgl-画任意多边形

news2024/10/5 23:28:07

注意:

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

 

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

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

相关文章

移远云服务QuecCloud正式发布,一站式为全球客户提供创新有效的解决方案

4月12日&#xff0c;在“万物智联共数未来”移远通信物联网生态大会上&#xff0c;移远通信宣布正式推出其物联网云服务——QuecCloud。QuecCloud具备智能硬件开发、物联网开放平台、行业解决方案三大能力&#xff0c;可为开发者和企业用户提供从硬件接入到软件应用的全流程解决…

Java 进阶(5) Java IO流

⼀、File类 概念&#xff1a;代表物理盘符中的⼀个⽂件或者⽂件夹。 常见方法&#xff1a; 方法名 描述 createNewFile() 创建⼀个新文件。 mkdir() 创建⼀个新⽬录。 delete() 删除⽂件或空⽬录。 exists() 判断File对象所对象所代表的对象是否存在。 getAbsolute…

4.2 方差

学习目标&#xff1a; 我认为学习方差需要以下几个步骤&#xff1a; 确定学习目标&#xff1a;在开始学习方差之前&#xff0c;需要明确学习的目标和意义&#xff0c;例如&#xff0c;理解方差的定义、掌握方差的计算方法、了解方差在实际问题中的应用等。 学习相关数学概念&…

宝塔Linux面板安装命令脚本大全(Centos/Ubuntu/Debian/Fedora/Deepin)

宝塔面板Linux服务器操作系统安装命令大全&#xff0c;包括Centos、Alibaba Cloud Linux、Ubuntu、TencentOS Server、Deepin、Debian和Fedora安装脚本&#xff0c;云服务器吧分享宝塔面板Linux服务器系统安装命令大全&#xff1a; 目录 宝塔面板Linux系统安装命令 Centos安…

【Vue】学习笔记-事件处理

事件的基本用法 使用v-on:xxx 或xxx 绑定事件&#xff0c;其中xxx是事件名事件的回调需要配置在methods对象中&#xff0c;最终会在vm上methods中配置的函数&#xff0c;不要用箭头函数&#xff0c;否则this就不是vm了methods中配置的函数&#xff0c;都是被vue所管理的函数。…

Pandas库:从入门到应用(三)——多表连接操作

一 、concat数据连接 1.1、concat()函数参数 pd.concat(objs, axis0, joinouter, ignore indexFalse, keysNone, levelsNone, namesNoneverify integrityFalse, sort False, copyTrue)objs&#xff1a;多个 DataFrame 或者 Series axis&#xff1a;0-行拼接 1-列拼接 join&am…

011:Mapbox GL两种方式隐藏logo和版权,个性化版权的声明

第011个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中用两种方式隐藏logo和版权,并个性化版权的声明 。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共91行)相关API参考:专栏目标示例效果 配置方式…

2023高性价比学生手机选购攻略,预算不多入手这3款超值

学生党在预算不多的情况&#xff0c;想要换颜值高的新手机&#xff0c;应该选什么样的手机才实惠&#xff1f; 手机已经成为生活中的必需品&#xff0c;市场上的手机品牌和型号多种多样&#xff0c;价格逐年攀升&#xff0c;对于预算有限的学生党来说&#xff0c;在保证性能和…

编译原理期末速成笔记

哈喽大家好&#xff0c;又要考试了&#xff0c;在这里分享一下我的两天速成笔记&#xff0c;参考视频为哔站 Deeplei_ 的《编译原理期末速成》。本文仅是知识点总结&#xff0c;至于考试内容待我研究一下&#xff0c;后续我会再发文对考试的各个模块做详细分析&#xff0c;欢迎…

JavaWeb开发 —— Ajax

目录 一、介绍 二、原生Ajax 三、Axios 四、案例分析 一、介绍 ① 概念&#xff1a;Asynchronous JavaScript And XML&#xff0c;异步的JavaScript和XML。 ② 作用&#xff1a; 数据交换&#xff1a;通过Ajax可以给服务器发送请求&#xff0c;并获取服务器响应的数据。…

多元函数的基本概念——“高等数学”

各位CSDN的uu们你们好呀&#xff0c;今天&#xff0c;小雅兰的内容是多元函数的基本概念&#xff0c;下面&#xff0c;让我们一起进入多元函数的世界吧 平面点集 多元函数的概念 多元函数的极限 多元函数的连续性 有界闭区域上多元连续函数的性质 平面点集 第一个是坐标平…

中间表示- 到达定义分析

基本概念 定义&#xff08;def&#xff09;&#xff1a;对变量的赋值 使用&#xff08;use&#xff09;&#xff1a;对变量值的读取 问题&#xff1a;能把上图中的y替换为3吗&#xff1f;如果能&#xff0c;这称之为“常量传播”优化。 该问题等价于&#xff0c;有哪些对变量y…

R730服务器热插拔换磁盘(raid阵列)

r730服务器发现磁盘闪橙等&#xff0c;说明磁盘报警了&#xff0c;这时候我们就要换磁盘了。 由于本服务器磁盘是raid5的阵列磁盘&#xff0c;所以要采用热插拔的方式换磁盘。 这边要注意的是&#xff0c;不能关机的时候&#xff0c;直接来换磁盘。 因为关机换磁盘&#xff0c…

golang指针相关

指针相关的部分实在是没有搞太明白&#xff0c;抽时间来总结下。 1.指针相关基础知识 比如现在有一句话&#xff1a;『谜底666』&#xff0c;这句话在程序中一启动&#xff0c;就要加载到内存中&#xff0c;假如内存地址0x123456&#xff0c;然后我们可以将这句话复制给变量A&…

什么是服务架构?微服务架构的优势又是什么?

文章目录1.1 单体架构1.2 分布式架构1.3 微服务架构1.4 单体架构和分布式架构的区分1.4 服务架构的优劣点1.4.1 单体架构1.4.2 分布式架构1.4.3 微服务架构1.5 总结1.1 单体架构 单体架构&#xff08;Monolithic Architecture&#xff09;是一种传统的软件架构&#xff0c;它将…

算法学习day56

算法学习day561.力扣583. 两个字符串的删除操作1.1 题目描述1.2分析1.3 代码2.力扣72. 编辑距离2.1 题目描述2.2 分析2.3 代码3.参考资料1.力扣583. 两个字符串的删除操作 1.1 题目描述 题目描述&#xff1a; 给定两个单词word1和word2&#xff0c;找到使得word1和word2相同…

探索数据结构之精髓:单链表解密

文章目录1. 前言2. 单链表的特点3. 单链表的基础操作&#x1f351; 接口总览&#x1f351; 初始化操作&#x1f351; 插入操作&#x1f345; 优化操作&#x1f351; 删除操作&#x1f345; 优化操作&#x1f351; 获取元素&#x1f345; 按置查找&#x1f345; 按值查找&#x…

从C出发 20 --- 函数参数深度剖析

我们在编写这个函数的时候参数 n 的值具体是多少&#xff1f; 在编写一个函数的时候参数值是没法确定的&#xff0c;所以将 (int n) 这个参数命名为形参 那么这个参数的值什么时候指定&#xff0c;具体函数调用的时候指定 比如 在main 里面调用 实参用来初始化形参 初始化之…

安装多个版本的Node.js的方法

要在同一台计算机上安装多个版本的Node.js&#xff0c;可以使用以下几种方法&#xff1a; 使用nvm&#xff08;Node Version Manager&#xff09;&#xff1a;nvm是一个用于管理多个Active Node.js版本的工具。您可以使用nvm轻松地在系统中安装、卸载和切换不同版本的Node.js。…

Leetcode每日一题——“消失的数字”

各位CSDN的uu们你们好呀&#xff0c;今天&#xff0c;小雅兰又开新专栏了&#xff0c;以后会在Leetcode上面进行刷题&#xff0c;尽量每天写一道&#xff0c;请大家监督我&#xff01;&#xff01;&#xff01;好啦&#xff0c;让我们进入Leetcode的世界吧 力扣 对于这道题目&a…