WebGL - Zeichnen eines Dreiecks
Im vorherigen Kapitel (Kapitel 11) haben wir erläutert, wie Sie mit WebGL drei Punkte zeichnen. In Kapitel 5 haben wir anhand einer Beispielanwendung demonstriert, wie ein Dreieck gezeichnet wird. In beiden Beispielen haben wir die Grundelemente nur mit Eckpunkten gezeichnet.
Um komplexere Formen / Netze zu zeichnen, übergeben wir die Indizes einer Geometrie zusammen mit den Eckpunkten auch an die Shader. In diesem Kapitel erfahren Sie, wie Sie mithilfe von Indizes ein Dreieck zeichnen.
Erforderliche Schritte zum Zeichnen eines Dreiecks
Die folgenden Schritte sind erforderlich, um eine WebGL-Anwendung zum Zeichnen eines Dreiecks zu erstellen.
Step 1 − Prepare the Canvas and Get WebGL Rendering Context
In diesem Schritt erhalten wir das WebGL-Rendering-Kontextobjekt mit getContext().
Step 2 − Define the Geometry and Store it in Buffer Objects
Da wir ein Dreieck mit Indizes zeichnen, müssen wir die drei Eckpunkte des Dreiecks einschließlich der Indizes übergeben und in den Puffern speichern.
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
In diesem Schritt müssen Sie Vertex-Shader- und Fragment-Shader-Programme schreiben, kompilieren und ein kombiniertes Programm erstellen, indem Sie diese beiden Programme verknüpfen.
Vertex Shader - Im Vertex-Shader des Programms definieren wir das Vektorattribut, um 3D-Koordinaten zu speichern und zuzuweisen gl_position.
var vertCode =
'attribute vec3 coordinates;' +
'void main(void) {' +
' gl_Position = vec4(coordinates, 1.0);' +
'}';
Fragment Shader - Im Fragment-Shader weisen wir dem einfach die Fragmentfarbe zu 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
In diesem Schritt ordnen wir die Pufferobjekte und das Shader-Programm zu.
Step 5 − Drawing the Required Object
Da wir ein Dreieck mit Indizes zeichnen, werden wir verwenden drawElements()
. An diese Methode müssen wir die Anzahl der Indizes übergeben. Der Wert desindices.length bezeichnet die Anzahl der Indizes.
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT,0);
Beispiel - Zeichnen eines Dreiecks
Der folgende Programmcode zeigt, wie ein Dreieck in WebGL mithilfe von Indizes gezeichnet wird:
<!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>
Wenn Sie dieses Beispiel ausführen, wird die folgende Ausgabe erzeugt: