webgl-图形非矩阵旋转

知识拓展

由(x1,y1)旋转β角度到(x2,y2)

根据圆极坐标方程

x1 = r*cosα

y1 = r*sinα

可得

x2 =r*cos(α + β)= r*cosα*cosβ - r*sinα*sinβ,因为x1 = r*cosα,y1 = r*sinα,所以x2 = x1*cosβ -y1*sinβ

y2 = r*sin(α + β) = r*sinα*cosβ + r*cosα*sinβ,因为x1 = r*cosα,y1 = r*sinα,所以y2 = y1* cosβ + x1*sinβ

因此

(x1,y1)旋转β角度到(x1*cosβ -y1*sinβ, y1* cosβ + x1*sinβ)

关键代码

//创建顶点资源和像素资源(颜色)

let vertexSource = `

attribute vec2 a_position;

attribute float cosB;

attribute float sinB;

void main() {

  float x1 = a_position.x;

  float y1 = a_position.y;

  float x2 = x1*cosB - y1*sinB;

  float y2 = x1*sinB + y1*cosB;

  gl_Position = vec4(x2, y2, 0.0, 1.0);

  gl_PointSize = 10.0;

}

`

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 float cosB;

attribute float sinB;

void main() {

  float x1 = a_position.x;

  float y1 = a_position.y;

  float x2 = x1*cosB - y1*sinB;

  float y2 = x1*sinB + y1*cosB;

  gl_Position = vec4(x2, y2, 0.0, 1.0);

  gl_PointSize = 10.0;

}

`

let fragmentSource = `

precision mediump float;

void main (){

  gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);

}

