WebGL - Ridimensionamento

In questo capitolo, faremo un esempio per dimostrare come modificare la scala di un triangolo utilizzando WebGL.

Ridimensionamento

Il ridimensionamento non è altro che aumentare o diminuire le dimensioni di un oggetto. Ad esempio, se un triangolo ha vertici della dimensione [a, b, c], il triangolo con i vertici [2a, 2b, 2c] sarà il doppio della sua dimensione. Pertanto, per scalare un triangolo, devi moltiplicare ogni vertice con il fattore di scala. Puoi anche scalare un particolare vertice.

Per scalare un triangolo, nel vertex shader del programma, creiamo una matrice uniforme e moltiplichiamo i valori delle coordinate con questa matrice. Successivamente, passiamo una matrice diagonale 4 × 4 con i fattori di scala delle coordinate x, y, z nelle posizioni diagonali (ultima posizione diagonale 1).

Passaggi obbligatori

I seguenti passaggi sono necessari per creare un'applicazione WebGL per scalare un triangolo.

Step 1 − Prepare the Canvas and Get the WebGL Rendering Context

In questo passaggio, otteniamo l'oggetto contesto di rendering WebGL utilizzando getContext().

Step 2 − Define the Geometry and Store it in the Buffer Objects

Dato che stiamo disegnando un triangolo, dobbiamo passare tre vertici del triangolo e memorizzarli nei buffer.

var vertices = [ -0.5,0.5,0.0, -0.5,-0.5,0.0, 0.5,-0.5,0.0, ];

Step 3 − Create and Compile the Shader Programs

In questo passaggio, è necessario scrivere i programmi vertex shader e fragment shader, compilarli e creare un programma combinato collegando questi due programmi.

  • Vertex Shader- Nel vertex shader del programma, definiamo un attributo vettoriale per memorizzare le coordinate 3D. Insieme ad esso, definiamo una matrice uniforme per memorizzare i fattori di scala e, infine, moltiplichiamo questi due valori e lo assegniamo agl_position che mantiene la posizione finale dei vertici.

var vertCode =
   'attribute vec4 coordinates;' +
   'uniform mat4 u_xformMatrix;' +
   'void main(void) {' +
      ' gl_Position = u_xformMatrix * coordinates;' +
   '}';
  • Fragment Shader - Nello shader del frammento, assegniamo semplicemente il colore del frammento al file gl_FragColor variabile.

var fragCode = 'void main(void) {' +' gl_FragColor = vec4(1, 0.5, 0.0, 1);' +'}';

Step 4 − Associate the Shader Programs with the Buffer Objects

In questo passaggio, associamo gli oggetti buffer al programma shader.

Step 5 − Drawing the Required Object

Dato che stiamo disegnando il triangolo usando gli indici, usiamo il drawArrays()metodo. A questo metodo dobbiamo passare il numero di vertici / elementi da considerare. Dato che stiamo disegnando un triangolo, passeremo 3 come parametro.

gl.drawArrays(gl.TRIANGLES, 0, 3);

Esempio: scala un triangolo

L'esempio seguente mostra come scalare un triangolo:

<!doctype html>
<html>
   <body>
      <canvas width = "300" height = "300" id = "my_Canvas"></canvas>

      <script>
         /*=================Creating a canvas=========================*/
         var canvas = document.getElementById('my_Canvas');
         gl = canvas.getContext('experimental-webgl'); 

         /*===========Defining and storing the geometry==============*/
         var vertices =  [
            -0.5,0.5,0.0, 	
            -0.5,-0.5,0.0, 	
            0.5,-0.5,0.0,   
         ];

         //Create an empty buffer object and store vertex data

         var vertex_buffer = gl.createBuffer();                                                     
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);                                                
         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);           
         gl.bindBuffer(gl.ARRAY_BUFFER, null);  

         /*========================Shaders============================*/

         //Vertex shader source code
         var vertCode =
            'attribute vec4 coordinates;' + 
            'uniform mat4 u_xformMatrix;' +
            'void main(void) {' +
               '  gl_Position = u_xformMatrix * coordinates;' +
            '}';

         //Create a vertex shader program object and compile it                
         var vertShader = gl.createShader(gl.VERTEX_SHADER);
         gl.shaderSource(vertShader, vertCode);
         gl.compileShader(vertShader);

         //fragment shader source code
         var fragCode =
            'void main(void) {' +
               '   gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);' +
            '}';

         //Create a fragment shader program object and compile it 
         var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
         gl.shaderSource(fragShader, fragCode);
         gl.compileShader(fragShader);

         //Create and use combiened shader program
         var shaderProgram = gl.createProgram();
         gl.attachShader(shaderProgram, vertShader);
         gl.attachShader(shaderProgram, fragShader);
         gl.linkProgram(shaderProgram);

         gl.useProgram(shaderProgram); 

         /*===================scaling==========================*/

         var Sx = 1.0, Sy = 1.5, Sz = 1.0;
         var xformMatrix = new Float32Array([
            Sx,   0.0,  0.0,  0.0,
            0.0,  Sy,   0.0,  0.0,
            0.0,  0.0,  Sz,   0.0,
            0.0,  0.0,  0.0,  1.0  
         ]);

         var u_xformMatrix = gl.getUniformLocation(shaderProgram, 'u_xformMatrix');
         gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix);

         /* ===========Associating shaders to buffer objects============*/
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);   

         var coordinatesVar = gl.getAttribLocation(shaderProgram, "coordinates"); 
         gl.vertexAttribPointer(coordinatesVar, 3, gl.FLOAT, false, 0, 0);  
         gl.enableVertexAttribArray(coordinatesVar);

         /*=================Drawing the Quad========================*/ 
         gl.clearColor(0.5, 0.5, 0.5, 0.9);
         gl.enable(gl.DEPTH_TEST);

         gl.clear(gl.COLOR_BUFFER_BIT);
         gl.viewport(0,0,canvas.width,canvas.height);
         gl.drawArrays(gl.TRIANGLES, 0, 3);
      </script>
   </body>
</html>

Se esegui questo esempio, produrrà il seguente output: