Scroll to top
This post is part of a series called WebGL Essentials.
WebGL Essentials: Part II

German (Deutsch) translation by Alex Grigorovich (you can also view the original English article)

WebGL ist ein 3D-Renderer im Browser, der auf OpenGL basiert und es hilft Ihnen, Ihre 3D-Inhalte direkt auf einer HTML5-Seite anzuzeigen. In diesem Tutorial werde ich alle wichtigen Informationen behandeln, die Sie benötigen, um mit diesem Framework beginnen zu können.


Einführung

Es gibt ein paar Dinge, die Sie wissen sollten, bevor wir anfangen. WebGL ist eine JavaScript-API, die 3D-Inhalte auf einer HTML5-Zeichenfläche rendert. Dazu werden zwei Skripte verwendet, die in der "3D-Welt" als Shader bekannt sind. Die zwei Shader sind:

  • Der Vertex-Shader
  • Der Fragment-Shader

Seien Sie jetzt nicht zu nervös, wenn Sie diese Namen hören. Es ist nur eine ausgefallene Art zu sagen: "Positionsrechner" bzw. "Farbauswahl". Der Fragment-Shader ist leichter zu verstehen. Es teilt WebGL einfach mit, welche Farbe ein bestimmter Punkt auf Ihrem Modell haben soll. Der Vertex-Shader ist etwas technischer, konvertiert jedoch im Grunde die Punkte in Ihren 3D-Modellen in 2D-Koordinaten. Da alle Computermonitore flache 2D-Oberflächen sind und Sie 3D-Objekte auf Ihrem Bildschirm sehen, sind sie lediglich eine Illusion der Perspektive.

Wenn Sie genau wissen möchten, wie diese Berechnung funktioniert, müssen Sie einen Mathematiker fragen, da er erweiterte 4 x 4-Matrixmultiplikationen verwendet, die etwas über das Tutorial "Essentials" hinausgehen. Sie müssen nicht wissen, wie es funktioniert, da WebGL sich um das meiste kümmert. Also lassen uns anfangen.


Schritt 1: Einrichten von WebGL

WebGL hat viele kleine Einstellungen, die Sie fast jedes Mal vornehmen müssen, wenn Sie etwas auf den Bildschirm zeichnen. Um Zeit zu sparen und Ihren Code ordentlich zu gestalten, werde ich ein JavaScript-Objekt erstellen, das alle Dinge hinter den Kulissen in einer separaten Datei enthält. Erstellen Sie zunächst eine neue Datei mit dem Namen 'WebGL.js' und fügen Sie den folgenden Code ein:

1
function WebGL(CID, FSID, VSID){
2
	var canvas = document.getElementById(CID);
3
	if(!canvas.getContext("webgl") && !canvas.getContext("experimental-webgl"))
4
		alert("Your Browser Doesn't Support WebGL");
5
	else
6
	{
7
		this.GL = (canvas.getContext("webgl")) ? canvas.getContext("webgl") : canvas.getContext("experimental-webgl");	
8
		
9
		this.GL.clearColor(1.0, 1.0, 1.0, 1.0); // this is the color 

10
		this.GL.enable(this.GL.DEPTH_TEST); //Enable Depth Testing

11
		this.GL.depthFunc(this.GL.LEQUAL); //Set Perspective View

12
		this.AspectRatio = canvas.width / canvas.height;
13
		
14
		//Load Shaders Here

15
	}
16
}

Diese Konstruktorfunktion berücksichtigt die IDs der Zeichenfläche und der beiden Shader-Objekte. Zuerst erhalten wir das Canvas-Element und stellen sicher, dass es WebGL unterstützt. Wenn dies der Fall ist, weisen wir den WebGL-Kontext einer lokalen Variablen namens "GL" zu. Die klare Farbe ist einfach die Hintergrundfarbe, und es ist erwähnenswert, dass in WebGL die meisten Parameter von 0,0 bis 1,0 reichen, sodass Sie Ihre RGB-Werte durch 255 teilen müssten. In unserem Beispiel bedeutet 1.0, 1.0, 1.0, 1.0 einen weißen Hintergrund mit 100% Sichtbarkeit (keine Transparenz). In den nächsten beiden Zeilen wird WebGL angewiesen, Tiefe und Perspektive zu berechnen, damit ein Objekt in Ihrer Nähe Objekte dahinter blockiert. Schließlich legen wir das Seitenverhältnis fest, das berechnet wird, indem die Breite der Leinwand durch ihre Höhe geteilt wird.

Bevor wir fortfahren und die beiden Shader laden, schreiben wir sie. Ich werde diese in die HTML-Datei schreiben, in die wir das eigentliche Canvas-Element einfügen werden. Erstellen Sie eine HTML-Datei und platzieren Sie die folgenden zwei Skriptelemente direkt vor dem schließenden Body-Tag:

1
<script id="VertexShader" type="x-shader/x-vertex">
2
  
3
	attribute highp vec3 VertexPosition;
4
	attribute highp vec2 TextureCoord;
5
	
6
	
7
	uniform highp mat4 TransformationMatrix;
8
	uniform highp mat4 PerspectiveMatrix;
9
	
10
	varying highp vec2 vTextureCoord;
11
	
12
	void main(void) {
13
		gl_Position = PerspectiveMatrix * TransformationMatrix * vec4(VertexPosition, 1.0);
14
		vTextureCoord = TextureCoord;
15
	}
16
</script>

17
18
<script id="FragmentShader" type="x-shader/x-fragment"> 
19
	varying highp vec2 vTextureCoord;
20
	
21
	uniform sampler2D uSampler;
22
	
23
	void main(void) {
24
		highp vec4 texelColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
25
		gl_FragColor = texelColor;
26
	}     
27
</script>

Der Vertex-Shader wird zuerst erstellt und wir definieren zwei Attribute:

  • die Scheitelpunktposition, d.h. die Position in x-, y- und z-Koordinaten des aktuellen Scheitelpunkts (Punkt in Ihrem Modell)
  • die Texturkoordinate; die Position im Texturbild, die diesem Punkt zugewiesen werden soll

Danach erstellen wir Variablen für die Transformations- und Perspektivenmatrizen. Diese werden verwendet, um das 3D-Modell in ein 2D-Bild umzuwandeln. In der nächsten Zeile wird eine gemeinsame Variable für den Fragment-Shader erstellt, und in der Hauptfunktion berechnen wir die gl_Position (die endgültige 2D-Position). Anschließend weisen wir der gemeinsam genutzten Variablen die 'aktuelle Texturkoordinate' zu.

Im Fragment-Shader nehmen wir nur die Koordinaten, die wir im Vertex-Shader definiert haben, und "probieren" die Textur an dieser Koordinate aus. Grundsätzlich erhalten wir nur die Farbe in der Textur, die dem aktuellen Punkt in unserer Geometrie entspricht.

Nachdem wir die Shader geschrieben haben, können wir sie wieder in unsere JS-Datei laden. Ersetzen Sie daher die "//Load Shaders Here" durch den folgenden Code:

1
var FShader = document.getElementById(FSID);
2
var VShader = document.getElementById(VSID);
3
4
if(!FShader || !VShader)
5
	alert("Error, Could Not Find Shaders");
6
else
7
{
8
	//Load and Compile Fragment Shader

9
	var Code = LoadShader(FShader);
10
	FShader = this.GL.createShader(this.GL.FRAGMENT_SHADER);
11
	this.GL.shaderSource(FShader, Code);
12
	this.GL.compileShader(FShader);
13
	
14
	//Load and Compile Vertex Shader

15
	Code = LoadShader(VShader);
16
	VShader = this.GL.createShader(this.GL.VERTEX_SHADER);
17
	this.GL.shaderSource(VShader, Code);
18
	this.GL.compileShader(VShader);
19
	
20
	//Create The Shader Program

21
	this.ShaderProgram = this.GL.createProgram();
22
	this.GL.attachShader(this.ShaderProgram, FShader);
23
	this.GL.attachShader(this.ShaderProgram, VShader);
24
	this.GL.linkProgram(this.ShaderProgram);
25
	this.GL.useProgram(this.ShaderProgram);
26
	
27
	//Link Vertex Position Attribute from Shader

28
	this.VertexPosition = this.GL.getAttribLocation(this.ShaderProgram, "VertexPosition");
29
	this.GL.enableVertexAttribArray(this.VertexPosition);
30
	
31
	//Link Texture Coordinate Attribute from Shader

32
	this.VertexTexture = this.GL.getAttribLocation(this.ShaderProgram, "TextureCoord");
33
	this.GL.enableVertexAttribArray(this.VertexTexture);
34
}

Ihre Texturen müssen in geraden Bytegrößen vorliegen, sonst wird eine Fehlermeldung angezeigt... wie 2x2, 4x4, 16x16, 32x32...

Wir stellen zuerst sicher, dass die Shader vorhanden sind, und laden sie dann einzeln. Der Prozess ruft im Grunde den Quellcode des Shaders ab, kompiliert ihn und hängt ihn an das zentrale Shader-Programm an. Es gibt eine Funktion namens LoadShader, die den Shader-Code aus der HTML-Datei abruft. Wir werden gleich darauf zurückkommen. Wir verwenden das 'Shader-Programm', um die beiden Shader miteinander zu verbinden, und es gibt uns Zugriff auf ihre Variablen. Wir speichern die beiden Attribute, die wir in den Shadern definiert haben. damit wir später unsere Geometrie in sie eingeben können.

Schauen wir uns nun die LoadShader-Funktion an. Sie sollten diese außerhalb der WebGL-Funktion platzieren:

1
function LoadShader(Script){
2
	var Code = "";
3
	var CurrentChild = Script.firstChild;
4
	while(CurrentChild)
5
	{
6
		if(CurrentChild.nodeType == CurrentChild.TEXT_NODE)
7
			Code += CurrentChild.textContent;
8
		CurrentChild = CurrentChild.nextSibling;
9
	}
10
	return Code;
11
}

Es durchläuft im Grunde nur den Shader und sammelt den Quellcode.


Schritt 2: Der "einfache" Würfel

Zum Zeichnen von Objekten in WebGL benötigen Sie die folgenden drei Arrays:

  • Eckpunkte; die Punkte, aus denen Ihre Objekte bestehen
  • Dreiecke; teilt WebGL mit, wie die Scheitelpunkte zu Flächen verbunden werden sollen
  • Texturkoordinaten; Definiert, wie die Scheitelpunkte auf dem Texturbild abgebildet werden

Das wird als UV-Mapping bezeichnet. In unserem Beispiel erstellen wir einen Basiswürfel. Ich werde den Würfel in 4 Eckpunkte pro Seite teilen, die sich in zwei Dreiecke verbinden. Lassen Sie uns eine Variable erstellen, die die Arrays eines Cubes enthält.

