WebGL - Beispielanwendung

Wir haben die Grundlagen von WebGL und der WebGL-Pipeline erläutert (ein Verfahren zum Rendern von Grafikanwendungen). In diesem Kapitel nehmen wir eine Beispielanwendung, um mit WebGL ein Dreieck zu erstellen, und befolgen die in der Anwendung befolgten Schritte.

Struktur der WebGL-Anwendung

Der WebGL-Anwendungscode ist eine Kombination aus JavaScript und OpenGL Shader Language.

  • Für die Kommunikation mit der CPU ist JavaScript erforderlich
  • Für die Kommunikation mit der GPU ist OpenGL Shader Language erforderlich.

Beispielanwendung

Nehmen wir nun ein einfaches Beispiel, um zu lernen, wie Sie mit WebGL ein einfaches Dreieck mit 2D-Koordinaten zeichnen.

<!doctype html>
<html>
   <body>
      <canvas width = "300" height = "300" id = "my_Canvas"></canvas>
		
      <script>
         /* Step1: Prepare the canvas and get WebGL context */

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

         /* Step2: Define the geometry and store it in buffer objects */

         var vertices = [-0.5, 0.5, -0.5, -0.5, 0.0, -0.5,];

         // Create a new buffer object
         var vertex_buffer = gl.createBuffer();

         // Bind an empty array buffer to it
         gl.bindBuffer(gl.ARRAY_BUFFER, vertex_buffer);
         
         // Pass the vertices data to the buffer
         gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

         // Unbind the buffer
         gl.bindBuffer(gl.ARRAY_BUFFER, null);

         /* Step3: Create and compile Shader programs */

         // Vertex shader source code
         var vertCode =
            'attribute vec2 coordinates;' + 
            'void main(void) {' + ' gl_Position = vec4(coordinates,0.0, 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 fragment shader
         gl.compileShader(fragShader);

         // Create a shader program object to store 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 programs
         gl.linkProgram(shaderProgram);

         // Use the combined shader program object
         gl.useProgram(shaderProgram);

         /* Step 4: Associate the shader programs 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, 2, gl.FLOAT, false, 0, 0);

         //Enable the attribute
         gl.enableVertexAttribArray(coord);

         /* Step5: Drawing the required object (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.drawArrays(gl.TRIANGLES, 0, 3);
      </script>
   </body>
</html>

Es wird das folgende Ergebnis erzeugt -

Wenn Sie das obige Programm sorgfältig beobachten, haben wir fünf aufeinanderfolgende Schritte ausgeführt, um mit WebGL ein einfaches Dreieck zu zeichnen. Die Schritte sind wie folgt:

Step 1 − Prepare the canvas and get WebGL rendering context

Wir erhalten das aktuelle HTML-Canvas-Objekt und erhalten dessen WebGL-Rendering-Kontext.

Step 2 − Define the geometry and store it in buffer objects

Wir definieren die Attribute der Geometrie wie Scheitelpunkte, Indizes, Farben usw. und speichern sie in den JavaScript-Arrays. Anschließend erstellen wir ein oder mehrere Pufferobjekte und übergeben die Arrays mit den Daten an das jeweilige Pufferobjekt. Im Beispiel speichern wir die Scheitelpunkte des Dreiecks in einem JavaScript-Array und übergeben dieses Array an ein Scheitelpunktpufferobjekt.

Step 3 − Create and compile Shader programs

Wir schreiben Vertex-Shader- und Fragment-Shader-Programme, kompilieren sie und erstellen ein kombiniertes Programm, indem wir diese beiden Programme verbinden.

Step 4 − Associate the shader programs with buffer objects

Wir verknüpfen die Pufferobjekte und das kombinierte Shader-Programm.

Step 5 − Drawing the required object (triangle)

Dieser Schritt umfasst Vorgänge wie das Löschen der Farbe, das Löschen des Pufferbits, das Aktivieren des Tiefentests, das Festlegen des Ansichtsfensters usw. Schließlich müssen Sie die erforderlichen Grundelemente mit einer der folgenden Methoden zeichnen: drawArrays() oder drawElements().

Alle diese Schritte werden in diesem Tutorial näher erläutert.