WebGL - Dessiner un triangle
Dans le chapitre précédent (chapitre 11), nous avons expliqué comment dessiner trois points à l'aide de WebGL. Au chapitre 5, nous avons pris un exemple d'application pour montrer comment dessiner un triangle. Dans les deux exemples, nous avons dessiné les primitives en utilisant uniquement des sommets.
Pour dessiner des formes / maillages plus complexes, nous transmettons également les indices d'une géométrie, ainsi que les sommets, aux shaders. Dans ce chapitre, nous verrons comment dessiner un triangle à l'aide d'indices.
Étapes requises pour dessiner un triangle
Les étapes suivantes sont nécessaires pour créer une application WebGL pour dessiner un triangle.
Step 1 − Prepare the Canvas and Get 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 Buffer Objects
Puisque nous dessinons un triangle à l'aide d'indices, nous devons passer les trois sommets du triangle, y compris les indices, et les stocker dans les tampons.
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
Dans cette étape, vous devez écrire des 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(1, 0.5, 0.0, 1);' +
'}';
Step 4 − Associate the Shader Programs to the Buffer Objects
Dans cette étape, nous associons les objets tampons et le programme shader.
Step 5 − Drawing the Required Object
Puisque nous dessinons un triangle à l'aide d'indices, nous utiliserons drawElements()
. A cette méthode, il faut passer le nombre d'indices. La valeur duindices.length signifie le nombre d'indices.
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);
Exemple - Dessiner un triangle
Le code de programme suivant montre comment dessiner un triangle dans WebGL à l'aide d'indices -
<!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>
Si vous exécutez cet exemple, il produira la sortie suivante -