1
var Cube = {
2
	Vertices : [ // X, Y, Z Coordinates

3
	
4
		//Front

5
		
6
		 1.0,  1.0,  -1.0,
7
		 1.0, -1.0,  -1.0,
8
		-1.0,  1.0,  -1.0,
9
		-1.0, -1.0,  -1.0,
10
		
11
		//Back

12
		
13
		 1.0,  1.0,  1.0,
14
		 1.0, -1.0,  1.0,
15
		-1.0,  1.0,  1.0,
16
		-1.0, -1.0,  1.0,
17
		
18
		//Right

19
		
20
		 1.0,  1.0,  1.0,
21
		 1.0, -1.0,  1.0,
22
		 1.0,  1.0, -1.0,
23
		 1.0, -1.0, -1.0,
24
		 
25
		 //Left

26
		 
27
		-1.0,  1.0,  1.0,
28
		-1.0, -1.0,  1.0,
29
		-1.0,  1.0, -1.0,
30
		-1.0, -1.0, -1.0,
31
		
32
		//Top

33
		
34
		 1.0,  1.0,  1.0,
35
		-1.0, -1.0,  1.0,
36
		 1.0, -1.0, -1.0,
37
		-1.0, -1.0, -1.0,
38
		
39
		//Bottom

40
		
41
		 1.0, -1.0,  1.0,
42
		-1.0, -1.0,  1.0,
43
		 1.0, -1.0, -1.0,
44
		-1.0, -1.0, -1.0
45
	
46
	],
47
	Triangles : [ // Also in groups of threes to define the three points of each triangle

48
		//The numbers here are the index numbers in the vertex array

49
		
50
		//Front

51
		
52
		0, 1, 2,
53
		1, 2, 3,
54
		
55
		//Back

56
		
57
		4, 5, 6,
58
		5, 6, 7,
59
		
60
		//Right

61
		
62
		8, 9, 10,
63
		9, 10, 11,
64
		
65
		//Left

66
		
67
		12, 13, 14,
68
		13, 14, 15,
69
		
70
		//Top

71
		
72
		16, 17, 18,
73
		17, 18, 19,
74
		
75
		//Bottom

76
		
77
		20, 21, 22,
78
		21, 22, 23
79
		
80
	],
81
	Texture : [ //This array is in groups of two, the x and y coordinates (a.k.a U,V) in the texture

82
		//The numbers go from 0.0 to 1.0, One pair for each vertex

83
		
84
		 //Front

85
		 
86
		 1.0, 1.0,
87
		 1.0, 0.0,
88
		 0.0, 1.0,
89
		 0.0, 0.0,
90
		 
91
		
92
		 //Back

93
		
94
		 0.0, 1.0,
95
		 0.0, 0.0,
96
		 1.0, 1.0,
97
		 1.0, 0.0,
98
		
99
		 //Right

100
		
101
		 1.0, 1.0,
102
		 1.0, 0.0,
103
		 0.0, 1.0,
104
		 0.0, 0.0,
105
		 
106
		 //Left

107
		 
108
		 0.0, 1.0,
109
		 0.0, 0.0,
110
		 1.0, 1.0,
111
		 1.0, 0.0,
112
		
113
		 //Top

114
		
115
		 1.0, 0.0,
116
		 1.0, 1.0,
117
		 0.0, 0.0,
118
		 0.0, 1.0,
119
		
120
		 //Bottom

121
		
122
		 0.0, 0.0,
123
		 0.0, 1.0,
124
		 1.0, 0.0,
125
		 1.0, 1.0
126
	]
127
};

Es mag wie eine Menge Daten für einen einfachen Würfel erscheinen. In Teil 2 dieses Tutorials werde ich jedoch ein Skript erstellen, das Ihre 3D-Modelle importiert, damit Sie sich nicht um die Berechnung dieser Daten kümmern müssen.

Sie fragen sich vielleicht auch, warum ich 24 Punkte (4 für jede Seite) gemacht habe, wenn ein Würfel wirklich nur insgesamt acht eindeutige Punkte enthält? Ich habe dies getan, weil Sie nur eine Texturkoordinate pro Scheitelpunkt zuweisen können. Wenn wir also nur die 8 Punkte eingeben würden, müsste der gesamte Würfel gleich aussehen, da er die Textur um alle Seiten wickeln würde, die der Scheitelpunkt berührt. Auf diese Weise hat jede Seite ihre eigenen Punkte, sodass wir auf jeder Seite einen anderen Teil der Textur platzieren können.

Wir haben jetzt diese Würfelvariable und können mit dem Zeichnen beginnen. Kehren wir zur WebGL-Methode zurück und fügen eine Draw-Funktion hinzu.


Schritt 3: Die Zeichenfunktion

Das Verfahren zum Zeichnen von Objekten in WebGL umfasst viele Schritte. Daher ist es eine gute Idee, eine Funktion zu erstellen, um den Prozess zu vereinfachen. Die Grundidee besteht darin, die drei Arrays in WebGL-Puffer zu laden. Anschließend verbinden wir diese Puffer mit den Attributen, die wir in den Shadern definiert haben, zusammen mit den Transformations- und Perspektivmatrizen. Als nächstes müssen wir die Textur in den Speicher laden und schließlich können wir den Befehl draw aufrufen. Also lasst uns anfangen.

Der folgende Code ist in der WebGL-Funktion enthalten:

