Primjer 2 - animacija

Rezultat

U ovom primjeru je korištena biblioteka webgl-utils, koja primjerice pomaže kod pokretanja zahtjeva za ponovno iscrtavanje kod animacija iz razloga što za različite preglednike ista funkcija ima različite nazive, pa nam biblioteka olakšava rad.

U ovom primjeru se koristi animacija prethodno nacrtanog kvadrata. Za to su nam potrebne neke nove metode. Metodu tick() pozivamo u metodi webGLStart() umjesto drawScene() metode.

              function tick() {
                requestAnimFrame(tick); // metoda iz biblioteke webgl-utils
                drawScene();
                animate();
              }
            

Promjene u programskom kodu

Pogledajmo sada promjene u metodi drawScene() u odnosu na prošli primjer. Prije same metode se inicijalizira globalna varijabla "kut" koja nam služi za rotiranje kvadrata.

              var kut = 0;
              function drawScene() {
                gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
                gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
                mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);

                mat4.identity(mvMatrix);
                mat4.translate(mvMatrix, [0.0, 0.0, -8.0]);

                mvPushMatrix();   // zapamtimo trenutnu matricu transformacije
                // rotacija oko x osi za kut
                mat4.rotate(mvMatrix, degToRad(kut), [1, 0, 0]);

                gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
                gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);

                setMatrixUniforms();
                gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems);

                mvPopMatrix();  // vratimo se na prethodnu matricu transformacije
              }
            

Naravno, potrebna je i metoda koja će kontrolirati kut za koji se rotira nacrtani kvadrat.

              var lastTime = 0;
              function animate() {
                var timeNow = new Date().getTime();
                if (lastTime != 0) {
                  var elapsed = timeNow - lastTime;

                  kut += (75 * elapsed) / 1000.0; // kvadrat će se rotirati 75 stupnjeva po sekundi
                }
                lastTime = timeNow;
              }
            

To je cijeli kod koji u stvarnosti animira i iscrtava scenu. No, potrebno je i kreirati metode koje će upravljati stogom matrica transformacija.

              var mvMatrix = mat4.create();
              var mvMatrixStack = [];
              var pMatrix = mat4.create();

              function mvPushMatrix() {
                var copy = mat4.create();
                mat4.set(mvMatrix, copy);
                mvMatrixStack.push(copy);
              }

              function mvPopMatrix() {
                if (mvMatrixStack.length == 0) {
                  throw "Invalid popMatrix!";
                }
                mvMatrix = mvMatrixStack.pop();
              }
            

Dodatno, korištena je metoda degToRad() koja stupnjeve pretvara u radijane, a kod te metode je prikazan u nastavku.

              function degToRad(degrees) {
                return degrees * Math.PI / 180;
              }