WebGL - Dessiner un quad

Dans le chapitre précédent, nous avons abordé les différents modes de dessin fournis par WebGL. Nous pouvons également utiliser des indices pour dessiner des primitives en utilisant l'un de ces modes. Pour dessiner des modèles dans WebGL, nous devons choisir l'une de ces primitives et dessiner le maillage requis (c'est-à-dire un modèle formé à l'aide d'une ou plusieurs primitives).

Dans ce chapitre, nous prendrons un exemple pour montrer comment dessiner un quadrilatère en utilisant WebGL.

Étapes pour dessiner un quadrilatère

Les étapes suivantes sont nécessaires pour créer une application WebGL pour dessiner un quadrilatère.

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

Dans cette étape, nous obtenons l'objet de contexte de rendu WebGL en utilisant getContext().

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

Un carré peut être dessiné à l'aide de deux triangles. Dans cet exemple, nous fournissons les sommets de deux triangles (avec une arête commune) et des indices.

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

indices = [3,2,1,3,1,0];

Step 3 − Create and Compile the Shader Programs

Dans cette étape, vous devez écrire les programmes vertex shader et fragment shader, les compiler et créer un programme combiné en liant ces deux programmes.

  • Vertex Shader - Dans le vertex shader du programme, nous définissons l'attribut vectoriel pour stocker les coordonnées 3D et l'attribuons à gl_position.

var vertCode =
   'attribute vec3 coordinates;' +
   'void main(void) {' +
      ' gl_Position = vec4(coordinates, 1.0);' +
   '}';
  • Fragment Shader - Dans le shader de fragment, nous attribuons simplement la couleur du fragment au gl_FragColor variable.

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

Step 4 − Associate the Shader Programs to Buffer Objects

Dans cette étape, nous associons les objets tampons au programme shader.

Step 5 − Drawing the Required Object

Puisque nous dessinons deux triangles pour former un quad, en utilisant des indices, nous utiliserons la méthode drawElements(). A cette méthode, il faut passer le nombre d'indices. La valeur deindices.length donne le nombre d'indices.

gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);

Exemple - Dessinez un quadrilatère

Le programme suivant montre comment créer une application WebGL pour dessiner un quadrilatère.

<!doctype html>
<html>
   <body>
      <canvas width = "570" height = "570" 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,
            0.5,0.5,0.0 
         ];

         indices = [3,2,1,3,1,0];

         // Create an empty buffer object to store vertex buffer
         var vertex_buffer = gl.createBuffer();

         // Bind appropriate array buffer to it
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

         // Pass the vertex data to the buffer
         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

         // Unbind the buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, null);

         // Create an empty buffer object to store Index buffer
         var Index_Buffer = gl.createBuffer();

         // Bind appropriate array buffer to it
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer);

         // Pass the vertex data to the buffer
         gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);

         // Unbind the buffer
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);

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

         // Vertex shader source code
         var vertCode =
            'attribute vec3 coordinates;' +
            'void main(void) {' +
               ' gl_Position = vec4(coordinates, 1.0);' +
            '}';

         // Create a vertex shader object
         var vertShader = gl.createShader(gl.VERTEX_SHADER);

         // Attach vertex shader source code
         gl.shaderSource(vertShader, vertCode);

         // Compile the vertex shader
         gl.compileShader(vertShader);

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

         // Create fragment shader object 
         var fragShader = gl.createShader(gl.FRAGMENT_SHADER);

         // Attach fragment shader source code
         gl.shaderSource(fragShader, fragCode);

         // Compile the fragmentt shader
         gl.compileShader(fragShader);

         // Create a shader program object to
         // store the combined shader program
         var shaderProgram = gl.createProgram();

         // Attach a vertex shader
         gl.attachShader(shaderProgram, vertShader);

         // Attach a fragment shader
         gl.attachShader(shaderProgram, fragShader);

         // Link both the programs
         gl.linkProgram(shaderProgram);

         // Use the combined shader program object
         gl.useProgram(shaderProgram);

         /* ======= Associating shaders to buffer objects =======*/

         // Bind vertex buffer object
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);

         // Bind index buffer object
         gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, Index_Buffer); 

         // Get the attribute location
         var coord = gl.getAttribLocation(shaderProgram, "coordinates");

         // Point an attribute to the currently bound VBO
         gl.vertexAttribPointer(coord, 3, gl.FLOAT, false, 0, 0);

         // Enable the attribute
         gl.enableVertexAttribArray(coord);

         /*============= Drawing the Quad ================*/

         // Clear the canvas
         gl.clearColor(0.5, 0.5, 0.5, 0.9);

         // Enable the depth test
         gl.enable(gl.DEPTH_TEST);

         // Clear the color buffer bit
         gl.clear(gl.COLOR_BUFFER_BIT);

         // Set the view port
         gl.viewport(0,0,canvas.width,canvas.height);

         // Draw the triangle
         gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);
      </script>
   </body>
</html>

Si vous exécutez cet exemple, il produira la sortie suivante -