1
this.Draw = function(Object, Texture)
2
{
3
    var VertexBuffer = this.GL.createBuffer(); //Create a New Buffer

4
5
    //Bind it as The Current Buffer

6
    this.GL.bindBuffer(this.GL.ARRAY_BUFFER, VertexBuffer);
7
8
    // Fill it With the Data

9
    this.GL.bufferData(this.GL.ARRAY_BUFFER, new Float32Array(Object.Vertices), this.GL.STATIC_DRAW);
10
11
    //Connect Buffer To Shader's attribute

12
    this.GL.vertexAttribPointer(this.VertexPosition, 3, this.GL.FLOAT, false, 0, 0);
13
14
    //Repeat For The next Two

15
    var TextureBuffer = this.GL.createBuffer();
16
    this.GL.bindBuffer(this.GL.ARRAY_BUFFER, TextureBuffer);
17
    this.GL.bufferData(this.GL.ARRAY_BUFFER, new Float32Array(Object.Texture), this.GL.STATIC_DRAW);
18
    this.GL.vertexAttribPointer(this.VertexTexture, 2, this.GL.FLOAT, false, 0, 0);
1
    var TriangleBuffer = this.GL.createBuffer();
2
    this.GL.bindBuffer(this.GL.ELEMENT_ARRAY_BUFFER, TriangleBuffer);
3
    //Generate The Perspective Matrix

4
    var PerspectiveMatrix = MakePerspective(45, this.AspectRatio, 1, 10000.0);
5
6
    var TransformMatrix = MakeTransform(Object);
7
8
    //Set slot 0 as the active Texture

9
    this.GL.activeTexture(this.GL.TEXTURE0);
10
11
    //Load in the Texture To Memory

12
    this.GL.bindTexture(this.GL.TEXTURE_2D, Texture);
13
14
    //Update The Texture Sampler in the fragment shader to use slot 0

15
    this.GL.uniform1i(this.GL.getUniformLocation(this.ShaderProgram, "uSampler"), 0);
16
17
    //Set The Perspective and Transformation Matrices

18
    var pmatrix = this.GL.getUniformLocation(this.ShaderProgram, "PerspectiveMatrix");
19
    this.GL.uniformMatrix4fv(pmatrix, false, new Float32Array(PerspectiveMatrix));
20
21
    var tmatrix = this.GL.getUniformLocation(this.ShaderProgram, "TransformationMatrix");
22
    this.GL.uniformMatrix4fv(tmatrix, false, new Float32Array(TransformMatrix));
23
24
    //Draw The Triangles

25
    this.GL.drawElements(this.GL.TRIANGLES, Object.Trinagles.length, this.GL.UNSIGNED_SHORT, 0);
26
};

Der Vertex-Shader positioniert, dreht und skaliert Ihr Objekt basierend auf den Transformations- und Perspektivmatrizen. Wir werden im zweiten Teil dieser Reihe eingehender auf Transformationen eingehen.

Ich habe zwei Funktionen hinzugefügt: MakePerspective() und MakeTransform(). Diese generieren nur die notwendigen 4x4-Matrizen für WebGL. Die Funktion MakePerspective() akzeptiert das vertikale Sichtfeld, das Seitenverhältnis sowie die nächstgelegenen und am weitesten entfernten Punkte als Argumente. Alles, was näher als 1 Einheit und weiter als 10000 Einheiten ist, wird nicht angezeigt. Sie können diese Werte jedoch bearbeiten, um den gewünschten Effkt zu erzielen. Schauen wir uns nun diese beiden Funktionen an:

1
function MakePerspective(FOV, AspectRatio, Closest, Farest){
2
	var YLimit = Closest * Math.tan(FOV * Math.PI / 360);
3
	var A = -( Farest + Closest ) / ( Farest - Closest );
4
	var B = -2 * Farest * Closest / ( Farest - Closest );
5
	var C = (2 * Closest) / ( (YLimit * AspectRatio) * 2 );
6
	var D =	(2 * Closest) / ( YLimit * 2 );
7
	return [
8
		C, 0, 0, 0,
9
		0, D, 0, 0,
10
		0, 0, A, -1,
11
		0, 0, B, 0
12
	];
13
}
14
function MakeTransform(Object){
15
	return [
16
		1, 0, 0, 0,
17
		0, 1, 0, 0,
18
		0, 0, 1, 0,
19
		0, 0, -6, 1
20
	];
21
}