`

if (initShader(ctx, vertexSource, fragmentSource)) {

    //画三角形

    let vertexs = [

        //   x     y    R    G    B

        -0.5, 0.0, 1.0, 0.0, 0.0, //第一个点的信息

        0.5, 0.0, 0.0, 1.0, 0.0, //第二个点的信息

        0.0, 0.5, 0.0, 0.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);

    // ctx.drawArrays(ctx.TRIANGLE_FAN, 0, 3)


 

    let angle = 0

    function render(){

        angle++

        let cosB = ctx.getAttribLocation(ctx.program, "cosB")

        let sinB = ctx.getAttribLocation(ctx.program, "sinB")

        ctx.vertexAttrib1f(cosB, Math.cos(angle/180 * Math.PI))

        ctx.vertexAttrib1f(sinB, Math.sin(angle/180 * Math.PI))

        ctx.drawArrays(ctx.TRIANGLE_FAN, 0, 3)

      window.requestAnimationFrame(render)

    }

    render()

}


 

//创建顶点阴影和像素阴影

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

    }

}

效果图

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

GooglePlay马甲包过审详细流程

1. 更改内部的包名 直接选中app/src/main/java下的自定义包名&#xff0c;有可能refactor后还有需要手动调整的地方&#xff0c;编译不过时可以定位。 2. 打包时修改Manifest文件、保证每个包的manifest都不一样 备选工具&#xff1a;https://github.com/king-ma1993/Andro…

Java基础(六)面向对象编程(进阶)

1 关键字&#xff1a;this 1.1 this是什么&#xff1f; 在Java中&#xff0c;this关键字不算难理解&#xff0c;它的作用和其词义很接近。 它在方法&#xff08;准确的说是实例方法或非static的方法&#xff09;内部使用&#xff0c;表示调用该方法的对象它在构造器内部使用&a…

2023-04-14 算法面试中常见的查找表问题

2023-04-14 算法面试中常见的查找表问题 1 Set的使用 LeetCode349号问题&#xff1a;两个数组的交集 给定两个数组&#xff0c;编写一个函数来计算它们的交集。示例 1:输入: nums1 [1,2,2,1], nums2 [2,2] 输出: [2] 示例 2:输入: nums1 [4,9,5], nums2 [9,4,9,8,4] 输出:…

ChatGPT大规模封号+停止注册?最火概念会凉吗?

一、背景 这个周末&#xff0c;先是意大利暂时封杀ChatGPT&#xff0c;限制OpenAI处理本国用户信息。 接着&#xff0c;据韩国媒体报道&#xff0c;三星导入ChatGPT不到20天&#xff0c;便曝出机密资料外泄&#xff08;涉及半导体设备测量资料、产品良率等内容&#xff0c;已…

AI绘画——Stable Diffusion模型,变分自编码器(VAE)模型 , lora模型——调配设置与分享

目录 Stable Diffusion模型 模型调配 模型设置 变分自编码器&#xff08;VAE&#xff09;模型 模型调配 模型设置 lora模型&#xff08;原生&#xff09;&#xff08;插件&#xff09; 模型调配 模型设置 AI生成prompt及模型分享 Stable Diffusion模型 pastel-mix…

git 命令:工作日常使用

git start 存储分支 git start list 查看所有存储 拉取最新master 合并到自己分支&#xff1a; git remote add [远程名称] [远程仓库链接] //关联(添加)远程仓库; 第一步&#xff1a;查看分支在哪里&#xff0c;是自己的吗&#xff0c;添加暂存区&#xff0c;添加到仓…

基于CBC、ECB、CTR、OCF、CFB模式的AES加密算法

1、什么是AES加密算法 什么是加密算法&#xff1f;我在文章《从个人角度看什么是加密算法》中描述了我对加密算法的一些浅薄的理解。我不是信息安全领域的大神&#xff0c;只求有一个入门罢了&#xff01; 这篇文章是文章《从个人角度看什么是加密算法》的延伸&#xff0c;所…

Monitor方案MT9800学习笔记(三) —— 点屏(V-by-One信号接口)

点屏1. 硬件准备1.1 屏1.2 屏线1.3 背光接口2. 软件配置2.1 新增屏驱2.2 屏参配置2.3 点屏3. LVDS信号接口点屏介绍1. 硬件准备 1.1 屏 点屏前&#xff0c;要先确认其参数和功能&#xff0c;再选择匹配的主板。 这里以 Innolux 的 M280DGJ-L30 作为例子说明&#xff0c;先来看…

MybatisPlus <= 3.5.3.1 TenantPlugin 组件 存在 sql 注入漏洞(CVE-2023-25330)

漏洞描述 MyBatis-Plus TenantPlugin 是 MyBatis-Plus 的一个为多租户场景而设计的插件&#xff0c;可以在 SQL 中自动添加租户 ID 来实现数据隔离功能。 MyBatis-Plus TenantPlugin 3.5.3.1及之前版本由于 TenantHandler#getTenantId 方法在构造 SQL 表达式时默认情况下未对…

测试:腾讯云轻量4核8G12M服务器CPU流量带宽系统盘

腾讯云轻量4核8G12M应用服务器带宽&#xff0c;12M公网带宽下载速度峰值可达1536KB/秒&#xff0c;折合1.5M/s&#xff0c;每月2000GB月流量&#xff0c;折合每天66GB&#xff0c;系统盘为180GB SSD盘&#xff0c;地域节点可选上海、广州或北京&#xff0c;4核8G服务器网来详细…

pytorch进阶学习(三):在数据集数量不够时如何进行数据增强

对图片数据增强&#xff0c;可以对图片实现&#xff1a; 1. 尺寸放大缩小 2. 旋转&#xff08;任意角度&#xff0c;如45&#xff0c;90&#xff0c;180&#xff0c;270&#xff09; 3. 翻转&#xff08;水平翻转&#xff0c;垂直翻转&#xff09; 4. 明亮度改变&#xff08;变…

花30分钟,我用ChatGPT写了一篇2000字文章(内附实操过程)

有了ChatGPT之后&#xff0c;于我来说&#xff0c;有两个十分明显的变化&#xff1a; 1. 人变的更懒 因为生活、工作中遇到大大小小的事情&#xff0c;都可以直接找ChatGPT来寻求答案。 2. 工作产出量更大 之前花一天&#xff0c;甚至更久才能写一篇原创内容&#xff0c;现…

【LeetCode】剑指 Offer 49. 丑数 p240 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/chou-shu-lcof/ 1. 题目介绍&#xff08;49. 丑数&#xff09; 我们把只包含质因子 2、3 和 5 的数称作丑数&#xff08;Ugly Number&#xff09;。求按从小到大的顺序的第 n 个丑数。 质因数&#xff1a;质因子&#xff08…

JavaScript 基础入门速成上篇

JavaScript 嵌入页面的方式 1. 行间事件 <button onclick"alert(点击按钮)">按钮</button> 2. script标签 <script type"text/javascript">console.log(Hello javascript !) </script> 3. 外部引入 <script type"t…

IO流复习

目录字符集git pull origin master --allow-unrelated-historiesCTRL ALT T进行整块代码的操作&#xff08;会出现一个选项栏&#xff09;字符集的编码和解码操作IO流字节输入流和字节输出流文件拷贝资源释放的方式字符输入流和字符输出流缓冲流字节缓冲流的性能分析字符缓冲流…

算法题:图的表示形式与遍历框架

图的基本概念 在数据结构和算法上&#xff0c;图的数据表示一般使用邻接表和邻接矩阵的形式。 比如&#xff1a; 邻接表和邻接矩阵存储如下。邻接表是用vector[vector[i]] 存储每个节点指向的节点&#xff0c;邻接矩阵是用一个二维矩阵matrix[i][j]表示&#xff0c;如果第数据…

小米手机root后过软件检测

工具&#xff1a; https://wwp.lanzouf.com/b0cybm3ib 密码: 9hn8 视频讲解&#xff1a;隐藏root终极教程&#xff08;2022年&#xff09; 演示机型&#xff1a;小米10&#xff0c;安卓14&#xff0c;MIUI14.0.2 问题描述 安装magisk后使用病毒扫描发现支付环…

Flink (十) --------- 容错机制

目录一、 检查点&#xff08;Checkpoint&#xff09;1. 检查点的保存2. 从检查点恢复状态3. 检查点算法4. 检查点配置5. 保存点&#xff08;Savepoint&#xff09;二、状态一致性1. 一致性的概念和级别2. 端到端的状态一致性三、端到端精确一次&#xff08;end-to-end exactly-…

ActiveMQ使用(二):在JavaScript中使用mqtt.js

ActiveMQ使用(二):在JavaScript中使用mqtt.js 1. 环境准备 jQuery-1.10 下载地址:https://www.jsdelivr.com/package/npm/jquery-1.10.2?tabfilesmqtt.js 4.3.7: 下载地址:https://www.jsdelivr.com/package/npm/mqtt 2. 相关代码 <!DOCTYPE html> <html lang&q…

和开振学Spring boot 3.0之Spring MVC:④获取参数(上)

之前&#xff0c;我反复说过处理器封装了控制器&#xff0c;HandlerMapping的机制找到处理器后&#xff0c;通过处理器就能运行控制器&#xff0c;那么处理器增强了控制器什么功能呢&#xff1f; 我们用脑子想一下&#xff0c;要运行控制器之前&#xff0c;我们需要做什么&…
最新文章