[IG]WebGL旋转正方形


注明
该代码源于Interactive Computer Graphics
Edward Angel and Dave Shreiner
Eighth Edition, Pearson Education, 2020

为更好理解此代码,仅添加部分注释


WebGL 旋转正方形


在这里插入图片描述


大概思路

HTML文件中,正方形在平面上旋转,就相当于是在空间中绕Z轴旋转,那么,x和y坐标的变化可以根据 绕Z轴旋转的计算公式得出:

x n e w = − s i n θ ∗ y o l d + c o s θ ∗ x o l d x_{new} = -sin \theta * y_{old}+cos \theta * x_{old} xnew=sinθyold+cosθxold

y n e w = s i n θ ∗ x o l d + c o s θ ∗ y o l d y_{new} = sin \theta * x_{old}+cos \theta * y_{old} ynew=sinθxold+cosθyold

由上式就可以通过更新旋转角度 θ \theta θ 更新正方形的 x , y 坐标

然后在JS文件中定义好正方形初始四个顶点的坐标,通过 gl.getUniformLocation(program, “uTheta”) 函数获取html文件中 uTheta的位置,再通过 gl.uniform1f(thetaLoc, theta) 将持续改变的theta值赋值给 uTheta, 最后用 requestAnimationFrame(render) 持续进行渲染动画!


HTML文件

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>Rotating Square</title>



<script id="vertex-shader" type="x-shader/x-vertex">
    #version 300 es

    in vec4 aPosition;
    uniform float uTheta;   //uniform传输的是对所有顶点都相同或者与顶点无关的数据,向片元着色器中传递数据

    void
    main()
    {
    float s = sin(uTheta);  //返回sin结果
    float c = cos(uTheta);

    gl_Position.x = -s*aPosition.y + c*aPosition.x;
    gl_Position.y =  s*aPosition.x + c*aPosition.y;
    gl_Position.z = 0.0;
    gl_Position.w = 1.0;
    }
</script>

<script id="fragment-shader" type="x-shader/x-fragment">
#version 300 es
precision mediump float;

out vec4 fColor;

void
main()
{
    fColor = vec4(1.0, 0.0, 0.0, 1.0);
}
</script>

<script type="text/javascript" src="../Common/initShaders.js"></script>
<script type="text/javascript" src="../Common/MVnew.js"></script>
<script type="text/javascript" src="rotatingSquare1.js"></script>
</head>

<body>
<canvas id="gl-canvas" width="512" height="512">
Oops ... your browser doesn't support the HTML5 canvas element
</canvas>
</body>
</html>

JavaScript文件

"use strict";

var canvas;
var gl;

var theta = 0.0;
var thetaLoc;

window.onload = function init()
{
    canvas = document.getElementById( "gl-canvas" );

    gl = canvas.getContext('webgl2');
    if (!gl) alert( "WebGL 2.0 isn't available" );


    //
    //  Configure WebGL
    //
    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clearColor(1.0, 1.0, 1.0, 1.0);

    //  Load shaders and initialize attribute buffers
    var program = initShaders(gl, "vertex-shader", "fragment-shader");
    gl.useProgram(program);

    //定义正方形四个角坐标
    var vertices = [
        vec2(0, 1),
        vec2(-1, 0),
        vec2(1, 0),
        vec2(0, -1)
    ];


    // Load the data into the GPU

    var bufferId = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, bufferId);
    gl.bufferData(gl.ARRAY_BUFFER, flatten(vertices), gl.STATIC_DRAW);

    // Associate out shader variables with our data bufferData

    var positionLoc = gl.getAttribLocation(program, "aPosition");
    gl.vertexAttribPointer(positionLoc, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(positionLoc);

    thetaLoc = gl.getUniformLocation(program, "uTheta");    //返回指定的uniform变量uTheta的位置

    render();
};


function render() {

    gl.clear(gl.COLOR_BUFFER_BIT);

    theta += 0.1;
    gl.uniform1f(thetaLoc, theta);  //用于旋转,将新的theta值通过thetaLoc赋值给uTheta,这样这函数大概就是重复持续改变坐标?然后达到旋转的效果

    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

    requestAnimationFrame(render);  //告诉浏览器你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是土豆大叔啊!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值