Beide Matrizen wirken sich auf das endgültige Aussehen Ihrer Objekte aus, aber die perspektivische Matrix bearbeitet Ihre '3D-Welt' wie das Sichtfeld und die sichtbaren Objekte, während die Transformationsmatrix die einzelnen Objekte wie ihre Rotationsskala und Position bearbeitet. Nachdem dies erledigt ist, sind wir fast bereit zu zeichnen. Alles, was übrig bleibt, ist eine Funktion zum Konvertieren eines Bildes in eine WebGL-Textur.


Schritt 4: Laden von Texturen

Das Laden einer Textur erfolgt in zwei Schritten. Zuerst müssen wir ein Bild wie in einer Standard-JavaScript-Anwendung laden und dann in eine WebGL-Textur konvertieren. Beginnen wir also mit dem zweiten Teil, da wir uns bereits in der JS-Datei befinden. Fügen Sie am Ende der WebGL-Funktion direkt nach dem Befehl Zeichnen Folgendes hinzu:

1
this.LoadTexture = function(Img){
2
	//Create a new Texture and Assign it as the active one

3
	var TempTex = this.GL.createTexture();
4
	this.GL.bindTexture(this.GL.TEXTURE_2D, TempTex);  
5
	
6
	//Flip Positive Y (Optional)

7
	this.GL.pixelStorei(this.GL.UNPACK_FLIP_Y_WEBGL, true);
8
	
9
	//Load in The Image

10
	this.GL.texImage2D(this.GL.TEXTURE_2D, 0, this.GL.RGBA, this.GL.RGBA, this.GL.UNSIGNED_BYTE, Img);  
11
	
12
	//Setup Scaling properties

13
	this.GL.texParameteri(this.GL.TEXTURE_2D, this.GL.TEXTURE_MAG_FILTER, this.GL.LINEAR);  
14
	this.GL.texParameteri(this.GL.TEXTURE_2D, this.GL.TEXTURE_MIN_FILTER, this.GL.LINEAR_MIPMAP_NEAREST);  
15
	this.GL.generateMipmap(this.GL.TEXTURE_2D); 
16
	
17
	//Unbind the texture and return it.

18
	this.GL.bindTexture(this.GL.TEXTURE_2D, null);
19
	return TempTex;
20
};

Es ist erwähnenswert, dass Ihre Texturen in geraden Byte-Größen vorliegen müssen, sonst erhalten Sie eine Fehlermeldung. Es müssen also Abmessungen wie 2x2, 4x4, 16x16, 32x32 usw. vorliegen. Ich habe die Linie hinzugefügt, um die Y-Koordinaten einfach umzudrehen, weil die Y-Koordinaten meiner 3D-Anwendung rückwärts waren, aber es hängt davon ab, was Sie verwenden. Dies liegt daran, dass einige Programme 0 in der Y-Achse in der oberen linken Ecke und einige Anwendungen in der unteren linken Ecke festlegen. Die von mir festgelegten Skalierungseigenschaften teilen WebGL lediglich mit, wie das Bild vergrößert und verkleinert werden soll. Sie können mit verschiedenen Optionen herumspielen, um verschiedene Effekte zu erzielen, aber ich dachte, diese funktionieren am besten.

Nachdem wir mit der JS-Datei fertig sind, kehren wir zur HTML-Datei zurück und implementieren all dies.


Schritt 5: Einpacken

Wie bereits erwähnt, wird WebGL in ein Canvas-Element gerendert. Das ist alles was wir im Körperteil brauchen. Nach dem Hinzufügen des Canvas-Elements sollte Ihre HTML-Seite wie folgt aussehen:

1
<html>
2
	<head>
3
		<!-- Include Our WebGL JS file -->
4
		<script src="WebGL.js" type="text/javascript"></script>
5
		<script>
6
			
7
		</script>
