《WebGL編程指南》學(xué)習(xí)筆記18——?jiǎng)赢嫛切涡D(zhuǎn)

本系列僅作為本人學(xué)習(xí)《WebGL編程指南》這本書的筆記所用

image.jpeg

動(dòng)畫基礎(chǔ):轉(zhuǎn)動(dòng)的三角形 = 不斷擦除和重繪三角形扯键,每次重繪時(shí)改動(dòng)角度
requestAnimationFrame()
是瀏覽器用于定時(shí)循環(huán)操作的一個(gè)接口,類似于setTimeout投慈,主要用途是按幀對(duì)網(wǎng)頁(yè)進(jìn)行重繪。參數(shù)為要循環(huán)的回調(diào)函數(shù)裕寨,在瀏覽器重繪前調(diào)用撒妈。
優(yōu)勢(shì):充分利用顯示器的刷新機(jī)制,刷新頻率保持同步运褪,比較節(jié)省系統(tǒng)資源惊楼,一旦頁(yè)面不處于瀏覽器的當(dāng)前標(biāo)簽玖瘸,就會(huì)自動(dòng)停止刷新。
缺點(diǎn):不能修改刷新頻率檀咙,且是在主線程上完成雅倒,若主線程繁忙會(huì)使其效果打折扣。


webgl-動(dòng)畫.gif
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>16繪制三角形-動(dòng)畫-旋轉(zhuǎn)</title>

    <script src="./lib/cuon-matrix.js"></script>
    <script src="./lib/cuon-utils.js"></script>
    <script src="./lib/webgl-debug.js"></script>
    <script src="./lib/webgl-utils.js"></script>
  </head>
  <body onload="main()">
    <canvas id="webgl" width="400" height="400">
      不支持canvas的瀏覽器會(huì)展示這段文字
    </canvas>

    <script>
      // 頂點(diǎn)著色器程序
      let VSHADER_SOURCE = `
        attribute vec4 a_Position;
        uniform mat4 u_ModeMatrix;
        void main() {
        gl_Position = u_ModeMatrix * a_Position;
        }
    `;

      // 片元著色器程序
      let FSHADER_SOURCE = `
        void main() {
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
        }
    `;
      // 旋轉(zhuǎn)速度(度/秒)
      let ANGLE_STEP = 45.0;
      // 主程序
      function main() {
        let canvas = document.getElementById("webgl");

        // 獲取WebGL繪圖上下文
        let gl = getWebGLContext(canvas);
        if (!gl) {
          console.error("無(wú)法使用WebGL");
          return;
        }

        // 初始化著色器
        if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
          console.error("無(wú)法使用著色器");
          return;
        }

        // 設(shè)置頂點(diǎn)坐標(biāo)
        let nLength = initVertexBuffers(gl);
        if (nLength < 0) {
          console.log("無(wú)法設(shè)置點(diǎn)的位置");
          return;
        }
        // ===============
        // 設(shè)置<canvas> 背景色弧可,在繪制圖形前設(shè)置背景色蔑匣,當(dāng)清除和重繪時(shí)一直有效
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        // 三角形當(dāng)前旋轉(zhuǎn)角度
        let currentAngle = 0.0;
        // 創(chuàng)建Matrix4對(duì)象以進(jìn)行模型變換
        let modelMatrix = new Matrix4();
        // 將旋轉(zhuǎn)矩陣傳輸給頂點(diǎn)著色器
        let u_ModeMatrix = gl.getUniformLocation(gl.program, "u_ModeMatrix");
        // =============
        // =============
        // 開(kāi)始繪制三角形
        let tick = function () {
          currentAngle = animate(currentAngle); // 更新旋轉(zhuǎn)角
          draw(gl, nLength, currentAngle, modelMatrix, u_ModeMatrix);
          requestAnimationFrame(tick); // 請(qǐng)求瀏覽器調(diào)用tick
        };
        tick();
        // =============
      }
      function initVertexBuffers(gl) {
        // 類型化數(shù)組, 用于儲(chǔ)存頂點(diǎn)的坐標(biāo)或顏色。比Array性能更高棕诵,不支持push(),和pop()
        let vertices = new Float32Array([0.0, 0.5, -0.5, -0.5, 0.5, -0.5]); // 坐標(biāo) x1,y1,x2,y2,x3,y3
        let n = 3; // 點(diǎn)的個(gè)數(shù)

        // 1.創(chuàng)建緩沖區(qū)對(duì)象
        let vertexBuffer = gl.createBuffer();
        if (!vertexBuffer) {
          console.log("不能創(chuàng)建緩沖區(qū)對(duì)象");
          return -1;
        }

        // 2.將緩沖區(qū)對(duì)象綁定到目標(biāo)
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);

        // 3.向緩沖區(qū)對(duì)象寫入數(shù)據(jù),不能直接向緩沖區(qū)寫入數(shù)據(jù)裁良,只能向綁定的目標(biāo)輸入數(shù)據(jù)
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

        // 獲取a_Position變量的存儲(chǔ)位置
        let a_Position = gl.getAttribLocation(gl.program, "a_Position");
        if (a_Position < 0) {
          console.log("無(wú)法獲取 a_Position");
          return -1;
        }
        // 4.將緩沖區(qū)對(duì)象分配給attribute變量--所有點(diǎn)數(shù)據(jù)一次性傳入
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);

        // 5.連接a_Position變量與分配給它的緩沖區(qū)對(duì)象,開(kāi)啟attribute變量
        gl.enableVertexAttribArray(a_Position);

        return n; // 返回待繪制頂點(diǎn)的數(shù)量, 函數(shù)內(nèi)部發(fā)生錯(cuò)誤后返回-1
      }
      // =============
      function draw(gl, nLength, currentAngle, modelMatrix, u_ModeMatrix) {
        // 設(shè)置旋轉(zhuǎn)矩陣
        modelMatrix.setRotate(currentAngle, 0, 0, 1);
        // 將旋轉(zhuǎn)矩陣傳輸給頂點(diǎn)著色器
        gl.uniformMatrix4fv(u_ModeMatrix, false, modelMatrix.elements);
        // 清除<canvas>
        gl.clear(gl.COLOR_BUFFER_BIT);

        // 繪制三角形
        gl.drawArrays(gl.TRIANGLES, 0, nLength); // nLength為n個(gè)點(diǎn)
      }
      // 記錄上一次調(diào)用函數(shù)的時(shí)刻
      let g_last = Date.now();
      function animate(angle) {
        // 計(jì)算距離上次調(diào)用經(jīng)過(guò)多少時(shí)間
        let now = Date.now();
        let elapsed = now - g_last; // 毫秒
        g_last = now;
        // 根據(jù)距離上次調(diào)用的時(shí)間校套,更新當(dāng)前旋轉(zhuǎn)角度
        let newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0;
        return (newAngle %= 360);
      }
      // =============
    </script>
  </body>
