WebGL - Desenhando um Quad

No capítulo anterior, discutimos os diferentes modos de desenho fornecidos pelo WebGL. Também podemos usar índices para desenhar primitivas usando um desses modos. Para desenhar modelos em WebGL, temos que escolher um desses primitivos e desenhar a malha necessária (ou seja, um modelo formado usando um ou mais primitivos).

Neste capítulo, daremos um exemplo para demonstrar como desenhar um quadrilátero usando WebGL.

Passos para desenhar um quadrilátero

As etapas a seguir são necessárias para criar um aplicativo WebGL para desenhar um quadrilátero.

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

Nesta etapa, obtemos o objeto de contexto de renderização WebGL usando getContext().

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

Um quadrado pode ser desenhado usando dois triângulos. Neste exemplo, fornecemos os vértices para dois triângulos (com uma aresta comum) e índices.

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

Nesta etapa, você precisa escrever os programas do sombreador de vértice e do sombreador de fragmento, compilá-los e criar um programa combinado vinculando esses dois programas.

  • Vertex Shader - No sombreador de vértice do programa, definimos o atributo vetorial para armazenar coordenadas 3D e atribuí-lo a gl_position.

var vertCode =
   'attribute vec3 coordinates;' +
   'void main(void) {' +
      ' gl_Position = vec4(coordinates, 1.0);' +
   '}';
  • Fragment Shader - No shader de fragmento, simplesmente atribuímos a cor do fragmento ao gl_FragColor variável.

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

Nesta etapa, associamos os objetos buffer ao programa shader.

Step 5 − Drawing the Required Object

Como estamos desenhando dois triângulos para formar um quadrante, usando índices, usaremos o método drawElements(). Para este método, temos que passar o número de índices. O valor deindices.length dá o número de índices.

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

Exemplo - Desenhe um Quadrilátero

O programa a seguir mostra como criar um aplicativo WebGL para desenhar um quadrilátero.

<!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>

Se você executar este exemplo, ele produzirá a seguinte saída -