8
	</head>
9
	<body onload="Ready()">  
10
	  <canvas id="GLCanvas" width="720" height="480">
11
	    	Your Browser Doesn't Support HTML5's Canvas.  
12
	  </canvas>
13
	  
14
	<!-- Your Vertex Shader -->
15
	
16
	<!-- Your Fragment Shader -->
17
	
18
	</body>
19
</html>

Es ist eine ziemlich einfache Seite. Im Kopfbereich habe ich auf unsere JS-Datei verlinkt. Lassen Sie uns nun unsere Ready-Funktion implementieren, die beim Laden der Seite aufgerufen wird:

1
//This will hold our WebGL variable

2
var GL; 
3
	
4
//Our finished texture

5
var Texture;
6
	
7
//This will hold the textures image 

8
var TextureImage;
9
	
10
function Ready(){
11
	GL = new WebGL("GLCanvas", "FragmentShader", "VertexShader");
12
	TextureImage = new Image();
13
	TextureImage.onload = function(){
14
		Texture = GL.LoadTexture(TextureImage);
15
		GL.Draw(Cube, Texture);
16
	};
17
	TextureImage.src = "Texture.png";
18
}

Also erstellen wir ein neues WebGL-Objekt und übergeben die IDs für die Zeichenfläche und die Shader. Als nächstes laden wir das Texturbild. Nach dem Laden rufen wir die Draw()-Methode mit dem Cube und der Texture auf. Wenn Sie mitgemacht haben, sollte Ihr Bildschirm einen statischen Würfel mit einer Textur haben.

Obwohl ich sagte, dass wirdas nächste Mal Transformationen behandeln werden, kann ich Sie nicht einfach mit einem statischen Quadrat zurücklassen. Es ist nicht 3D genug. Gehen wir zurück und fügen eine kleine Drehung hinzu. Ändern Sie in der HTML-Datei die onload-Funktion folgendermaßen:

1
TextureImage.onload = function(){
2
		Texture = GL.LoadTexture(TextureImage);
3
		setInterval(Update, 33);
4
};

Dadurch wird alle 33 Millisekunden eine Funktion namens Update() aufgerufen, die eine Bildrate von ca. 30 fps ergibt. Hier ist die Update-Funktion:

1
function Update(){
2
	GL.GL.clear(16384 | 256);
3
	GL.Draw(GL.Cube, Texture);
4
}

Dies ist eine ziemlich einfache Funktion; Es löscht den Bildschirm und zeichnet dann den aktualisierten Cube. Gehen wir nun zur JS-Datei, um den Rotationscode hinzuzufügen.


Schritt 6: Hinzufügen von Spin

Ich werde Transformationen nicht vollständig implementieren, da ich sie für das nächste Mal speichere, aber fügen wir eine Drehung um die Y-Achse hinzu. Zuerst fügen Sie dem unseren Cube-Objekt eine Rotationsvariable hinzu. Dadurch wird der aktuelle Winkel verfolgt und die Drehung kann weiter erhöht werden. Der obere Rand Ihrer Cube-Variablen sollte also folgendermaßen aussehen:

1
var Cube = {
2
	Rotation : 0,
3
	//The Other Three Arrays

4
};

Aktualisieren wir nun die Funktion MakeTransform(), um die Rotation einzubeziehen:

1
function MakeTransform(Object){
2
	var y = Object.Rotation * (Math.PI / 180.0);
3
	var A = Math.cos(y);
4
	var B = -1 * Math.sin(y);
5
	var C = Math.sin(y);
6
	var D = Math.cos(y);
7
	Object.Rotation += .3;	
8
	return [
9
		A, 0, B, 0,
10
		0, 1, 0, 0,
11
		C, 0, D, 0,
12
		0, 0, -6, 1
13
	];
14
}

Abschluss

Und das ist es! Im nächsten Tutorial werden wir das Laden von Modellen und das Durchführen von Transformationen behandeln. Ich hoffe, Ihnen hat dieses Tutorial gefallen. Fühlen Sie sich frei, Fragen oder Kommentare zu hinterlassen, die Sie möglicherweise unten haben.