WebGL - Vẽ hình tam giác

Trong chương trước (Chương 11), chúng ta đã thảo luận về cách vẽ ba điểm bằng cách sử dụng WebGL. Trong Chương 5, chúng tôi đã lấy ứng dụng mẫu để chứng minh cách vẽ một hình tam giác. Trong cả hai ví dụ, chúng tôi đã rút ra các nguyên thủy chỉ sử dụng các đỉnh.

Để vẽ các hình dạng / lưới phức tạp hơn, chúng tôi cũng chuyển các chỉ số của một hình học, cùng với các đỉnh, cho các bóng đổ. Trong chương này, chúng ta sẽ xem cách vẽ một tam giác bằng cách sử dụng các chỉ số.

Các bước cần thiết để vẽ một tam giác

Các bước sau là bắt buộc để tạo một ứng dụng WebGL để vẽ một hình tam giác.

Step 1 − Prepare the Canvas and Get WebGL Rendering Context

Trong bước này, chúng tôi lấy đối tượng ngữ cảnh Kết xuất WebGL bằng cách sử dụng getContext().

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

Vì chúng ta đang vẽ một tam giác bằng cách sử dụng các chỉ số, chúng ta phải vượt qua ba đỉnh của tam giác, bao gồm các chỉ số và lưu trữ chúng trong bộ đệm.

var vertices = [
   -0.5,0.5,0.0,
   -0.5,-0.5,0.0,
   0.5,-0.5,0.0, 
];
	
indices = [0,1,2];

Step 3 − Create and Compile the Shader Programs

Trong bước này, bạn cần viết chương trình đổ bóng đỉnh và đổ bóng phân mảnh, biên dịch chúng và tạo một chương trình kết hợp bằng cách liên kết hai chương trình này.

  • Vertex Shader - Trong phần đổ bóng đỉnh của chương trình, chúng ta xác định thuộc tính vector để lưu trữ tọa độ 3D và gán nó cho gl_position.

var vertCode =
   'attribute vec3 coordinates;' +
	
   'void main(void) {' +
      ' gl_Position = vec4(coordinates, 1.0);' +
   '}';
  • Fragment Shader - Trong trình đổ bóng phân mảnh, chúng ta chỉ cần gán màu phân mảnh cho gl_FragColor Biến đổi.

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

Step 4 − Associate the Shader Programs to the Buffer Objects

Trong bước này, chúng tôi liên kết các đối tượng đệm và chương trình đổ bóng.

Step 5 − Drawing the Required Object

Vì chúng tôi đang vẽ một hình tam giác bằng cách sử dụng các chỉ số, chúng tôi sẽ sử dụng drawElements(). Đối với phương pháp này, chúng ta phải chuyển số chỉ số. Giá trị củaindices.length biểu thị số lượng chỉ số.

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

Ví dụ - Vẽ hình tam giác

Đoạn mã chương trình sau đây cho thấy cách vẽ một hình tam giác trong WebGL bằng cách sử dụng các chỉ số:

<!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, 
         ];
         
         indices = [0,1,2];
         
         // 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 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 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>

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