WebGL - Chế độ vẽ

Trong chương trước (Chương 12), chúng ta đã thảo luận về cách vẽ một tam giác bằng cách sử dụng WebGL. Ngoài hình tam giác, WebGL hỗ trợ nhiều chế độ vẽ khác. Chương này giải thích các chế độ vẽ được hỗ trợ bởi WebGL.

Thông số chế độ

Hãy cùng xem cú pháp của các phương thức: drawElements() và vẽ Arrays().

void drawElements(enum mode, long count, enum type, long offset);

void drawArrays(enum mode, int first, long count);

Nếu bạn quan sát rõ ràng, cả hai phương thức đều chấp nhận một tham số mode. Sử dụng tham số này, người lập trình có thể chọn chế độ vẽ trong WebGL.

Các chế độ vẽ do WebGL cung cấp được liệt kê trong bảng sau.

Sr.No. Chế độ & Mô tả
1

gl.POINTS

Để vẽ một loạt các điểm.

2

gl.LINES

Để vẽ một loạt các đoạn thẳng không nối (các đoạn thẳng).

3

gl.LINE_STRIP

Để vẽ một loạt các đoạn thẳng được kết nối.

4

gl.LINE_LOOP

Để vẽ một loạt các đoạn thẳng được kết nối. Nó cũng nối các đỉnh đầu tiên và cuối cùng để tạo thành một vòng lặp.

5

gl.TRIANGLES

Để vẽ một loạt các hình tam giác riêng biệt.

6

gl.TRIANGLE_STRIP

Để vẽ một loạt các hình tam giác được kết nối theo kiểu dải.

7

gl.TRIANGLE_FAN

Để vẽ một loạt các tam giác được kết nối có chung đỉnh đầu tiên theo kiểu hình cánh quạt.

Ví dụ - Vẽ ba đường song song

Ví dụ sau đây cho thấy cách vẽ ba đường thẳng song song bằng cách sử dụng gl.LINES.

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

      <script>
         /*======= Creating a canvas =========*/

         var canvas = document.getElementById('my_Canvas');
         var gl = canvas.getContext('experimental-webgl');

         /*======= Defining and storing the geometry ======*/

         var vertices = [
            -0.7,-0.1,0,
            -0.3,0.6,0,
            -0.3,-0.3,0,
            0.2,0.6,0,
            0.3,-0.3,0,
            0.7,0.6,0 
         ]

         // Create an empty buffer object
         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);

         /*=================== 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);

         // 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 triangle =============*/

         // 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 and depth buffer
         gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

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

         // Draw the triangle
         gl.drawArrays(gl.LINES, 0, 6);

         // POINTS, LINE_STRIP, LINE_LOOP, LINES,
         // TRIANGLE_STRIP,TRIANGLE_FAN, TRIANGLES
      </script>
   </body>
</html>

Nếu bạn chạy ví dụ này, nó sẽ tạo ra kết quả sau:

Chế độ vẽ

Trong chương trình trên, nếu bạn thay thế chế độ của drawArrays() với một trong các chế độ vẽ sau, nó sẽ tạo ra các đầu ra khác nhau mỗi lần.

Chế độ vẽ Kết quả đầu ra
LINE_STRIP
LINE_LOOP
TRIANGLE_STRIP
TRIANGLE_FAN
HÌNH TAM GIÁC