当前位置: 首页 > article >正文

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

相关文章:

  • 响应式网页设计--html
  • 性能测试|JMeter接口与性能测试项目
  • C获取程序名称的方法
  • 利用阿里云下载 WebRTC 源码
  • 不对称信息
  • 《MYSQL45讲》kill不掉的线程
  • GooglePlay马甲包过审详细流程
  • Java基础(六)面向对象编程(进阶)
  • 2023-04-14 算法面试中常见的查找表问题
  • Available-Python-Tuf
  • ChatGPT大规模封号+停止注册?最火概念会凉吗?
  • 【Camera HW介绍】
  • AI绘画——Stable Diffusion模型,变分自编码器(VAE)模型 , lora模型——调配设置与分享
  • shell的简单信息-执行、变量命名、变量的数据类型
  • git 命令:工作日常使用
  • 基于CBC、ECB、CTR、OCF、CFB模式的AES加密算法
  • 洛谷 P1341 无序字母对
  • Monitor方案MT9800学习笔记(三) —— 点屏(V-by-One信号接口)
  • MybatisPlus <= 3.5.3.1 TenantPlugin 组件 存在 sql 注入漏洞(CVE-2023-25330)
  • 测试:腾讯云轻量4核8G12M服务器CPU流量带宽系统盘
  • pytorch进阶学习(三):在数据集数量不够时如何进行数据增强
  • 花30分钟,我用ChatGPT写了一篇2000字文章(内附实操过程)
  • 【LeetCode】剑指 Offer 49. 丑数 p240 -- Java Version
  • JavaScript 基础入门速成上篇
  • GPT、科技、人类的生产、知识与未来(下)
  • IO流复习