</html>

未完待續(xù)价脾。。笛匙。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末侨把,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子妹孙,更是在濱河造成了極大的恐慌秋柄,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涕蜂,死亡現(xiàn)場(chǎng)離奇詭異华匾,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)机隙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門蜘拉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人有鹿,你說(shuō)我怎么就攤上這事旭旭。” “怎么了葱跋?”我有些...
    開(kāi)封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵持寄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我娱俺,道長(zhǎng)稍味,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任荠卷,我火速辦了婚禮模庐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘油宜。我一直安慰自己掂碱,他們只是感情好怜姿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著疼燥,像睡著了一般沧卢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上醉者,一...
    開(kāi)封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天但狭,我揣著相機(jī)與錄音,去河邊找鬼湃交。 笑死熟空,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的搞莺。 我是一名探鬼主播息罗,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼才沧!你這毒婦竟也來(lái)了迈喉?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤温圆,失蹤者是張志新(化名)和其女友劉穎挨摸,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體岁歉,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡得运,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了锅移。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片熔掺。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖非剃,靈堂內(nèi)的尸體忽然破棺而出置逻,到底是詐尸還是另有隱情,我是刑警寧澤备绽,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布券坞,位于F島的核電站,受9級(jí)特大地震影響肺素,放射性物質(zhì)發(fā)生泄漏恨锚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一倍靡、第九天 我趴在偏房一處隱蔽的房頂上張望眠冈。 院中可真熱鬧,春花似錦、人聲如沸蜗顽。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)雇盖。三九已至,卻和暖如春栖忠,著一層夾襖步出監(jiān)牢的瞬間崔挖,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工庵寞, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狸相,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓捐川,卻偏偏與公主長(zhǎng)得像脓鹃,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子古沥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容