<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
		<id>https://wiki.delphigl.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Yogu</id>
		<title>DGL Wiki - Benutzerbeiträge [de]</title>
		<link rel="self" type="application/atom+xml" href="https://wiki.delphigl.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Yogu"/>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php/Spezial:Beitr%C3%A4ge/Yogu"/>
		<updated>2026-04-14T23:30:15Z</updated>
		<subtitle>Benutzerbeiträge</subtitle>
		<generator>MediaWiki 1.27.4</generator>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=glBegin&amp;diff=24800</id>
		<title>glBegin</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=glBegin&amp;diff=24800"/>
				<updated>2010-03-26T20:37:52Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: /* Name */ Doppelter Verweis auf gleiche Seite im selben Satz entfernt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Excellent}}&lt;br /&gt;
= glBegin, glEnd =&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
'''glBegin, glEnd''' - Umschließen die [[Eckpunkt|Eckpunkte (Vertices)]] einer [[Primitive|Primitiven]], oder eine Gruppe gleicher Primitiven.&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 procedure '''glBegin'''(''mode'' : GLEnum);&lt;br /&gt;
 procedure '''glEnd''';&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; rules=&amp;quot;all&amp;quot;&lt;br /&gt;
! ''mode'' &lt;br /&gt;
| Bestimmt die [[Primitive]] bzw. Gruppe von [[Primitive|Primitiven]] die aus den von '''glBegin''' und '''glEnd''' umschlossenen [[Eckpunkt|Eckpunkten (Vertices)]] erstellt werden.&lt;br /&gt;
Erlaubt sind die folgenden zehn symbolischen Konstanten:&lt;br /&gt;
'''GL_POINTS''', '''GL_LINES''', '''GL_LINE_STRIP''', '''GL_LINE_LOOP''', '''GL_TRIANGLES''', '''GL_TRIANGLE_STRIP''', '''GL_TRIANGLE_FAN''', '''GL_QUADS''', '''GL_QUAD_STRIP''', und '''GL_POLYGON'''.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
'''glBegin''' und '''glEnd''' umschließen eine Liste von [[Eckpunkt|Eckpunkten (Vertices)]] die eine [[Primitive]] oder Gruppe von [[Primitive|Primitiven]] darstellt. '''glBegin''' erhält ein einzelnes Argument (''mode''), das angibt, auf welche Art und Weise die [[Eckpunkt|Eckpunkte (Vertices)]] interpretiert werden.&lt;br /&gt;
&lt;br /&gt;
Unter der Annahme ''n'' sei ein Integerwert der bei Eins beginnt und ''N'' als Integerwert der die Gesamtanzahl der übergebenen Eckpunkte angibt, ergeben sich folgende Interpretationen :&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable_B1}}&lt;br /&gt;
!mode&lt;br /&gt;
!Einschätzung&lt;br /&gt;
!Beschreibung&lt;br /&gt;
|-&lt;br /&gt;
|'''GL_POINTS'''&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|langsam&lt;br /&gt;
|[[Bild:Glbegin_points.jpg|350px|thumb|right]]&lt;br /&gt;
Behandelt jeden Eckpunkt als einzelnen Punkt. Eckpunkt ''n'' definiert Punkt ''n'', und ''N'' Punkte werden gerendert.&lt;br /&gt;
|-&lt;br /&gt;
|'''GL_LINES'''&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|mittel&lt;br /&gt;
|[[Bild:Glbegin_lines.jpg|350px|thumb|right]]&lt;br /&gt;
Behandelt jedes Eckpunkt-Paar als unabhängigen Linienabschnitt. Eckpunkte 2*''n''-1 und 2*''n'' beschreiben Linie n. N/2 Linien werden gerendert.&lt;br /&gt;
|-&lt;br /&gt;
|'''GL_LINE_STRIP'''&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|schnell&lt;br /&gt;
|[[Bild:Glbegin_linestrip.jpg|350px|thumb|right]]&lt;br /&gt;
Rendert eine Gruppe von miteinander verbundenen Liniensegmenten, beginnend beim ersten Eckpunkt bis zum letzten. Eckpunkte ''n'' und ''n+1'' beschreiben dabei Linie ''n''. ''N-1'' Linien werden gerendert.&lt;br /&gt;
|-&lt;br /&gt;
|'''GL_LINE_LOOP'''&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|sehr schnell&lt;br /&gt;
|[[Bild:Glbegin_lineloop.jpg|350px|thumb|right]]&lt;br /&gt;
Rendert eine miteinander verbundene Gruppe von Linienabschnitten, beginnend beim ersten Eckpunkt und endend beim letzten, und dann wieder abschließend zurück zum ersten. Eckpunkte ''n'' und ''n+1'' definieren Linie ''n''. Die letzte Linie wird jedoch durch die Eckpunkte ''N'' und 1 definiert. ''N'' Linien werden gerendert.&lt;br /&gt;
|-&lt;br /&gt;
|'''GL_TRIANGLES'''&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|schnell&lt;br /&gt;
|[[Bild:Glbegin_triangles.jpg|350px|thumb|right]]&lt;br /&gt;
Behandelt jedes Eckpunkt-Trio als unabhängiges Dreieck. Eckpunkte 3*''n''-2, 3*''n''-1 und 3*''n'' beschreiben Dreieck ''n''. ''N''/3 Dreiecke werden gerendert.&lt;br /&gt;
&lt;br /&gt;
'''Eigenschaften''':&lt;br /&gt;
* Alle Dreiecke bestehen aus jeweils 3 Vertices, die ausschließlich nur zu diesem Dreieck gehören.&lt;br /&gt;
|-&lt;br /&gt;
|'''GL_TRIANGLE_STRIP'''&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|am schnellsten&lt;br /&gt;
|[[Bild:Glbegin_trianglestrip.jpg|350px|thumb|right]]&lt;br /&gt;
Rendert eine verbundene Gruppe von Dreiecken. Ein Dreieck wird für jeden Eckpunkt der nach den beiden ersten Eckpunkten definiert wird gerendert. Für ein ungerades ''n'' definieren die Eckpunkte ''n'', ''n''+1 und ''n''+2 Dreieck ''n'', für gerade ''n''s definieren die Eckpunkte ''n''+1, ''n'' und ''n''+2 ein Dreieck. (Man beachte, dass die Reihenfolge bei geraden ''n'' impliziet geändert wird um entgegen der Uhrzeigerrichtung zu rendern. Siehe auch [[glFrontFace]])&lt;br /&gt;
&lt;br /&gt;
''N''-2 Dreiecke werden gerendert.&lt;br /&gt;
&lt;br /&gt;
'''Eigenschaften''':&lt;br /&gt;
* Nacheinander erstellte Dreiecke haben eine gemeinsame Kante.&lt;br /&gt;
* Nacheinander erstellte Dreiecke benutzen 2 gemeinsame Vertices.&lt;br /&gt;
|-&lt;br /&gt;
|'''GL_TRIANGLE_FAN'''&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|schnell&lt;br /&gt;
|[[Bild:Glbegin_trianglefan.jpg|350px|thumb|right]]&lt;br /&gt;
Rendert eine verbundene Gruppe von Dreiecken. Ein Dreieck wird für jeden Eckpunkt gerendert der nach den ersten beiden definiert wird. Eckpunkte 1, ''n''+1 und ''n''+2 definieren Dreieck ''n''. ''N''-2 Dreiecke werden gerendert.&lt;br /&gt;
&lt;br /&gt;
'''Eigenschaften''':&lt;br /&gt;
* Alle Dreiecke haben mindestens einen gemeinsamen Punkt (Vertex1).&lt;br /&gt;
* Nacheinander erstellte Dreiecke haben eine gemeinsame Kante.&lt;br /&gt;
* Nacheinander erstellte Dreiecke benutzen 2 gemeinsame Vertices.&lt;br /&gt;
|-&lt;br /&gt;
|'''GL_QUADS'''&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|schnell&lt;br /&gt;
|[[Bild:Glbegin_quads.jpg|350px|thumb|right]]&lt;br /&gt;
Behandelt jeweils vier Eckpunkte als unabhängiges Viereck. Eckpunkte 4*''n''-3, 4*''n''-2, 4*''n''-1 und 4*''n'' beschreiben Viereck ''n''. ''N''/4 Vierecke werden gerendert.&lt;br /&gt;
&lt;br /&gt;
'''Eigenschaften''':&lt;br /&gt;
* Alle Vierecke bestehen aus jeweils 4 Vertices, die ausschließlich nur zu diesem Viereck gehören.&lt;br /&gt;
|-&lt;br /&gt;
|'''GL_QUAD_STRIP'''&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|sehr schnell&lt;br /&gt;
|[[Bild:Glbegin_quadstrip.jpg|350px|thumb|right]]&lt;br /&gt;
Rendert eine verbundene Gruppe von Vierecken. Ein Viereck wird für jedes nach den ersten beiden Eckpunkten übergebene Eckpunktepaar gerendert. Eckpunkte 2*''n''-1, 2*''n'', 2*''n''+2 und 2*''n''+1 beschreiben Viereck ''n''. ''N''/2-1 Vierecke werden gerendert. Es gilt allerdings zu beachten, dass die Reihenfolge der Eckpunkte, die genutzt werden, um Vierecke aus einem Streifen zu generieren, unterschiedlich ggü. der unabhängigen Konstruktion sind.&lt;br /&gt;
&lt;br /&gt;
'''Eigenschaften''':&lt;br /&gt;
* Nacheinander erstellte Vierecke haben eine gemeinsame Kante.&lt;br /&gt;
* Nacheinander erstellte Vierecke benutzen 2 gemeinsame Vertices.&lt;br /&gt;
|-&lt;br /&gt;
|'''GL_POLYGON'''&lt;br /&gt;
|align=&amp;quot;center&amp;quot;|(langsam)&lt;br /&gt;
|[[Bild:Glbegin_polygon.jpg|350px|thumb|right]]&lt;br /&gt;
Rendert eine einzelnes, [[konvex|konvexes]] Polygon (=Vieleck). Eckpunkte 1 bis ''N'' definieren dieses Polygon.&lt;br /&gt;
&lt;br /&gt;
'''Hinweis'''&lt;br /&gt;
&lt;br /&gt;
GL_POLYGON scheint für Anfänger meist die &amp;quot;beste Lösung&amp;quot; zu sein, denn man kann alle möglichen (konvexen) Polygone erzeugen. Dies ist soweit richtig, allerdings ist GL_POLYGON um ein vielfaches langsamer als GL_TRIANGLES! Dies hat die folgenden Gründe: &amp;lt;br&amp;gt;&lt;br /&gt;
1. sind moderne Grafikkarten auf die Darstellung von Dreiecken optimiert und &amp;lt;br&amp;gt;&lt;br /&gt;
2. müssen die Polygone bevor sie von den Grafikkarten verwendet werden können, erst in Dreiecke zerlegt werden (siehe [[Triangulation]]). &amp;lt;br&amp;gt;&lt;br /&gt;
Vorallem der letzte Punkt sorgt für niedrige Frameraten im Vergleich zu dreiecksbasierten Strukturen.&amp;lt;br&amp;gt;&lt;br /&gt;
''Die OpenGL-Spezifikiation erlaubt es jedoch GL_POLYGON annähernd gleich zu behandeln  wie GL_TRIANGLE_FAN (die Ausnahme bildet der Wireframe-Modus mit [[glPolygonMode]]), was auch von vielen Grafikkarten in dieser Form umgesetzt wird. Ist dies der Fall, so fallen alle Vor- und Nachteile gegenüber GL_TRIANGLE_FAN weg.''&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Nur eine Untergruppe von GL Befehlen kann zwischen '''glBegin''' und '''glEnd''' genutzt werden. Die Befehle sind [[glVertex]], [[glColor]], [[glSecondaryColor]], [[glIndex]], [[glNormal]], [[glFogCoord]], [[glTexCoord]], [[glMultiTexCoord]], [[glVertexAttrib]], [[glEvalCoord]], [[glEvalPoint]], [[glArrayElement]], [[glMaterial]] und [[glEdgeFlag]]. Außerdem ist es erlaubt  [[glCallList]] oder [[glCallLists]] zu nutzen, um [[Displaylisten]] auszuführen, die nur oben erwähnte Kommandos enthalten. Sollte ein nicht erwähnter GL Befehl zwischen '''glBegin''' und '''glEnd''' ausgeführt werden, dann wird das Fehlerflag gesetzt und der Befehl ignoriert.&lt;br /&gt;
&lt;br /&gt;
Unabhängig des für ''mode'' übergebenen Wertes gibt es '''keine''' Begrenzung für die Anzahl der übergebenen Eckpunkte die zwischen '''glBegin''' und '''glEnd''' definiert werden. Linien, Dreiecke, Vierecke und Polygone die nicht genügendend beschrieben wurden, werden nicht gerendert.&lt;br /&gt;
Ungenügende Beschreibung bedeutet entweder, dass zu wenige Eckpunkte angegeben wurden, um eine einzelne [[Primitive]] zu beschreiben, oder ein inkorrektes Vielfaches an Eckpunkten übergeben wurde. Nicht komplette Primitiven werden ignoriert; der Rest wird gerendet.&lt;br /&gt;
&lt;br /&gt;
Das Minimum an zu spezifizierenden Eckpunkten für jede Primitive ist wie folgt :&lt;br /&gt;
*1 für einen Punkt&lt;br /&gt;
*2 für eine Linie&lt;br /&gt;
*3 für ein Dreieck&lt;br /&gt;
*4 für ein Viereck und &lt;br /&gt;
*3 für ein Polygon. &lt;br /&gt;
Modi die ein festgelegtes Vielfaches an Eckpunkten brauchen sind '''GL_LINES''' (2), '''GL_TRIANGLES''' (3), '''GL_QUADS''' (4), und '''GL_QUAD_STRIP''' (2).  ''(D.h. wenn man bei GL_TRIANGLES 8 Vertices angibt (kein Vielfaches von 3), werden nur die ersten 6 bearbeitet. Die restlichen 2 ergeben kein Dreieck und werden deshalb verworfen.)''&lt;br /&gt;
&lt;br /&gt;
Wenn Flächen gemeinsame Punkte haben (z.B. bei '''GL_TRIANGLE_FAN''') ist es nicht möglich die Eigenschaften dieser Vertices für jede Fläche individuell zu bestimmen. Wenn dies nötig sein sollte, müssen die entsprechenden Flächen aus individuellen Vertices zusammengestellt werden.&lt;br /&gt;
&lt;br /&gt;
== Änderungen ==&lt;br /&gt;
Folgende Erweiterungen hat die Funktion erfahren:&lt;br /&gt;
=== Ab OpenGL-Version 1.3 ===&lt;br /&gt;
Zusätzliche Funktionen definiert, welche innerhalb '''glBegin/glEnd''' auftauchen dürfen:&lt;br /&gt;
*[[glMultiTexCoord]]&lt;br /&gt;
=== Ab OpenGL-Version 1.4 ===&lt;br /&gt;
Zusätzliche Funktionen definiert, welche innerhalb '''glBegin/glEnd''' auftauchen dürfen:&lt;br /&gt;
*[[glFogCoord]]&lt;br /&gt;
*[[glSecondaryColor]]&lt;br /&gt;
=== Ab OpenGL-Version 2.0 ===&lt;br /&gt;
Zusätzliche Funktionen definiert, welche innerhalb '''glBegin/glEnd''' auftauchen dürfen:&lt;br /&gt;
*[[glVertexAttrib]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fehlermeldungen ==&lt;br /&gt;
'''GL_INVALID_ENUM''' wird ausgelöst wenn ''mode'' einen ungültigen Wert besitzt.&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_OPERATION''' wird ausgelöst, wenn zwischen '''glBegin''' und dem zugehörigen '''glEnd''' ein weiteres '''glBegin''' aufgerufen wird.&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_OPERATION''' wird ausgelöst, wenn '''glEnd''' ohne ein vorhergehendes '''glBegin''' aufgerufen wird.&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_OPERATION''' wird aufgerufen, wenn ein anderer Befehl als [[glVertex]], [[glColor]], [[glSecondaryColor]], [[glIndex]], [[glNormal]], [[glFogCoord]], [[glTexCoord]], [[glMultiTexCoord]], [[glVertexAttrib]], [[glEvalCoord]], [[glEvalPoint]], [[glArrayElement]], [[glMaterial]], [[glEdgeFlag]], [[glCallList]] oder [[glCallLists]] zwischen '''glBegin''' und dem zugehörigen '''glEnd''' aufgerufen wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ein Aufruf von [[glEnableClientState]], [[glDisableClientState]],  [[glPushClientAttrib]],  [[glPopClientAttrib]], [[glEdgeFlagPointer]], [[glFogCoordPointer]], [[glTexCoordPointer]], [[glColorPointer]], [[glSecondaryColorPointer]] [[glIndexPointer]], [[glNormalPointer]], [[glVertexPointer]], [[glVertexAttribPointer]], [[glInterleavedArrays]] oder [[glPixelStore]] nach einem Aufruf von '''glBegin''' und dem zugehörigen '''glEnd''' ist nicht erlaubt, aber je nach Implementation wird möglicherweise kein Fehler ausgelöst.&lt;br /&gt;
&lt;br /&gt;
==Beispiele==&lt;br /&gt;
{|{{Prettytable_B1}} width=&amp;quot;100%&amp;quot;&lt;br /&gt;
!width=&amp;quot;60%&amp;quot;|Code&lt;br /&gt;
!Ausgabe&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;glBegin(GL_TRIANGLES);&lt;br /&gt;
    glVertex3f(1,0,0);&lt;br /&gt;
    glVertex3f(0,1,0);&lt;br /&gt;
    glVertex3f(0,0,1);&lt;br /&gt;
glEnd;&amp;lt;/source&amp;gt;&lt;br /&gt;
|[[Bild:GlBegin_Bsp1.jpg|center]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Zwischen glBegin und glEnd können natürlich auch &amp;quot;nicht OpenGL&amp;quot;-Befehle stehen was man dazu nutzen kann komplexere Gebilde direkt mit einer Schleife zeichnen zu lassen:&lt;br /&gt;
&lt;br /&gt;
{|{{Prettytable_B1}} width=&amp;quot;100%&amp;quot;&lt;br /&gt;
!width=&amp;quot;60%&amp;quot;|Code&lt;br /&gt;
!Ausgabe&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
glBegin(GL_LINE_STRIP);&lt;br /&gt;
  f := 0.0;&lt;br /&gt;
  for i:=0 to 20 do&lt;br /&gt;
  begin&lt;br /&gt;
    glVertex3f(cos(f),sin(f),0);&lt;br /&gt;
    f := f + (2*Pi/20);&lt;br /&gt;
  end;&lt;br /&gt;
glEnd;&amp;lt;/source&amp;gt;&lt;br /&gt;
|[[Bild:GlBegin_Bsp2.jpg|center]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
http://www.opengl.org/sdk/docs/man/xhtml/glBegin.xml&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[glArrayElement]], [[glCallList]], [[glCallLists]], [[glColor]], [[glEdgeFlag]], [[glEvalCoord]], [[glEvalPoint]], [[glFogCoord]], [[glIndex]], [[glMaterial]], [[glMultiTexCoord]], [[glNormal]], [[glSecondaryColor]], [[glTexCoord]], [[glVertex]], [[glVertexAttrib]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:GL|Begin]]&lt;br /&gt;
 [[Kategorie:GL1.0]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Perlin_Noise&amp;diff=23259</id>
		<title>Perlin Noise</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Perlin_Noise&amp;diff=23259"/>
				<updated>2009-04-09T16:07:42Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: /* Interpolation */ Hineis korrigiert ;)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Excellent}}&lt;br /&gt;
Perlin Noise ist ein Fraktal-Algorithmus welcher mit sehr einfachen Formeln komplexe und theoretisch endlose Gebilde berechnen kann. Da Perlin Noise darauf basiert, scheinbar zufällige Funktionen mit weichen Übergängen (die Steigung kann einen gewissen Wert nicht überschreiten) zu benutzen, eignet er sich sehr gut zur Simulation verschiedenster, natürlicher Phänomene wie Beispielsweise:&lt;br /&gt;
* Wolken&lt;br /&gt;
* Landschaftshöhen- und auch Texturen&lt;br /&gt;
* eventuell auch Texturen wie Wasser, Feuer und ähnliches&lt;br /&gt;
&lt;br /&gt;
=Grundlagen=&lt;br /&gt;
Perlin Noise basiert auf der Überlagerung von Frequenzen. Bei einer niedrigen Frequenz wird zwischen 2 eher weit voneinander entfernten angegebenen Werten interpoliert. Bei der höchsten (sinnvollen) Frequenz wird für jeden dargestellten Wert (zB jedes Pixel) ein anderer Wert berechnet. Die Werte werden aus Pseudozufallszahlen für eine Positionsangabe gebildet. Die Positionsangabe kann hier eine beliebige Dimension besitzen (beispielsweise 2D für eine Heightmap, 3D für eine Volumentrische Textur, ...). Die Ausgabe ist üblicherweise 1 Wert welcher beliebig interpretiert werden kann.&lt;br /&gt;
&lt;br /&gt;
== Zufallswerte aber wie? ==&lt;br /&gt;
&lt;br /&gt;
Es wird eine Funktion benötigt die für jede Dimension einen Parameter hat und für die gleichen Parameter auch die gleichen Zahlen liefert.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;// 1. Dimension&lt;br /&gt;
function Werte1D(X:Integer):ErgebnisTyp&lt;br /&gt;
// 2.Dimension&lt;br /&gt;
function Werte2D(X,Y:Integer):ErgebnisTyp&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mit einen Array===&lt;br /&gt;
&lt;br /&gt;
Diese Aufgabe kann ein Array erfüllen welches man zuvor mit Zufallswerten gefüllt hat.&lt;br /&gt;
also:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
Werte1D:array [0..X_Werte_Max] of ErgebnisTyp;&lt;br /&gt;
Werte2D:array [0..X_Werte_Max,0..Y_Werte_Max] of ErgebnisTyp;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== eigene Zufallsfunktion ===&lt;br /&gt;
Ein gängiger Algorithmus sieht beispielsweise so aus:&lt;br /&gt;
 x := x + Seed;&lt;br /&gt;
 x := ( x shl 13 ) xor x;&lt;br /&gt;
 rand := 1 - ( (x * (x * x * 15731 + 789221) + 1376312589) and $7fffffff) / 1073741824;&lt;br /&gt;
Rand liefert hier einen Wert für eine 1 Dimensionale Positionsangabe (X - Ganzzahl) einen Wert zwischen -1 und 1. Für 2 Dimensionen könnte dieser Code folgendermaßen erweitert werden:&lt;br /&gt;
 n := x + y * 57 + Seed;&lt;br /&gt;
 n := ( n shl 13 ) xor n;&lt;br /&gt;
 rand := 1 - ( (n * (n * n * 15731 + 789221) + 1376312589) and $7fffffff) / 1073741824;&lt;br /&gt;
im weiteren wird diese Funktionalität mit Random( Pos ) bzw. Random( PosX, PosY ) verwendet.&lt;br /&gt;
&lt;br /&gt;
==[[Interpolation]]==&lt;br /&gt;
&lt;br /&gt;
Zwischen den Werten aus dem Array versucht man nun mit einer [[Interpolation]] schöne Übergänge zu schaffen. Am schnellsten ist die lineare [[Interpolation]], jedoch kann durch einen Trick auch eine Sinus artige [[Interpolation]] sehr schnell ablaufen. Auf den folgenden Bildern sieht man links linear [[Interpolation|interpolierte]] Höhenwerte und auf der rechten seite eine Sinus/Cosinus artige [[Interpolation]]. Die größern Punkte entsprechen den im Array abgespeicherten Zufallswerten.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Interpolation.png|center]]&lt;br /&gt;
&lt;br /&gt;
Die [[Interpolation]]s funktion muss zunächst einmal die beiden zu interpolierenden Werte entgegen nehmen. Zusätzlich muss noch durch mindestens einen weiteren Parameter klar werden, welche Position (im obrigen Bild X) den gesuchte Wert haben soll.&lt;br /&gt;
&lt;br /&gt;
Wäre einem die Ausführgeschwindigkeit egal, könnten die beiden Interpolations Funktionen folgerndermaßen aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;//Hinweis: nicht getestet&lt;br /&gt;
&lt;br /&gt;
function InterpoliereLinear(Wert1, Wert2, FaktorWert1: Real): Real;&lt;br /&gt;
// Lineare Interpolation von zwei Werten &lt;br /&gt;
// FaktorWert1 muss zwischen 0 und 1 liegen&lt;br /&gt;
begin&lt;br /&gt;
  result := Wert1*FaktorWert1 + Wert2*(1-FaktorWert1);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function InterpoliereCos(Wert1, Wert2, FaktorWert1: Real): Real;&lt;br /&gt;
// Cosinus/Sinus artige Interpolation von zwei werten; &lt;br /&gt;
// FaktorWert muss zwischen 0 und 1 liegen&lt;br /&gt;
begin&lt;br /&gt;
  result := Wert1*((cos(pi/2*FaktorWert1)+1)/2) + Wert2*(1-(cos(pi/2*FaktorWert1)+1)/2)&lt;br /&gt;
end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedoch möchte man meistens möglichst schnelle Berechnungen haben. Besonders die Sinus und Cosinus Funktionen können unter Umständen zum Problem werden. Um trotzdem Sinuns- und Cosinus-Interpolation zu erzeugen kann man im Vorraus sich ein Array mit Interpolationswerten anlegen. Da Rechner schneller mit Integerwerten als mit Gleitkommerwerten rechnen werden wir im folgenden Beispiel erstere verwenden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  Interpolation:array [0..Interpolation_Bereich-1]of Integer;&lt;br /&gt;
  //Interpoaltions_Bereich ist legt die Maximale Anzahl an Punkten fest,&lt;br /&gt;
  // die für zwei Interpolationswerte ermittelt werden können(inklusive Randpunkte).&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  Interpolation_Max = 1000 // * entspricht dem Wert 1.000; &lt;br /&gt;
                           // * je höher dieser Wert deso genauer das Ergebnis.&lt;br /&gt;
                           // * je höher dieser Wert ist deso niedriger  müssen&lt;br /&gt;
                           //   die Interpolationswerte sein&lt;br /&gt;
&lt;br /&gt;
procedure BeimStart;&lt;br /&gt;
begin&lt;br /&gt;
{..}&lt;br /&gt;
  // Im Interpolations Array werden mit den Werten die von Interpolation_Max bis 0 gehen gefüllt.&lt;br /&gt;
  // wobei Interpolation[0] = Interpolation_Max ist&lt;br /&gt;
  // und Interploation[high(Interpolation)] = 0 ist&lt;br /&gt;
  for i := 0 to high(Interpolation) do Interpolation[I] := round((cos(pi/(Interpolation_Bereich-1)*i)+1)/2*Interpolation_Max);&lt;br /&gt;
{..}&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Interpoliere(Wert1, Wert2: Integer; Nr, Von: Integer): Integer;&lt;br /&gt;
// Interpoliert zwischen 2 Werten&lt;br /&gt;
// Nr ist gibt den Punkt an den man ermitteln möchte. Von die Anzahl der Interpolations schrite&lt;br /&gt;
var&lt;br /&gt;
  Wert1_Faktor:Integer;&lt;br /&gt;
begin&lt;br /&gt;
  if Nr &amp;gt; Von then raise ERangeError.CreateFmt('Nr Wert %d nicht in 0..%d',[Nr,Von-1]);&lt;br /&gt;
  if Von &amp;gt; Interpolations_Bereich raise ERangeError.CreateFmt('Von Wert %d nicht in 0..%d',[0,-1]);&lt;br /&gt;
  Wert1_Faktor := Interpolation[(Interpolation_Bereich*  Nr)div Von];&lt;br /&gt;
  result := (Wert1*Wert1_Faktor) div Interpolation_Max&lt;br /&gt;
   + (Wert2*(1000 - Wert1_Faktor)) div Interpolation_Max;&lt;br /&gt;
end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies wäre die [[Interpolation]] für eine 1 Dimensionale Positionsangabe. Natürlich müssen aber auch die anderen Dimensionen [[Interpolation|interpoliert]] werden. Dies kann aber (wenn gewünscht) ebenfalls mit mehreren [[Interpolation]]en von 2 Werten erfolgen&lt;br /&gt;
 PosX = Ganzzahl( Position.x )&lt;br /&gt;
 PosY = Ganzzahl( Position.y )&lt;br /&gt;
 X1 = Interpoliere( Random( PosX, PosY ), Random( PosX, PosY + 1 ), Nachkommateil( Position.y ) )&lt;br /&gt;
 X2 = Interpoliere( Random( PosX + 1, PosY), Random( PosX + 1, PosY + 1, Nachkommateil( Position.y ) )&lt;br /&gt;
 Ergebnis = Interpoliere( X1, X2, Nachkommateil( Position.x ) )&lt;br /&gt;
&lt;br /&gt;
=Algorithmus=&lt;br /&gt;
Mit den oben beschriebenen Funktionen ist der Algorithmus recht schnell zu machen.&lt;br /&gt;
&lt;br /&gt;
==Die Parameter==&lt;br /&gt;
Der Perlin Noise Algorithmus erhält üblicherweise folgende Parameter:&lt;br /&gt;
*Double: Position (Die Position wird bereits entsprechend skaliert)&lt;br /&gt;
*Double: Persistenz (wie stark ist der Einfluss der höheren Frequenzen)&lt;br /&gt;
*Wertebereich: Double: Min, Double: Max&lt;br /&gt;
*Integer: Rechentiefe (Detailgrad)&lt;br /&gt;
*Gegebenenfalls Double: Frequenzfaktor (oder Standard auf 2)&lt;br /&gt;
Die Laufzeit für einen berechneten Wert beträgt [[O-Notation|O]]( n ) wobei n die Rechentiefe angibt.&lt;br /&gt;
&lt;br /&gt;
==Überlagerung der Frequenzen==&lt;br /&gt;
Es wird für jeden Detailgrad ein Wert berechnet. Da Perlin Noise für einen einzelnen Wert kaum Sinn macht und im Normalfall für mehrere nebeneinander liegende Positionen ein Wert berechnet wird, kann man auch von Frequenzbändern sprechen. Der Code könnte beispielsweise so aussehen:&lt;br /&gt;
 Wert = 0&lt;br /&gt;
 Für jeden Detailgrad&lt;br /&gt;
  Wert = Wert + InterpolierterWert( Position * Frequenz )&lt;br /&gt;
  Frequenz = Frequenz * Frequenzfaktor&lt;br /&gt;
Wie hier unschwer zu erkennen ist werden die Werte addiert (also überlagert).&lt;br /&gt;
&lt;br /&gt;
[[Bild:PerlinUeberlagerung.png|center|framed|''Abb.1: Frequenzbänder für 200 Werte (Pixel).''&amp;lt;br&amp;gt;&lt;br /&gt;
''Frequenzfaktor = 2; Persitenz = 0.5;''&amp;lt;br&amp;gt;&lt;br /&gt;
''Links oben: Frequenz 0.01 (Einheit = Pixel)''&amp;lt;br&amp;gt;&lt;br /&gt;
''Rechts oben: Frequenz 0.02''&amp;lt;br&amp;gt;&lt;br /&gt;
''Links unten: Frequenz 0.04''&amp;lt;br&amp;gt;&lt;br /&gt;
''Rechts unten: überlagerte (addierte) Frequenzbänder (für die ersten 3 Detailgrade)'']]&lt;br /&gt;
&lt;br /&gt;
==Rechentiefe==&lt;br /&gt;
Die Rechentiefe gibt an wie hoch der Detailgrad sein soll. In Abbildung 1 (siehe Frequenzen) wurde beispielsweise eine Rechentiefe von 3 verwendet. Bei einem 2 Dimensionalen Perlin Noise dürfte dies jedoch deutlichere Unterschiede zeigen (siehe Abbildung 2).&lt;br /&gt;
&lt;br /&gt;
[[Bild:PerlinTiefe.png|center|framed|''Abb. 2: Unterschiedliche Rechentiefen.''&amp;lt;br&amp;gt;&lt;br /&gt;
''Frequenzfaktor = 2; Persitenz = 0.5;''&amp;lt;br&amp;gt;&lt;br /&gt;
''Links oben: Rechentiefe 1''&amp;lt;br&amp;gt;&lt;br /&gt;
''Rechts oben: Rechentiefe 2''&amp;lt;br&amp;gt;&lt;br /&gt;
''Links unten: Rechentiefe 3''&amp;lt;br&amp;gt;&lt;br /&gt;
''Rechts unten: Rechentiefe 4'']]&lt;br /&gt;
&lt;br /&gt;
==Persistenz==&lt;br /&gt;
Die Persistenz gibt an wie stark die höheren Frequenzbänder Einfluss auf das Ergebnis haben sollen. Hierfür erweitern wir den unter '''Überlagerung der Frequenzen''' angegebenen Code:&lt;br /&gt;
 Wert = 0&lt;br /&gt;
 Faktor = 1&lt;br /&gt;
 Für Detailgrad = 1 bis Rechentiefe&lt;br /&gt;
  Wert = Wert + InterpolierterWert( Position * Frequenz ) * Faktor&lt;br /&gt;
  Frequenz = Frequenz * Frequenzfaktor&lt;br /&gt;
  Faktor = Faktor * Persistenz&lt;br /&gt;
&lt;br /&gt;
[[Bild:PerlinPersistenz.png|center|framed|&lt;br /&gt;
''Abb. 3: Unterschiedliche Persistenzen.''&amp;lt;br&amp;gt;&lt;br /&gt;
''Frequenzfaktor = 2; Rechentiefe = 5''&amp;lt;br&amp;gt;&lt;br /&gt;
''Links oben: Persistenz 0.2''&amp;lt;br&amp;gt;&lt;br /&gt;
''Rechts oben: Persistenz 0.4''&amp;lt;br&amp;gt;&lt;br /&gt;
''Links unten: Persistenz 0.6''&amp;lt;br&amp;gt;&lt;br /&gt;
''Rechts unten: Persistenz 0.8'']]&lt;br /&gt;
&lt;br /&gt;
==Der Wertebereich==&lt;br /&gt;
Bisher wurden zwar in den Bildern die Werte korrekt dargestellt, jedoch wurde noch nicht erklärt wie man zu diesen Werten kommt. Wir möchten nun den Code welcher unter Persistenz angegeben wurde so modifizieren, das er Werte für den Wertebereich [Min|Max] liefert. Betrachten wir vorerst was wir alles verwenden:&lt;br /&gt;
*InterpolierterWert( Position * Frequenz ): liefert einen Wert im Bereich [-1|1]&lt;br /&gt;
*Faktor: zu Beginn 1, wird bei jeden Durchlauf mit Persistenz multipliziert&lt;br /&gt;
*Frequenz und Frequenzfaktor: spielen für die Amplitude keine Rolle&lt;br /&gt;
Der Gesamtfaktor lässt sich recht einfach berechnen:&lt;br /&gt;
 Faktor = 1&lt;br /&gt;
 GesFaktor = 0&lt;br /&gt;
 Für Deteilgrad = 1 bis Rechentiefe&lt;br /&gt;
  GesFaktor = GesFaktor + Faktor&lt;br /&gt;
  Faktor = Faktor * Persistenz&lt;br /&gt;
Mit dem errechneten Gesamtfaktor wissen wir nun, das die Funktion einen Wert im Bereich &lt;br /&gt;
&lt;br /&gt;
[-GesFaktor|+GesFaktor] liefert. Nun brauchen wir nur noch die Amplitude skalieren und einen entsprechenden Offset für das Minimum addieren. Dies sieht im Endeffekt so aus:&lt;br /&gt;
&lt;br /&gt;
Initialisierung:&lt;br /&gt;
 Bereich = Max - Min;   &lt;br /&gt;
 Offset = Min + Bereich * 0.5;&lt;br /&gt;
 GesFaktor = 0;&lt;br /&gt;
 Faktor = 2;&lt;br /&gt;
 &lt;br /&gt;
 für 1 bis Rechentiefe&lt;br /&gt;
   GesFaktor += Faktor&lt;br /&gt;
   Faktor = Faktor * Persistenz&lt;br /&gt;
 &lt;br /&gt;
 Tiefe_1_Amplitude =   Bereich / GesFaktor&lt;br /&gt;
&lt;br /&gt;
Berechnung eines Wertes:&lt;br /&gt;
 Wert = 0&lt;br /&gt;
 Faktor = Tiefe_1_Amplitude&lt;br /&gt;
 Frequenz = 1&lt;br /&gt;
 Für Detailgrad = 1 bis Rechentiefe&lt;br /&gt;
   Wert = Wert + InterpolierterWert( Position * Frequenz ) * Faktor&lt;br /&gt;
   Frequenz = Frequenz * Frequenzfaktor&lt;br /&gt;
   Faktor = Faktor * Persistenz&lt;br /&gt;
 &lt;br /&gt;
 Wert = Wert + Offset&lt;br /&gt;
&lt;br /&gt;
= Weiterführendes =&lt;br /&gt;
== Einsatzgebiete ==&lt;br /&gt;
Neben der Generierung von Texturen und [[Heightmap]]s - welche von den Grafiken und Quellcodes in diesem Artikel bevorzugt behandelt wurden - gibt es natürlich noch andere Einsatzgebiete. Einige davon sind:&lt;br /&gt;
* Animation, also gehen, Mimik oder jede andere Form von Bewegung kann durch Perlin Noise abwechslungsreicher und somit etwas &amp;quot;menschlicher&amp;quot; gestaltet werden. Der Erfinder Ken Perlin hat hierfür auf seiner [http://mrl.nyu.edu/~perlin/ Homepage] ein paar gute Beispiele.&lt;br /&gt;
* Modifikation von Meshes: was bei [[Heightmap]]s am offensichtlichesten ist kann man auch auf eine Kugel anwenden um einen wunderbar unregelmäßigen, aber dennoch realistisch wirkenden Stein, Planeten oder einen Kometen daraus zu machen.&lt;br /&gt;
* Denkbar wäre die Verwendung von Perlin Noise natürlich auch für verschiedenste Umwelteinflüsse wie Wind (was sich sowohl in Animationen als auch Geräuschlautstärke auswirken kann), aber natürlich auch für künstliche Einflüsse wie Börsenkurse in einem Strategiespiel.&lt;br /&gt;
* Prozedurale Texturen (u.a. Holz-, Stein-, oder Marmor-Oberflächen) können gut mit Perlin Noise und einigen Zusatzfunktionen erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
== Erweiterungen ==&lt;br /&gt;
Perlin Noise kann (wie nahezu jeder andere Algorithmus auch) nach eigenen Wünschen modifiziert werden. Häufige Modifikationen sind:&lt;br /&gt;
* Tilebare Texturen erstellen, also Texturen welche links und rechts - und ggf. auch oben und unten - exakt gleich aussehen. Dieses Problem wird in [http://www.delphigl.com/forum/viewtopic.php?t=3859&amp;amp;postdays=0&amp;amp;postorder=asc&amp;amp;start=15 diesem DGL-Forenthread (ab Seite 2)] etwas näher behandelt.&lt;br /&gt;
* Nachbearbeitung der Ausgabewerte. Hier können wir das endgültige Resultat noch sehr stark verändern. Denkbar wäre hier beispielsweise, dass wir die Unterwasser und über Wasser - Landschaft ganz unterschiedlich skalieren. Das eindrucksvollste Beispiel hierfür dürfte jedoch ein Algorithmus für eine [[Himmel]]stextur sein, welcher [http://freespace.virgin.net/hugo.elias/models/m_clouds.htm hier] zu finden ist. Dieser Algorithmus verwendet einfaches Perlin Noise, modifiziert jedoch die Ausgabewerte mit einer Exponentialfunktion, wodurch eine (meines Erachtens) eindrucksvolle Wolkendecke entsteht. Das endgültige Ergebnis des Algorithmus beinhaltet natürlich noch etwas mehr als diese einfache Exponentialfunktion, jedoch könnte man auch dies im weiteren Sinne als Modifikation der Ausgabewerte sehen.&lt;br /&gt;
&lt;br /&gt;
== Verwandte Themen ==&lt;br /&gt;
Die Dekomprimierung von JPEG-Bildern basiert auf der Überlagerungen von Cosinus-Schwingungen einer vorgegebenen Frequenz und einer (von Bild zu Bild) variierenden Amplitude. Diese Überlagerung ist sehr ähnlich der Frequenzüberlagerung beim Perlin Noise. Der Unterschied ist natürlich, dass bei JPEG Cosinus Schwingungen verwendet werden und beim Perlin Noise zufällige Werte welche [[Interpolation|interpoliert]] werden.&lt;br /&gt;
&lt;br /&gt;
Die Komprimierung von JPEG-Bildern bildet nun das Gegenteil der Überlagerung von Cosinus-Schwingungen, also der Berechnung der Amplituden der einzelnen Frequenzen. Derartige Berechnungen basieren alle auf der Fourier Transformation.&lt;br /&gt;
&lt;br /&gt;
Also wenn ihr nun verstanden habt wozu die Überlagerung von verschiedenen Frequenzbändern in der Lage ist (wofür dieser Artikel hoffentlich hilfreich war), euch diverse Themen der Mathematik wie integrieren, differenzieren und vor allem Regression nicht allzu sehr abschrecken und ihr immer schon mal wissen wolltet wie derartige Bildkompression oder die Frequenzbalken eurer Audiowidergabe entstehen, wäre wohl nun ein (neuer?) Anlauf vielversprechend.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]] [[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Perlin_Noise&amp;diff=23258</id>
		<title>Perlin Noise</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Perlin_Noise&amp;diff=23258"/>
				<updated>2009-04-09T16:06:55Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: /* Interpolation */ Rückgabewerte für &amp;quot;InterpoliereLinear&amp;quot; und &amp;quot;InterpoliereCos&amp;quot; hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Excellent}}&lt;br /&gt;
Perlin Noise ist ein Fraktal-Algorithmus welcher mit sehr einfachen Formeln komplexe und theoretisch endlose Gebilde berechnen kann. Da Perlin Noise darauf basiert, scheinbar zufällige Funktionen mit weichen Übergängen (die Steigung kann einen gewissen Wert nicht überschreiten) zu benutzen, eignet er sich sehr gut zur Simulation verschiedenster, natürlicher Phänomene wie Beispielsweise:&lt;br /&gt;
* Wolken&lt;br /&gt;
* Landschaftshöhen- und auch Texturen&lt;br /&gt;
* eventuell auch Texturen wie Wasser, Feuer und ähnliches&lt;br /&gt;
&lt;br /&gt;
=Grundlagen=&lt;br /&gt;
Perlin Noise basiert auf der Überlagerung von Frequenzen. Bei einer niedrigen Frequenz wird zwischen 2 eher weit voneinander entfernten angegebenen Werten interpoliert. Bei der höchsten (sinnvollen) Frequenz wird für jeden dargestellten Wert (zB jedes Pixel) ein anderer Wert berechnet. Die Werte werden aus Pseudozufallszahlen für eine Positionsangabe gebildet. Die Positionsangabe kann hier eine beliebige Dimension besitzen (beispielsweise 2D für eine Heightmap, 3D für eine Volumentrische Textur, ...). Die Ausgabe ist üblicherweise 1 Wert welcher beliebig interpretiert werden kann.&lt;br /&gt;
&lt;br /&gt;
== Zufallswerte aber wie? ==&lt;br /&gt;
&lt;br /&gt;
Es wird eine Funktion benötigt die für jede Dimension einen Parameter hat und für die gleichen Parameter auch die gleichen Zahlen liefert.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;// 1. Dimension&lt;br /&gt;
function Werte1D(X:Integer):ErgebnisTyp&lt;br /&gt;
// 2.Dimension&lt;br /&gt;
function Werte2D(X,Y:Integer):ErgebnisTyp&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== mit einen Array===&lt;br /&gt;
&lt;br /&gt;
Diese Aufgabe kann ein Array erfüllen welches man zuvor mit Zufallswerten gefüllt hat.&lt;br /&gt;
also:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
Werte1D:array [0..X_Werte_Max] of ErgebnisTyp;&lt;br /&gt;
Werte2D:array [0..X_Werte_Max,0..Y_Werte_Max] of ErgebnisTyp;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== eigene Zufallsfunktion ===&lt;br /&gt;
Ein gängiger Algorithmus sieht beispielsweise so aus:&lt;br /&gt;
 x := x + Seed;&lt;br /&gt;
 x := ( x shl 13 ) xor x;&lt;br /&gt;
 rand := 1 - ( (x * (x * x * 15731 + 789221) + 1376312589) and $7fffffff) / 1073741824;&lt;br /&gt;
Rand liefert hier einen Wert für eine 1 Dimensionale Positionsangabe (X - Ganzzahl) einen Wert zwischen -1 und 1. Für 2 Dimensionen könnte dieser Code folgendermaßen erweitert werden:&lt;br /&gt;
 n := x + y * 57 + Seed;&lt;br /&gt;
 n := ( n shl 13 ) xor n;&lt;br /&gt;
 rand := 1 - ( (n * (n * n * 15731 + 789221) + 1376312589) and $7fffffff) / 1073741824;&lt;br /&gt;
im weiteren wird diese Funktionalität mit Random( Pos ) bzw. Random( PosX, PosY ) verwendet.&lt;br /&gt;
&lt;br /&gt;
==[[Interpolation]]==&lt;br /&gt;
&lt;br /&gt;
Zwischen den Werten aus dem Array versucht man nun mit einer [[Interpolation]] schöne Übergänge zu schaffen. Am schnellsten ist die lineare [[Interpolation]], jedoch kann durch einen Trick auch eine Sinus artige [[Interpolation]] sehr schnell ablaufen. Auf den folgenden Bildern sieht man links linear [[Interpolation|interpolierte]] Höhenwerte und auf der rechten seite eine Sinus/Cosinus artige [[Interpolation]]. Die größern Punkte entsprechen den im Array abgespeicherten Zufallswerten.&lt;br /&gt;
&lt;br /&gt;
[[Bild:Interpolation.png|center]]&lt;br /&gt;
&lt;br /&gt;
Die [[Interpolation]]s funktion muss zunächst einmal die beiden zu interpolierenden Werte entgegen nehmen. Zusätzlich muss noch durch mindestens einen weiteren Parameter klar werden, welche Position (im obrigen Bild X) den gesuchte Wert haben soll.&lt;br /&gt;
&lt;br /&gt;
Wäre einem die Ausführgeschwindigkeit egal, könnten die beiden Interpolations Funktionen folgerndermaßen aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;//Hineis: nicht getestet&lt;br /&gt;
&lt;br /&gt;
function InterpoliereLinear(Wert1, Wert2, FaktorWert1: Real): Real;&lt;br /&gt;
// Lineare Interpolation von zwei Werten &lt;br /&gt;
// FaktorWert1 muss zwischen 0 und 1 liegen&lt;br /&gt;
begin&lt;br /&gt;
  result := Wert1*FaktorWert1 + Wert2*(1-FaktorWert1);&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
function InterpoliereCos(Wert1, Wert2, FaktorWert1: Real): Real;&lt;br /&gt;
// Cosinus/Sinus artige Interpolation von zwei werten; &lt;br /&gt;
// FaktorWert muss zwischen 0 und 1 liegen&lt;br /&gt;
begin&lt;br /&gt;
  result := Wert1*((cos(pi/2*FaktorWert1)+1)/2) + Wert2*(1-(cos(pi/2*FaktorWert1)+1)/2)&lt;br /&gt;
end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jedoch möchte man meistens möglichst schnelle Berechnungen haben. Besonders die Sinus und Cosinus Funktionen können unter Umständen zum Problem werden. Um trotzdem Sinuns- und Cosinus-Interpolation zu erzeugen kann man im Vorraus sich ein Array mit Interpolationswerten anlegen. Da Rechner schneller mit Integerwerten als mit Gleitkommerwerten rechnen werden wir im folgenden Beispiel erstere verwenden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;pascal&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
var&lt;br /&gt;
  Interpolation:array [0..Interpolation_Bereich-1]of Integer;&lt;br /&gt;
  //Interpoaltions_Bereich ist legt die Maximale Anzahl an Punkten fest,&lt;br /&gt;
  // die für zwei Interpolationswerte ermittelt werden können(inklusive Randpunkte).&lt;br /&gt;
&lt;br /&gt;
const&lt;br /&gt;
  Interpolation_Max = 1000 // * entspricht dem Wert 1.000; &lt;br /&gt;
                           // * je höher dieser Wert deso genauer das Ergebnis.&lt;br /&gt;
                           // * je höher dieser Wert ist deso niedriger  müssen&lt;br /&gt;
                           //   die Interpolationswerte sein&lt;br /&gt;
&lt;br /&gt;
procedure BeimStart;&lt;br /&gt;
begin&lt;br /&gt;
{..}&lt;br /&gt;
  // Im Interpolations Array werden mit den Werten die von Interpolation_Max bis 0 gehen gefüllt.&lt;br /&gt;
  // wobei Interpolation[0] = Interpolation_Max ist&lt;br /&gt;
  // und Interploation[high(Interpolation)] = 0 ist&lt;br /&gt;
  for i := 0 to high(Interpolation) do Interpolation[I] := round((cos(pi/(Interpolation_Bereich-1)*i)+1)/2*Interpolation_Max);&lt;br /&gt;
{..}&lt;br /&gt;
end;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function Interpoliere(Wert1, Wert2: Integer; Nr, Von: Integer): Integer;&lt;br /&gt;
// Interpoliert zwischen 2 Werten&lt;br /&gt;
// Nr ist gibt den Punkt an den man ermitteln möchte. Von die Anzahl der Interpolations schrite&lt;br /&gt;
var&lt;br /&gt;
  Wert1_Faktor:Integer;&lt;br /&gt;
begin&lt;br /&gt;
  if Nr &amp;gt; Von then raise ERangeError.CreateFmt('Nr Wert %d nicht in 0..%d',[Nr,Von-1]);&lt;br /&gt;
  if Von &amp;gt; Interpolations_Bereich raise ERangeError.CreateFmt('Von Wert %d nicht in 0..%d',[0,-1]);&lt;br /&gt;
  Wert1_Faktor := Interpolation[(Interpolation_Bereich*  Nr)div Von];&lt;br /&gt;
  result := (Wert1*Wert1_Faktor) div Interpolation_Max&lt;br /&gt;
   + (Wert2*(1000 - Wert1_Faktor)) div Interpolation_Max;&lt;br /&gt;
end;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dies wäre die [[Interpolation]] für eine 1 Dimensionale Positionsangabe. Natürlich müssen aber auch die anderen Dimensionen [[Interpolation|interpoliert]] werden. Dies kann aber (wenn gewünscht) ebenfalls mit mehreren [[Interpolation]]en von 2 Werten erfolgen&lt;br /&gt;
 PosX = Ganzzahl( Position.x )&lt;br /&gt;
 PosY = Ganzzahl( Position.y )&lt;br /&gt;
 X1 = Interpoliere( Random( PosX, PosY ), Random( PosX, PosY + 1 ), Nachkommateil( Position.y ) )&lt;br /&gt;
 X2 = Interpoliere( Random( PosX + 1, PosY), Random( PosX + 1, PosY + 1, Nachkommateil( Position.y ) )&lt;br /&gt;
 Ergebnis = Interpoliere( X1, X2, Nachkommateil( Position.x ) )&lt;br /&gt;
&lt;br /&gt;
=Algorithmus=&lt;br /&gt;
Mit den oben beschriebenen Funktionen ist der Algorithmus recht schnell zu machen.&lt;br /&gt;
&lt;br /&gt;
==Die Parameter==&lt;br /&gt;
Der Perlin Noise Algorithmus erhält üblicherweise folgende Parameter:&lt;br /&gt;
*Double: Position (Die Position wird bereits entsprechend skaliert)&lt;br /&gt;
*Double: Persistenz (wie stark ist der Einfluss der höheren Frequenzen)&lt;br /&gt;
*Wertebereich: Double: Min, Double: Max&lt;br /&gt;
*Integer: Rechentiefe (Detailgrad)&lt;br /&gt;
*Gegebenenfalls Double: Frequenzfaktor (oder Standard auf 2)&lt;br /&gt;
Die Laufzeit für einen berechneten Wert beträgt [[O-Notation|O]]( n ) wobei n die Rechentiefe angibt.&lt;br /&gt;
&lt;br /&gt;
==Überlagerung der Frequenzen==&lt;br /&gt;
Es wird für jeden Detailgrad ein Wert berechnet. Da Perlin Noise für einen einzelnen Wert kaum Sinn macht und im Normalfall für mehrere nebeneinander liegende Positionen ein Wert berechnet wird, kann man auch von Frequenzbändern sprechen. Der Code könnte beispielsweise so aussehen:&lt;br /&gt;
 Wert = 0&lt;br /&gt;
 Für jeden Detailgrad&lt;br /&gt;
  Wert = Wert + InterpolierterWert( Position * Frequenz )&lt;br /&gt;
  Frequenz = Frequenz * Frequenzfaktor&lt;br /&gt;
Wie hier unschwer zu erkennen ist werden die Werte addiert (also überlagert).&lt;br /&gt;
&lt;br /&gt;
[[Bild:PerlinUeberlagerung.png|center|framed|''Abb.1: Frequenzbänder für 200 Werte (Pixel).''&amp;lt;br&amp;gt;&lt;br /&gt;
''Frequenzfaktor = 2; Persitenz = 0.5;''&amp;lt;br&amp;gt;&lt;br /&gt;
''Links oben: Frequenz 0.01 (Einheit = Pixel)''&amp;lt;br&amp;gt;&lt;br /&gt;
''Rechts oben: Frequenz 0.02''&amp;lt;br&amp;gt;&lt;br /&gt;
''Links unten: Frequenz 0.04''&amp;lt;br&amp;gt;&lt;br /&gt;
''Rechts unten: überlagerte (addierte) Frequenzbänder (für die ersten 3 Detailgrade)'']]&lt;br /&gt;
&lt;br /&gt;
==Rechentiefe==&lt;br /&gt;
Die Rechentiefe gibt an wie hoch der Detailgrad sein soll. In Abbildung 1 (siehe Frequenzen) wurde beispielsweise eine Rechentiefe von 3 verwendet. Bei einem 2 Dimensionalen Perlin Noise dürfte dies jedoch deutlichere Unterschiede zeigen (siehe Abbildung 2).&lt;br /&gt;
&lt;br /&gt;
[[Bild:PerlinTiefe.png|center|framed|''Abb. 2: Unterschiedliche Rechentiefen.''&amp;lt;br&amp;gt;&lt;br /&gt;
''Frequenzfaktor = 2; Persitenz = 0.5;''&amp;lt;br&amp;gt;&lt;br /&gt;
''Links oben: Rechentiefe 1''&amp;lt;br&amp;gt;&lt;br /&gt;
''Rechts oben: Rechentiefe 2''&amp;lt;br&amp;gt;&lt;br /&gt;
''Links unten: Rechentiefe 3''&amp;lt;br&amp;gt;&lt;br /&gt;
''Rechts unten: Rechentiefe 4'']]&lt;br /&gt;
&lt;br /&gt;
==Persistenz==&lt;br /&gt;
Die Persistenz gibt an wie stark die höheren Frequenzbänder Einfluss auf das Ergebnis haben sollen. Hierfür erweitern wir den unter '''Überlagerung der Frequenzen''' angegebenen Code:&lt;br /&gt;
 Wert = 0&lt;br /&gt;
 Faktor = 1&lt;br /&gt;
 Für Detailgrad = 1 bis Rechentiefe&lt;br /&gt;
  Wert = Wert + InterpolierterWert( Position * Frequenz ) * Faktor&lt;br /&gt;
  Frequenz = Frequenz * Frequenzfaktor&lt;br /&gt;
  Faktor = Faktor * Persistenz&lt;br /&gt;
&lt;br /&gt;
[[Bild:PerlinPersistenz.png|center|framed|&lt;br /&gt;
''Abb. 3: Unterschiedliche Persistenzen.''&amp;lt;br&amp;gt;&lt;br /&gt;
''Frequenzfaktor = 2; Rechentiefe = 5''&amp;lt;br&amp;gt;&lt;br /&gt;
''Links oben: Persistenz 0.2''&amp;lt;br&amp;gt;&lt;br /&gt;
''Rechts oben: Persistenz 0.4''&amp;lt;br&amp;gt;&lt;br /&gt;
''Links unten: Persistenz 0.6''&amp;lt;br&amp;gt;&lt;br /&gt;
''Rechts unten: Persistenz 0.8'']]&lt;br /&gt;
&lt;br /&gt;
==Der Wertebereich==&lt;br /&gt;
Bisher wurden zwar in den Bildern die Werte korrekt dargestellt, jedoch wurde noch nicht erklärt wie man zu diesen Werten kommt. Wir möchten nun den Code welcher unter Persistenz angegeben wurde so modifizieren, das er Werte für den Wertebereich [Min|Max] liefert. Betrachten wir vorerst was wir alles verwenden:&lt;br /&gt;
*InterpolierterWert( Position * Frequenz ): liefert einen Wert im Bereich [-1|1]&lt;br /&gt;
*Faktor: zu Beginn 1, wird bei jeden Durchlauf mit Persistenz multipliziert&lt;br /&gt;
*Frequenz und Frequenzfaktor: spielen für die Amplitude keine Rolle&lt;br /&gt;
Der Gesamtfaktor lässt sich recht einfach berechnen:&lt;br /&gt;
 Faktor = 1&lt;br /&gt;
 GesFaktor = 0&lt;br /&gt;
 Für Deteilgrad = 1 bis Rechentiefe&lt;br /&gt;
  GesFaktor = GesFaktor + Faktor&lt;br /&gt;
  Faktor = Faktor * Persistenz&lt;br /&gt;
Mit dem errechneten Gesamtfaktor wissen wir nun, das die Funktion einen Wert im Bereich &lt;br /&gt;
&lt;br /&gt;
[-GesFaktor|+GesFaktor] liefert. Nun brauchen wir nur noch die Amplitude skalieren und einen entsprechenden Offset für das Minimum addieren. Dies sieht im Endeffekt so aus:&lt;br /&gt;
&lt;br /&gt;
Initialisierung:&lt;br /&gt;
 Bereich = Max - Min;   &lt;br /&gt;
 Offset = Min + Bereich * 0.5;&lt;br /&gt;
 GesFaktor = 0;&lt;br /&gt;
 Faktor = 2;&lt;br /&gt;
 &lt;br /&gt;
 für 1 bis Rechentiefe&lt;br /&gt;
   GesFaktor += Faktor&lt;br /&gt;
   Faktor = Faktor * Persistenz&lt;br /&gt;
 &lt;br /&gt;
 Tiefe_1_Amplitude =   Bereich / GesFaktor&lt;br /&gt;
&lt;br /&gt;
Berechnung eines Wertes:&lt;br /&gt;
 Wert = 0&lt;br /&gt;
 Faktor = Tiefe_1_Amplitude&lt;br /&gt;
 Frequenz = 1&lt;br /&gt;
 Für Detailgrad = 1 bis Rechentiefe&lt;br /&gt;
   Wert = Wert + InterpolierterWert( Position * Frequenz ) * Faktor&lt;br /&gt;
   Frequenz = Frequenz * Frequenzfaktor&lt;br /&gt;
   Faktor = Faktor * Persistenz&lt;br /&gt;
 &lt;br /&gt;
 Wert = Wert + Offset&lt;br /&gt;
&lt;br /&gt;
= Weiterführendes =&lt;br /&gt;
== Einsatzgebiete ==&lt;br /&gt;
Neben der Generierung von Texturen und [[Heightmap]]s - welche von den Grafiken und Quellcodes in diesem Artikel bevorzugt behandelt wurden - gibt es natürlich noch andere Einsatzgebiete. Einige davon sind:&lt;br /&gt;
* Animation, also gehen, Mimik oder jede andere Form von Bewegung kann durch Perlin Noise abwechslungsreicher und somit etwas &amp;quot;menschlicher&amp;quot; gestaltet werden. Der Erfinder Ken Perlin hat hierfür auf seiner [http://mrl.nyu.edu/~perlin/ Homepage] ein paar gute Beispiele.&lt;br /&gt;
* Modifikation von Meshes: was bei [[Heightmap]]s am offensichtlichesten ist kann man auch auf eine Kugel anwenden um einen wunderbar unregelmäßigen, aber dennoch realistisch wirkenden Stein, Planeten oder einen Kometen daraus zu machen.&lt;br /&gt;
* Denkbar wäre die Verwendung von Perlin Noise natürlich auch für verschiedenste Umwelteinflüsse wie Wind (was sich sowohl in Animationen als auch Geräuschlautstärke auswirken kann), aber natürlich auch für künstliche Einflüsse wie Börsenkurse in einem Strategiespiel.&lt;br /&gt;
* Prozedurale Texturen (u.a. Holz-, Stein-, oder Marmor-Oberflächen) können gut mit Perlin Noise und einigen Zusatzfunktionen erzeugt werden.&lt;br /&gt;
&lt;br /&gt;
== Erweiterungen ==&lt;br /&gt;
Perlin Noise kann (wie nahezu jeder andere Algorithmus auch) nach eigenen Wünschen modifiziert werden. Häufige Modifikationen sind:&lt;br /&gt;
* Tilebare Texturen erstellen, also Texturen welche links und rechts - und ggf. auch oben und unten - exakt gleich aussehen. Dieses Problem wird in [http://www.delphigl.com/forum/viewtopic.php?t=3859&amp;amp;postdays=0&amp;amp;postorder=asc&amp;amp;start=15 diesem DGL-Forenthread (ab Seite 2)] etwas näher behandelt.&lt;br /&gt;
* Nachbearbeitung der Ausgabewerte. Hier können wir das endgültige Resultat noch sehr stark verändern. Denkbar wäre hier beispielsweise, dass wir die Unterwasser und über Wasser - Landschaft ganz unterschiedlich skalieren. Das eindrucksvollste Beispiel hierfür dürfte jedoch ein Algorithmus für eine [[Himmel]]stextur sein, welcher [http://freespace.virgin.net/hugo.elias/models/m_clouds.htm hier] zu finden ist. Dieser Algorithmus verwendet einfaches Perlin Noise, modifiziert jedoch die Ausgabewerte mit einer Exponentialfunktion, wodurch eine (meines Erachtens) eindrucksvolle Wolkendecke entsteht. Das endgültige Ergebnis des Algorithmus beinhaltet natürlich noch etwas mehr als diese einfache Exponentialfunktion, jedoch könnte man auch dies im weiteren Sinne als Modifikation der Ausgabewerte sehen.&lt;br /&gt;
&lt;br /&gt;
== Verwandte Themen ==&lt;br /&gt;
Die Dekomprimierung von JPEG-Bildern basiert auf der Überlagerungen von Cosinus-Schwingungen einer vorgegebenen Frequenz und einer (von Bild zu Bild) variierenden Amplitude. Diese Überlagerung ist sehr ähnlich der Frequenzüberlagerung beim Perlin Noise. Der Unterschied ist natürlich, dass bei JPEG Cosinus Schwingungen verwendet werden und beim Perlin Noise zufällige Werte welche [[Interpolation|interpoliert]] werden.&lt;br /&gt;
&lt;br /&gt;
Die Komprimierung von JPEG-Bildern bildet nun das Gegenteil der Überlagerung von Cosinus-Schwingungen, also der Berechnung der Amplituden der einzelnen Frequenzen. Derartige Berechnungen basieren alle auf der Fourier Transformation.&lt;br /&gt;
&lt;br /&gt;
Also wenn ihr nun verstanden habt wozu die Überlagerung von verschiedenen Frequenzbändern in der Lage ist (wofür dieser Artikel hoffentlich hilfreich war), euch diverse Themen der Mathematik wie integrieren, differenzieren und vor allem Regression nicht allzu sehr abschrecken und ihr immer schon mal wissen wolltet wie derartige Bildkompression oder die Frequenzbalken eurer Audiowidergabe entstehen, wäre wohl nun ein (neuer?) Anlauf vielversprechend.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]] [[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=SwapBuffers&amp;diff=23210</id>
		<title>SwapBuffers</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=SwapBuffers&amp;diff=23210"/>
				<updated>2009-03-31T18:36:00Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: Hinweis zu ShowModal eingefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SwapBuffers =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
'''SwapBuffers''' - tauscht Back- und Frontbuffer aus.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 '''function''' SwapBuffers(''DC'' : HDC) : Boolean;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
{| border=1 rules=all&lt;br /&gt;
! '''DC'''&lt;br /&gt;
|Steht für den Device Kontext und bezeichnet die aktuelle Zeichenfläche&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
Die Funktion SwapBuffers tauscht Back- und Frontbuffer aus.&amp;lt;br&amp;gt;&lt;br /&gt;
Diese Methode ist essentiell für das [[Doppelpufferung|Doublebuffering]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Zugehörige Wertrückgaben ==&lt;br /&gt;
Diese Funktion liefert TRUE zurück, wenn der Buffertausch vollzogen werden konnte. Andernfalls wird FALSE zurückgeliefert.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Funktionalität == &lt;br /&gt;
SwapBuffers funktioniert nicht, wenn ein modales Formular angezeigt wird. In diesem Fall liefert die Funktion FALSE zurück.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Siehe auch ==&lt;br /&gt;
[[Doppelpufferung|Doublebuffering]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Screenshot&amp;diff=22495</id>
		<title>Screenshot</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Screenshot&amp;diff=22495"/>
				<updated>2009-01-24T14:29:07Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: /* Speichern im TGA-Format bei Nutzung von SDL */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Allgemeines zum Screenshot erstellen ==&lt;br /&gt;
=== Einleitung ===&lt;br /&gt;
Ein '''Screenshot''' ist ein Abbild des aktuellen Bildschirm Inhaltes. &lt;br /&gt;
&lt;br /&gt;
Im Falle von OpenGL greifen wir nicht auf das Fenster zurück sondern auf den [[Framebuffer]]. Neben dem eigentlichen Vorgang des Bilddatenbesorgens ist es meistens auch noch sinnvoll die Daten dem Benutzer verfügbar zu machen. Dies geschieht meistens in Form einer Bild-Datei oder eines Eintrages in der Zwischenablage.&lt;br /&gt;
&lt;br /&gt;
=== Bilddaten besorgen ===&lt;br /&gt;
Mit Hilfe des [[glReadPixels]] Befehls kann der [[Framebuffer]] ausgelesen werden. Für einen Screenshot sind meistens die [[RGB]]-Werte interessant. Bei diesen Werten ergibt sich auch schon das erste Problem: OpenGL speichert die Daten in der Reihenfolge Rot Grün Blau, während es in einigen Bildformaten (nämlich denen die auf Bitmaps aufbauen) üblich ist, die Daten in der Reihenfolge Blau Grün Rot zu speichern. Glücklicherweise kann man in aktuellen OpenGL Versionen [[glReadPixels]] anweisen die Daten auch in dieser Reihenfolge zu liefern.&lt;br /&gt;
&lt;br /&gt;
Der [[glReadPixels]] Befehl für neue Grafikkarten könnte in etwa so aussehen:&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
  // ungünstige Reihenfolge Rot Grün Blau &lt;br /&gt;
  glReadPixels( 0, 0, Breite, Hoehe, GL_RGB, GL_UNSIGNED_BYTE, Daten );&lt;br /&gt;
  // auf neueren Grafikkarten:&lt;br /&gt;
  glReadPixels( 0, 0, Breite, Hoehe, GL_BGR, GL_UNSIGNED_BYTE, Daten );&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Was die einzelnen Parameter bedeuten, könnt ihr im [[glReadPixels]] Artikel nachlesen. Es sei hier nur gesagt das das letzte Argument der Speicherplatz ist, an dem OpenGL die Daten abspeichern soll (meist ein Pointer z.B. auf ein Array).&lt;br /&gt;
&lt;br /&gt;
=== Hinweis ===&lt;br /&gt;
Unter [[SDL]] finden sich die Bilddaten schon in der [[SDL_Surface|Displaysurface]] unter ''pixels''.&lt;br /&gt;
&lt;br /&gt;
== Speichern des Screenshots ==&lt;br /&gt;
Die Speicherung der Screenshots ist, sofern man erst einmal die Rohdaten der einzelnen Pixel hat, nicht mehr allzu kompliziert. Da der Computer aber ohne zusätzliche Informationen zu diesen Rohdaten später nichts mehr mit ihnen anfangen könnte, muss man einige zusätzliche Informationen mit in seine Zieldatei schreiben, die oftmals als &amp;quot;Header&amp;quot; bezeichnet werden und Informationen zu Breite, Höhe und &amp;quot;Pixelformat&amp;quot; beinhalten.&lt;br /&gt;
&lt;br /&gt;
=== Speichern im BMP Format ===&lt;br /&gt;
&lt;br /&gt;
Eine BMP-Datei hat einen relativ einfachen Aufbau. Als erstes kommen Header-Informationen (das Zeugs, was die Daten als Bitmap ausweist ;-)), dann FileInfo-Informationen (das, was angibt, wie groß das Bitmap ist) und schließlich die eigentlichen Bilddaten.&lt;br /&gt;
&lt;br /&gt;
Der Header sieht so aus:&lt;br /&gt;
&amp;lt;pascal&amp;gt; BITMAPFILEHEADER = packed record&lt;br /&gt;
    bfType: Word;&lt;br /&gt;
    bfSize: DWORD;&lt;br /&gt;
    bfReserved1: Word;&lt;br /&gt;
    bfReserved2: Word;&lt;br /&gt;
    bfOffBits: DWORD;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
 BITMAPINFOHEADER = packed record&lt;br /&gt;
    biSize: DWORD;&lt;br /&gt;
    biWidth: Longint;&lt;br /&gt;
    biHeight: Longint;&lt;br /&gt;
    biPlanes: Word;&lt;br /&gt;
    biBitCount: Word;&lt;br /&gt;
    biCompression: DWORD;&lt;br /&gt;
    biSizeImage: DWORD;&lt;br /&gt;
    biXPelsPerMeter: Longint;&lt;br /&gt;
    biYPelsPerMeter: Longint;&lt;br /&gt;
    biClrUsed: DWORD;&lt;br /&gt;
    biClrImportant: DWORD;&lt;br /&gt;
  end;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun zur Speicherfunktion für einen Screenshot:&lt;br /&gt;
&amp;lt;pascal&amp;gt;procedure ScreenShot(const Name : string);&lt;br /&gt;
 var F : file;&lt;br /&gt;
     FileInfo: BITMAPINFOHEADER;&lt;br /&gt;
     FileHeader : BITMAPFILEHEADER;&lt;br /&gt;
     pPicData:Pointer;&lt;br /&gt;
     Viewport : array[0..3] of integer;&lt;br /&gt;
begin&lt;br /&gt;
 //Speicher für die Speicherung der Header-Informationen vorbereiten&lt;br /&gt;
 ZeroMemory(@FileHeader, SizeOf(BITMAPFILEHEADER));&lt;br /&gt;
 ZeroMemory(@FileInfo, SizeOf(BITMAPINFOHEADER));&lt;br /&gt;
&lt;br /&gt;
 //Größe des Viewports abfragen --&amp;gt; Spätere Bildgrößenangaben&lt;br /&gt;
 glGetIntegerv(GL_VIEWPORT, @Viewport);&lt;br /&gt;
&lt;br /&gt;
 //Initialisieren der Daten des Headers&lt;br /&gt;
 FileHeader.bfType := 19778; //$4D42 = 'BM'&lt;br /&gt;
 FileHeader.bfOffBits := SizeOf(BITMAPINFOHEADER)+SizeOf(BITMAPFILEHEADER);&lt;br /&gt;
&lt;br /&gt;
 //Schreiben der Bitmap-Informationen&lt;br /&gt;
 FileInfo.biSize := SizeOf(BITMAPINFOHEADER);&lt;br /&gt;
 FileInfo.biWidth := Viewport[2];&lt;br /&gt;
 FileInfo.biHeight := Viewport[3];&lt;br /&gt;
 FileInfo.biPlanes := 1;&lt;br /&gt;
 FileInfo.biBitCount := 32;&lt;br /&gt;
 FileInfo.biSizeImage := FileInfo.biWidth*FileInfo.biHeight*(FileInfo.biBitCount div 8);&lt;br /&gt;
&lt;br /&gt;
 //Größenangabe auch in den Header übernehmen&lt;br /&gt;
 FileHeader.bfSize := FileHeader.bfOffBits + FileInfo.biSizeImage;&lt;br /&gt;
&lt;br /&gt;
 //Speicher für die Bilddaten reservieren&lt;br /&gt;
 GetMem(pPicData, FileInfo.biSizeImage);&lt;br /&gt;
 try&lt;br /&gt;
  //Bilddaten von OpenGL anfordern (siehe oben)&lt;br /&gt;
  glReadPixels(0, 0, Viewport[2], Viewport[3], GL_BGRA, GL_UNSIGNED_BYTE, pPicData);&lt;br /&gt;
&lt;br /&gt;
  //Und den ganzen Müll in die Datei schieben ;-)&lt;br /&gt;
  //Moderne Leute nehmen dafür auch Streams ...&lt;br /&gt;
  AssignFile(f, name);&lt;br /&gt;
  Rewrite( f,1 );&lt;br /&gt;
  try&lt;br /&gt;
   BlockWrite(F, FileHeader, SizeOf(BITMAPFILEHEADER));&lt;br /&gt;
   BlockWrite(F, FileInfo, SizeOf(BITMAPINFOHEADER));&lt;br /&gt;
   BlockWrite(F, pPicData^, FileInfo.biSizeImage );&lt;br /&gt;
  finally&lt;br /&gt;
   CloseFile(f);&lt;br /&gt;
  end;&lt;br /&gt;
 finally&lt;br /&gt;
  //Und den angeforderten Speicher wieder freigeben ...&lt;br /&gt;
  FreeMem(pPicData, FileInfo.biSizeImage);&lt;br /&gt;
 end;&lt;br /&gt;
end;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Speichern im TGA Format ===&lt;br /&gt;
&lt;br /&gt;
Eine TGA-Datei hat einen ähnlich einfachen Aufbau. Als erstes kommen auch hier Header-Informationen und dannach die eigentlichen Daten.&lt;br /&gt;
&lt;br /&gt;
Der Header sieht diesmal so aus:&lt;br /&gt;
&amp;lt;pascal&amp;gt;type &lt;br /&gt;
  TTGAHEADER = packed record&lt;br /&gt;
    tfType : Byte;&lt;br /&gt;
    tfColorMapType : Byte;&lt;br /&gt;
    tfImageType : Byte;&lt;br /&gt;
    tfColorMapSpec : Array[0..4] of Byte;&lt;br /&gt;
    tfOrigX : Word; //Array [0..1] of Byte;&lt;br /&gt;
    tfOrigY : Word;&lt;br /&gt;
    tfWidth : Word;&lt;br /&gt;
    tfHeight : Word;&lt;br /&gt;
    tfBpp : Byte;&lt;br /&gt;
    tfImageDes : Byte;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
Nun zur Speicherfunktion für ein Screenshot ohne Alpha Wert&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure ScreenShot(const Name : string);&lt;br /&gt;
var &lt;br /&gt;
  DataBuffer : array of Byte;&lt;br /&gt;
  f : file;&lt;br /&gt;
  tgaHeader : TTGAHEADER;&lt;br /&gt;
  width, height : integer;&lt;br /&gt;
  DataSize:Integer;&lt;br /&gt;
  viewport : Array[0..3] of integer;&lt;br /&gt;
begin&lt;br /&gt;
  //Viewport-Größe lesen&lt;br /&gt;
  glGetIntegerv(GL_VIEWPORT, @viewport);&lt;br /&gt;
  width := viewport[2];&lt;br /&gt;
  height := viewport[3];&lt;br /&gt;
&lt;br /&gt;
  //Größe der Daten berechnen&lt;br /&gt;
  DataSize := Width * Height * 3;&lt;br /&gt;
&lt;br /&gt;
  //Größe des Puffers festlegen (Speicher reservieren)&lt;br /&gt;
  SetLength(DataBuffer,DataSize);&lt;br /&gt;
&lt;br /&gt;
  // TGA Kopf mit Daten füllen&lt;br /&gt;
  ZeroMemory(@tgaHeader, SizeOf(tgaHeader));&lt;br /&gt;
  tgaHeader.tfImageType := 2; // TGA_RGB = 2&lt;br /&gt;
  tgaHeader.tfWidth := Width; &lt;br /&gt;
  tgaHeader.tfHeight := Height;&lt;br /&gt;
  tgaHeader.tfBpp := 24;&lt;br /&gt;
&lt;br /&gt;
  //Daten von OpenGL anfordern&lt;br /&gt;
  glReadPixels(0,0,Width, Height, GL_BGR, GL_UNSIGNED_BYTE, @DataBuffer[0]);&lt;br /&gt;
  &lt;br /&gt;
  //Datei erstellen&lt;br /&gt;
  AssignFile(f, Name);&lt;br /&gt;
  Rewrite( f,1 );&lt;br /&gt;
  try &lt;br /&gt;
    // TGA Kopf in die Datei reinschreiben&lt;br /&gt;
    BlockWrite(F, tgaHeader, SizeOf(tgaHeader));&lt;br /&gt;
&lt;br /&gt;
    // Die eigentlichen Bilddaten in die Datei schreiben&lt;br /&gt;
    BlockWrite(f, DataBuffer[0], DataSize );&lt;br /&gt;
  finally&lt;br /&gt;
    CloseFile(f);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Speichern im TGA-Format bei Nutzung von SDL ===&lt;br /&gt;
&lt;br /&gt;
Das Speichern eines Screenshots im TGA-Format sieht auch bei Nutzung von SDL nicht wesentlich anders aus. Als erstes müssen die Units sdl und sdl_utils eingebunden sein, was aber sicherlich schon der Fall ist. Ansonsten einfach kurz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;uses&lt;br /&gt;
    sdl, sdl_utils;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
und wir hätten auch dies erledigt.&lt;br /&gt;
&lt;br /&gt;
Was sich allerdings etwas unterscheided, ist, dass man gegebenenfalls einige Vorkehrungen treffen muss, um die richtige Reihenfolge der einzelnen Farbkanäle zu gewährleisten, was mit folgender Routine ein leichtes ist:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;procedure SwapBGR(Surface: PSDL_Surface);&lt;br /&gt;
var&lt;br /&gt;
  x,y: Integer;&lt;br /&gt;
  pixel: UInt32;&lt;br /&gt;
  pred, pgreen, pblue, palpha: PUInt8;&lt;br /&gt;
  red, green, blue, alpha: UInt8;&lt;br /&gt;
begin&lt;br /&gt;
  for y:=0 to (Surface.h-1) do&lt;br /&gt;
    for x:=0 to (Surface.w-1) do&lt;br /&gt;
    begin&lt;br /&gt;
      //reads the pixels them&lt;br /&gt;
      pixel:=SDL_GetPixel(Surface, x, y);&lt;br /&gt;
&lt;br /&gt;
      pred:=@red;&lt;br /&gt;
      pgreen:=@green;&lt;br /&gt;
      pblue:=@blue;&lt;br /&gt;
      palpha:=@alpha;&lt;br /&gt;
&lt;br /&gt;
      //read and swap color&lt;br /&gt;
      SDL_GetRGBA(pixel,Surface.format, pred, pgreen, pblue, palpha);&lt;br /&gt;
      pixel:=SDL_MapRGBA(Surface.format, blue, green, red, alpha);&lt;br /&gt;
&lt;br /&gt;
      SDL_PutPixel(Surface, x, y, pixel);&lt;br /&gt;
    end;&lt;br /&gt;
end;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier benötigen wir wieder den TGA-Header als Record:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;type&lt;br /&gt;
  TTGAHEADER = packed record&lt;br /&gt;
    tfType  : Byte;&lt;br /&gt;
    tfColorMapType : Byte;&lt;br /&gt;
    tfImageType    : Byte;&lt;br /&gt;
    tfColorMapSpec : Array[0..4] of Byte;&lt;br /&gt;
    tfOrigX    : Word;&lt;br /&gt;
    tfOrigY    : Word;&lt;br /&gt;
    tfWidth    : Word;&lt;br /&gt;
    tfHeight   : Word;&lt;br /&gt;
    tfBpp      : Byte;&lt;br /&gt;
    tfImageDes : Byte;&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nach diesen kleinen Vorbereitungen folgt eigentlich auch, wie gewohnt, der normale Code zum Speichern, nur eben mit SDL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;//Speichert eine Surface in eine TGA-Datei.&lt;br /&gt;
//Surface wird am Ende freigegeben. Die Videosurface sollte also vorher geblittet werden&lt;br /&gt;
//und diese dann weitergereicht werden.&lt;br /&gt;
function SaveSurfacetoTGA(filename: String; surface: PSDL_Surface): Boolean;&lt;br /&gt;
var&lt;br /&gt;
  TGAHEADER : TTGAHEADER;&lt;br /&gt;
&lt;br /&gt;
  rwop: PSDL_RWops;&lt;br /&gt;
  ImageSize: Integer;&lt;br /&gt;
  i : Integer;&lt;br /&gt;
begin&lt;br /&gt;
  Result:=False;&lt;br /&gt;
&lt;br /&gt;
  //Prüfen, ob's was zu Speichern gibt ...  &lt;br /&gt;
  if not Assigned(surface) then&lt;br /&gt;
  begin&lt;br /&gt;
    writeln('Keine Surface übergeben');&lt;br /&gt;
    exit;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  //Haben wir ein Pixelformat mit mindestens 24 Bit?&lt;br /&gt;
  if surface.format.BytesPerPixel&amp;lt;3 then&lt;br /&gt;
  begin&lt;br /&gt;
    writeln('Farbtiefe nicht unterstützt');&lt;br /&gt;
    exit;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  //Müssen wir die Reihenfolge der Farbkanäle anpassen?&lt;br /&gt;
  if SDL_BYTEORDER&amp;lt;&amp;gt;SDL_BIG_ENDIAN then&lt;br /&gt;
  begin&lt;br /&gt;
    SwapBGR(surface);&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  //Na gut, füllen wir den Header aus ...&lt;br /&gt;
  with TGAHEADER do&lt;br /&gt;
  begin&lt;br /&gt;
    tfType:=0;&lt;br /&gt;
    tfColorMapType:=0;&lt;br /&gt;
    tfImageType:=2;&lt;br /&gt;
    for i:=0 to 4 do&lt;br /&gt;
      tfColorMapSpec[i]:=0;&lt;br /&gt;
    tfOrigX:=0;&lt;br /&gt;
    tfOrigY:=0;&lt;br /&gt;
    tfWidth:=surface.w;&lt;br /&gt;
    tfHeight:=surface.h;&lt;br /&gt;
    tfBpp:=surface.format.BitsPerPixel;&lt;br /&gt;
    tfImageDes:=0;&lt;br /&gt;
  end;&lt;br /&gt;
&lt;br /&gt;
  //Ermitteln des benötigten Speicherplatze...&lt;br /&gt;
  ImageSize:=surface.w*surface.h*surface.format.BytesPerPixel;&lt;br /&gt;
&lt;br /&gt;
  //Datei zum Schreiben öffnen.&lt;br /&gt;
  rwop:=SDL_RWfromFile(PChar(filename),'w+b');&lt;br /&gt;
  if rwop=nil then&lt;br /&gt;
  begin&lt;br /&gt;
    Writeln('Fehler beim Erstellen des Rwops');&lt;br /&gt;
    exit;&lt;br /&gt;
  end;&lt;br /&gt;
  try&lt;br /&gt;
    //Versuchen, den Header in die Datei zu schreiben&lt;br /&gt;
    if SDL_RWWrite(rwop,@TGAHEADER,SizeOf(TGAHEADER),1)&amp;lt;&amp;gt;1 then&lt;br /&gt;
    begin&lt;br /&gt;
      writeln('Fehler beim Schreiben des Headers');&lt;br /&gt;
      exit;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    //Versuchen, die Bilddaten in die Datei zu schreibenSchreiben der Bilddaten&lt;br /&gt;
    if SDL_RWWrite(rwop,surface.pixels,ImageSize,1)&amp;lt;&amp;gt;1 then&lt;br /&gt;
    begin&lt;br /&gt;
      writeln('Fehler beim Schreiben der Daten');&lt;br /&gt;
      exit;&lt;br /&gt;
    end;&lt;br /&gt;
&lt;br /&gt;
    //Scheinbar waren wir erfolgreich&lt;br /&gt;
    Result:=True;&lt;br /&gt;
  finally&lt;br /&gt;
    //Datei schließen ...&lt;br /&gt;
    SDL_RWClose(rwop);&lt;br /&gt;
&lt;br /&gt;
    //Und das Surface freigeben&lt;br /&gt;
    SDL_FreeSurface(surface);&lt;br /&gt;
  end;&lt;br /&gt;
end;&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That's it. Have a nice day!&lt;br /&gt;
&lt;br /&gt;
== Siehe Auch ==&lt;br /&gt;
[[Tutorial Renderpass]] (Dieses Tutorial erklärt wie man das gerenderte zu anderen Zwecken verwenden kann.)&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]] [[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Tutorials&amp;diff=22181</id>
		<title>Tutorials</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Tutorials&amp;diff=22181"/>
				<updated>2008-10-14T18:18:47Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: Weiterleitung erstellt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Tutorial]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Text_ausgeben&amp;diff=22180</id>
		<title>Text ausgeben</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Text_ausgeben&amp;diff=22180"/>
				<updated>2008-10-13T17:43:48Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: Überschriftenverschachtelung beginnt bei Ebene 2 (an Wikipedia-Standard angelehnt)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Allen Möglichkeiten gemein ist das die Buchstaben in [[Liste]]n gespeichert werden um so per [[glCallLists]] den Text ausgeben zu können.&lt;br /&gt;
&lt;br /&gt;
== Buchstaben aus Pixeln ==&lt;br /&gt;
&lt;br /&gt;
Die primitivste Art Buchtaben auszugeben besteht darin einfach [[glBitmap]] aufzurufen. &lt;br /&gt;
&lt;br /&gt;
Falls das Betriebssystem Windows ist, kann mit [[wglUseFontBitmaps]] aus einer Windows Schrift [[glBitmap]] Befehle generiert, und in einer [[Liste]] abgespeichert werden.&lt;br /&gt;
&lt;br /&gt;
=== Position festlegen ===&lt;br /&gt;
Die Position der Ausgabe erfolgt durch [[glRasterPos]], oder besser falls verfügbar durch [[glWindowPos]].&lt;br /&gt;
&lt;br /&gt;
=== Farbe ===&lt;br /&gt;
Die [[Farbe]] der Schrift wird zum Zeitpunkt des letzen [[glRasterPos]] Aufrufes festgelegt. Auch wenn danach die atkive Farbe mit [[glColor]] abgeändert wird, ändert sich hierdurch nichts an der Farbe mit der die Buchstaben ausgegeben werden. (siehe [[glRasterPos]])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== 3D Schriften mit Windows ==&lt;br /&gt;
&lt;br /&gt;
Per [[wglUseFontOutlines]] wird aus einer Windows Schrift für jeden Buchstaben eine Liste erstellt, welche die entsprechenden Polygone enthält.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|+Das kann dann so aussehen:&lt;br /&gt;
|[[Bild:WglUseFontOutlines Beispiel.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Schrift aus Texturen ==&lt;br /&gt;
(Sogenannte Texturefonts)&lt;br /&gt;
&lt;br /&gt;
Benötigt wird für diese Technik eine Textur, auf dem alle 256 Zeichen untergebracht sind. Die Anordnung der Zeichen ist prinzipiell beliebig, nur sollte man dies so tun, dass man nachher leicht die Position der einzelnen Zeichen auf der Textur herausfindet. (z.B. indem man die Zeichen als 16x16 Zeichen Matrix anordnet). &lt;br /&gt;
&lt;br /&gt;
Zusätzliche Informationen über die Breite der Buchstaben, ermöglicht es gleich große Zwischenräume zwischen den einzenen Buchstaben zu haben.&lt;br /&gt;
Entsprechende [[Tool]]s erleichtern die Erstellung solcher Texturen.&lt;br /&gt;
&lt;br /&gt;
Die Textur [[Matrix]] wird dann mit  [[glScale]] und [[glTranslate]] so manipuliert, dass das mit [[glBegin]], [[glTexCoord]] und [[glVertex]] gezeichnete Rechteck immer nur ein Zeichen enthält. &lt;br /&gt;
('''glScale''' ist eigentlich nicht nötig, da ein mit [[glTexCoord]] abgesteckter Texturabschnitt automatisch auf die Größe des unterligenden Polygons (gezeichnet mit [[glBegin]]-[[glEnd]] und [[glVertex]]) gedehnt wird.)&lt;br /&gt;
&lt;br /&gt;
Um nur die Buchstaben ohne den Hintergrund (der Textur) zu sehen sollte dieser mittels [[Blenden|Blending]] oder (wenn man scharfe Kanten möchte) mittels [[glAlphaFunc]] heraus gefiltert werden.&lt;br /&gt;
&lt;br /&gt;
=== Position ===&lt;br /&gt;
Das '''Wo''' wird über die Koordinaten der [[Eckpunkt|Eckpunkte]] des unterliegenden Polygons geregelt. Welches Zeichen tatsächlich ausgegeben wird, bestimmen die Texturkoordinaten (übergeben mit [[glTexCoord]]).&lt;br /&gt;
&lt;br /&gt;
=== Farbe ===&lt;br /&gt;
Wenn man eine einfarbige Schrift möchte, so empfiehlt es sich die Textur komplett Weiß zu machen, damit man mit [[glColor]] die Textur einfärben kann und damit alle Farben anzeigen lassen kann. Dies kann beispielsweise auch mittels&lt;br /&gt;
 [[glPixelTransfer]]f( GL_RED_BIAS, 1.0 );&lt;br /&gt;
 [[glPixelTransfer]]f( GL_GREEN_BIAS, 1.0 );&lt;br /&gt;
 [[glPixelTransfer]]f( GL_BLUE_BIAS, 1.0 );&lt;br /&gt;
vor dem Erstellen der Textur erfolgen.&lt;br /&gt;
Der eigentliche Zeichensatz sollte (sofern man einfarbige Schrift möchte) nur den Alpha-Kanal beeinflussen, was beispielsweise mittels&lt;br /&gt;
 [[gluBuild2DMipmaps]]( GL_TEXTURE_2D, 2, Texturbreite, Texturhoehe, GL_ALPHA, GL_UNSIGNED_BYTE, Pixel );&lt;br /&gt;
gemacht werden kann. Zu beachten ist hier, dass 2 oder 4 Farbkomponenten benötigt werden damit die Textur Alphawerte erhält.&lt;br /&gt;
&lt;br /&gt;
Falls der Text nicht im dreidimensionalen Raum angezeigt werden soll, empfiehlt es sich den [[Tiefentest]] zu deaktivieren und die Projektions Matrix mit [[gluOrtho2D]] neu einzustellen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[glBegin]], [[glColor]], [[glScale]], [[glTranslate]], [[glTexCoord]], [[glVertex]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]][[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Text_ausgeben&amp;diff=22179</id>
		<title>Text ausgeben</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Text_ausgeben&amp;diff=22179"/>
				<updated>2008-10-13T17:40:52Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: Oberste Überschrift entfernt &amp;amp; dreidimensional in ein Wort gepackt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Allen Möglichkeiten gemein ist das die Buchstaben in [[Liste]]n gespeichert werden um so per [[glCallLists]] den Text ausgeben zu können.&lt;br /&gt;
&lt;br /&gt;
= Buchstaben aus Pixeln =&lt;br /&gt;
&lt;br /&gt;
Die primitivste Art Buchtaben auszugeben besteht darin einfach [[glBitmap]] aufzurufen. &lt;br /&gt;
&lt;br /&gt;
Falls das Betriebssystem Windows ist, kann mit [[wglUseFontBitmaps]] aus einer Windows Schrift [[glBitmap]] Befehle generiert, und in einer [[Liste]] abgespeichert werden.&lt;br /&gt;
&lt;br /&gt;
== Position festlegen ==&lt;br /&gt;
Die Position der Ausgabe erfolgt durch [[glRasterPos]], oder besser falls verfügbar durch [[glWindowPos]].&lt;br /&gt;
&lt;br /&gt;
== Farbe ==&lt;br /&gt;
Die [[Farbe]] der Schrift wird zum Zeitpunkt des letzen [[glRasterPos]] Aufrufes festgelegt. Auch wenn danach die atkive Farbe mit [[glColor]] abgeändert wird, ändert sich hierdurch nichts an der Farbe mit der die Buchstaben ausgegeben werden. (siehe [[glRasterPos]])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= 3D Schriften mit Windows &lt;br /&gt;
&lt;br /&gt;
Per [[wglUseFontOutlines]] wird aus einer Windows Schrift für jeden Buchstaben eine Liste erstellt, welche die entsprechenden Polygone enthält.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|+Das kann dann so aussehen:&lt;br /&gt;
|[[Bild:WglUseFontOutlines Beispiel.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Schrift aus Texturen =&lt;br /&gt;
(Sogenannte Texturefonts)&lt;br /&gt;
&lt;br /&gt;
Benötigt wird für diese Technik eine Textur, auf dem alle 256 Zeichen untergebracht sind. Die Anordnung der Zeichen ist prinzipiell beliebig, nur sollte man dies so tun, dass man nachher leicht die Position der einzelnen Zeichen auf der Textur herausfindet. (z.B. indem man die Zeichen als 16x16 Zeichen Matrix anordnet). &lt;br /&gt;
&lt;br /&gt;
Zusätzliche Informationen über die Breite der Buchstaben, ermöglicht es gleich große Zwischenräume zwischen den einzenen Buchstaben zu haben.&lt;br /&gt;
Entsprechende [[Tool]]s erleichtern die Erstellung solcher Texturen.&lt;br /&gt;
&lt;br /&gt;
Die Textur [[Matrix]] wird dann mit  [[glScale]] und [[glTranslate]] so manipuliert, dass das mit [[glBegin]], [[glTexCoord]] und [[glVertex]] gezeichnete Rechteck immer nur ein Zeichen enthält. &lt;br /&gt;
('''glScale''' ist eigentlich nicht nötig, da ein mit [[glTexCoord]] abgesteckter Texturabschnitt automatisch auf die Größe des unterligenden Polygons (gezeichnet mit [[glBegin]]-[[glEnd]] und [[glVertex]]) gedehnt wird.)&lt;br /&gt;
&lt;br /&gt;
Um nur die Buchstaben ohne den Hintergrund (der Textur) zu sehen sollte dieser mittels [[Blenden|Blending]] oder (wenn man scharfe Kanten möchte) mittels [[glAlphaFunc]] heraus gefiltert werden.&lt;br /&gt;
&lt;br /&gt;
== Position ==&lt;br /&gt;
Das '''Wo''' wird über die Koordinaten der [[Eckpunkt|Eckpunkte]] des unterliegenden Polygons geregelt. Welches Zeichen tatsächlich ausgegeben wird, bestimmen die Texturkoordinaten (übergeben mit [[glTexCoord]]).&lt;br /&gt;
&lt;br /&gt;
== Farbe ==&lt;br /&gt;
Wenn man eine einfarbige Schrift möchte, so empfiehlt es sich die Textur komplett Weiß zu machen, damit man mit [[glColor]] die Textur einfärben kann und damit alle Farben anzeigen lassen kann. Dies kann beispielsweise auch mittels&lt;br /&gt;
 [[glPixelTransfer]]f( GL_RED_BIAS, 1.0 );&lt;br /&gt;
 [[glPixelTransfer]]f( GL_GREEN_BIAS, 1.0 );&lt;br /&gt;
 [[glPixelTransfer]]f( GL_BLUE_BIAS, 1.0 );&lt;br /&gt;
vor dem Erstellen der Textur erfolgen.&lt;br /&gt;
Der eigentliche Zeichensatz sollte (sofern man einfarbige Schrift möchte) nur den Alpha-Kanal beeinflussen, was beispielsweise mittels&lt;br /&gt;
 [[gluBuild2DMipmaps]]( GL_TEXTURE_2D, 2, Texturbreite, Texturhoehe, GL_ALPHA, GL_UNSIGNED_BYTE, Pixel );&lt;br /&gt;
gemacht werden kann. Zu beachten ist hier, dass 2 oder 4 Farbkomponenten benötigt werden damit die Textur Alphawerte erhält.&lt;br /&gt;
&lt;br /&gt;
Falls der Text nicht im dreidimensionalen Raum angezeigt werden soll, empfiehlt es sich den [[Tiefentest]] zu deaktivieren und die Projektions Matrix mit [[gluOrtho2D]] neu einzustellen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Siehe auch=&lt;br /&gt;
[[glBegin]], [[glColor]], [[glScale]], [[glTranslate]], [[glTexCoord]], [[glVertex]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Anleitung]][[Kategorie:Technik_oder_Algorithmus]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=glBitmap&amp;diff=22125</id>
		<title>glBitmap</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=glBitmap&amp;diff=22125"/>
				<updated>2008-08-29T10:27:48Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: /* Beispiel */ Formatierung des ersten &amp;quot;nil&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= glBitmap =&lt;br /&gt;
&lt;br /&gt;
{{Hinweis|Den Texturloader &amp;quot;glBitmap&amp;quot; von Lossy eX findet man unter [[Glbitmap_loader]]}}&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
'''glBitmap''' - Zeichnet ein Bitmap.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 procedure '''glBitmap'''(''width,height'': TGLsizei; ''xorig, yorig'': TGLfloat; &lt;br /&gt;
                    ''xmove,ymove'': TGLfloat; '''const''' ''bitmap'': PGLubyte); &lt;br /&gt;
   &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; rules=&amp;quot;all&amp;quot;&lt;br /&gt;
| ''width,height''&lt;br /&gt;
| Bestimmen die Größe der Bitmap.&lt;br /&gt;
|-&lt;br /&gt;
| ''xorig, yorig''&lt;br /&gt;
| Bestimmt den Koordinaten Ursprung(von links,unten) innerhalb des Bitmaps.&lt;br /&gt;
|-&lt;br /&gt;
| ''xmove, ymove''&lt;br /&gt;
| Legt fest um wieviel die aktuelle Rasterposition verschoben werden soll.&lt;br /&gt;
|-&lt;br /&gt;
| ''bitmap''&lt;br /&gt;
| Ein Zeiger auf die Bitmap('''Achtung''': Entspricht nicht dem TBitmap aus Delphi)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
An der aktuellen Rasterposition wird überall dort wo im Bitmap eine 1 ist wird gezeichnet. Der Bereich des Bitmaps der eine 0 beihnhaltet bleibt unberührt.&lt;br /&gt;
Anschließend wird die aktuelle Rasterposition um ''xmove'' und ''ymove'' erhöht.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
Falls die aktuelle Rasterposition ungültig ist, wird glBitmap ignoriert.&lt;br /&gt;
&lt;br /&gt;
Die Fenster-Koordianten an denen das Bitmap gezeichnet wird errechnet man durch:&lt;br /&gt;
&lt;br /&gt;
 Fenster.X := Rasterposition.X - Bitmap_Ursprung.X ;&lt;br /&gt;
 Fenster.Y := Rasterposition.Y - Bitmap_Ursprung.Y ;&lt;br /&gt;
&lt;br /&gt;
[[Bild:GlBitmap.png|right]]&lt;br /&gt;
Möchte man etwa den Buchstaben klein &amp;quot;g&amp;quot; etwas tiefer positionieren so kann man sich diese Eigenschaft von glBitmap zu Nutze machen und den Urspung etwas höher ansetzen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Beim Zeichnen wird die aktuellen Rasterfarbe (bzw. dem aktuellen Raster Index)&lt;br /&gt;
verwendet sowie die aktuellen Raster Textur Koordianten.&lt;br /&gt;
Die Z Position wird von der aktullen Rasterposition bezogen.&lt;br /&gt;
&lt;br /&gt;
Die erzeugten Pixel-Fragmente werden so behandelt als wären sie von Polygon, Linen und Punkten unter der Benutzung  von [[Nebel]], [[texture mapping]] und anderen Pixel Operatoren (wie etwa Alpha- und Tiefen Test) erstellt worden. &lt;br /&gt;
&lt;br /&gt;
Die Bitmaps brauchen zur Speicherung einer Bit-Zeile immer 32 Bit egal wieviel  Spalten davon genutzt werden.&lt;br /&gt;
&lt;br /&gt;
== Fehlermeldungen ==&lt;br /&gt;
GL_INVALID_VALUE wird generiert wenn der Parameter width oder height negativ ist.&lt;br /&gt;
GL_INVALID_OPERATION wird generiert wenn glBitmap zwischen [[glBegin]] und dem dazugehörigen [[glEnd]] aufgerufen wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Zugehörige Wertrückgaben ==&lt;br /&gt;
*[[glGet]] mit Token [[glGet#GL_CURRENT_RASTER_POSITION|GL_CURRENT_RASTER_POSITION]]&lt;br /&gt;
*[[glGet]] mit Token [[glGet#GL_CURRENT_RASTER_COLOR|GL_CURRENT_RASTER_COLOR]]&lt;br /&gt;
*[[glGet]] mit Token [[glGet#GL_CURRENT_RASTER_INDEX|GL_CURRENT_RASTER_INDEX]]&lt;br /&gt;
*[[glGet]] mit Token [[glGet#GL_CURRENT_RASTER_TEXTURE_COORDS|GL_CURRENT_RASTER_TEXTURE_COORDS]]&lt;br /&gt;
*[[glGet]] mit Token [[glGet#GL_CURRENT_RASTER_POSITION_VALID|GL_CURRENT_RASTER_POSITION_VALID]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Beispiel==&lt;br /&gt;
&lt;br /&gt;
 '''type'''&lt;br /&gt;
   TBitmap='''array''' [0..7,0..3] '''of''' Byte;&lt;br /&gt;
 '''var'''&lt;br /&gt;
   Bitmap:TBitmap;&lt;br /&gt;
 &lt;br /&gt;
 '''procedure''' OnCreate;&amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;''//Wird beim Start aufgerufen''&amp;lt;/font&amp;gt;&lt;br /&gt;
 '''type'''&lt;br /&gt;
   Bit=0..1;&lt;br /&gt;
   '''function''' BinByte(B128,B64,B32,B16,B8,B4,B2,B1:Bit):Byte;&lt;br /&gt;
   '''begin'''&lt;br /&gt;
     result := 0;&lt;br /&gt;
     '''if '''B128 &amp;amp;lt;&amp;amp;gt; 0 '''then '''Inc(result,128);&lt;br /&gt;
     '''if '''B64  &amp;amp;lt;&amp;amp;gt; 0 '''then '''Inc(result,64);&lt;br /&gt;
     '''if '''B32  &amp;amp;lt;&amp;amp;gt; 0 '''then '''Inc(result,32);&lt;br /&gt;
     '''if '''B16  &amp;amp;lt;&amp;amp;gt; 0 '''then '''Inc(result,16);&lt;br /&gt;
     '''if '''B8   &amp;amp;lt;&amp;amp;gt; 0 '''then '''Inc(result,8);&lt;br /&gt;
     '''if '''B4   &amp;amp;lt;&amp;amp;gt; 0 '''then '''Inc(result,4);&lt;br /&gt;
     '''if '''B2   &amp;amp;lt;&amp;amp;gt; 0 '''then '''Inc(result,2);&lt;br /&gt;
     '''if '''B1   &amp;amp;lt;&amp;amp;gt; 0 '''then '''Inc(result,1);&lt;br /&gt;
   '''end''';&lt;br /&gt;
 '''begin'''&lt;br /&gt;
   Bitmap[7][0] := BinByte(1,1,1,1,1,1,1,0);&lt;br /&gt;
   Bitmap[6][0] := BinByte(0,1,1,1,1,1,1,0);&lt;br /&gt;
   Bitmap[5][0] := BinByte(0,1,1,0,0,0,1,0);&lt;br /&gt;
   Bitmap[4][0] := BinByte(0,1,1,1,1,0,0,0);&lt;br /&gt;
   Bitmap[3][0] := BinByte(0,1,1,1,1,0,0,0);&lt;br /&gt;
   Bitmap[2][0] := BinByte(0,1,1,0,0,0,0,0);&lt;br /&gt;
   Bitmap[1][0] := BinByte(0,1,1,0,0,0,0,0);&lt;br /&gt;
   Bitmap[0][0] := BinByte(1,1,1,1,0,0,0,0);&lt;br /&gt;
 &lt;br /&gt;
   Bitmap[7][1] := BinByte(1,1,1,1,0,0,0,0);&lt;br /&gt;
   Bitmap[6][1] := BinByte(0,1,1,0,0,0,0,0);&lt;br /&gt;
   Bitmap[5][1] := BinByte(0,1,1,0,0,0,0,0);&lt;br /&gt;
   Bitmap[4][1] := BinByte(0,1,1,0,0,0,0,0);&lt;br /&gt;
   Bitmap[3][1] := BinByte(0,1,1,0,0,0,0,0);&lt;br /&gt;
   Bitmap[2][1] := BinByte(0,1,1,0,0,0,1,0);&lt;br /&gt;
   Bitmap[1][1] := BinByte(0,1,1,1,1,1,1,0);&lt;br /&gt;
   Bitmap[0][1] := BinByte(1,1,1,1,1,1,1,0);&lt;br /&gt;
 &lt;br /&gt;
   Bitmap[7][2] := BinByte(0,0,1,1,1,1,0,0);&lt;br /&gt;
   Bitmap[6][2] := BinByte(0,1,1,1,1,1,1,0);&lt;br /&gt;
   Bitmap[5][2] := BinByte(1,1,0,0,0,0,1,1);&lt;br /&gt;
   Bitmap[4][2] := BinByte(1,1,0,0,0,0,1,1);&lt;br /&gt;
   Bitmap[3][2] := BinByte(1,1,0,0,0,0,1,1);&lt;br /&gt;
   Bitmap[2][2] := BinByte(1,1,0,0,0,0,1,1);&lt;br /&gt;
   Bitmap[1][2] := BinByte(0,1,1,1,1,1,1,0);&lt;br /&gt;
   Bitmap[0][2] := BinByte(0,0,1,1,1,1,0,0);&lt;br /&gt;
 &lt;br /&gt;
   Bitmap[7][3] := BinByte(0,0,0,0,0,0,0,0);&lt;br /&gt;
   Bitmap[6][3] := BinByte(0,0,0,0,0,0,0,0);&lt;br /&gt;
   Bitmap[5][3] := BinByte(0,0,0,0,0,0,0,0);&lt;br /&gt;
   Bitmap[4][3] := BinByte(1,1,1,1,1,1,1,1);&lt;br /&gt;
   Bitmap[3][3] := BinByte(1,1,1,1,1,1,1,1);&lt;br /&gt;
   Bitmap[2][3] := BinByte(0,0,0,0,0,0,0,0);&lt;br /&gt;
   Bitmap[1][3] := BinByte(0,0,0,0,0,0,0,0);&lt;br /&gt;
   Bitmap[0][3] := BinByte(0,0,0,0,0,0,0,0);&lt;br /&gt;
 '''end''';&lt;br /&gt;
 &lt;br /&gt;
 '''procedure''' Draw;&amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;''//Zeichen Routine''&amp;lt;/font&amp;gt;&lt;br /&gt;
 '''begin'''&lt;br /&gt;
   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);&lt;br /&gt;
   glBitmap(0,0,0,0,300,200,'''nil''');&lt;br /&gt;
     glBitmap(8,8,0,6, 0,0,@Bitmap[0,3]);&amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;''//Gibt Bit-Spalten 25-32 aus(_)''&amp;lt;/font&amp;gt;&lt;br /&gt;
     glBitmap(8,8,0,0,10,0,@Bitmap[0,0]);&amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;''//Gibt Bit-Spalten 1-8 aus(F)''&amp;lt;/font&amp;gt;&lt;br /&gt;
     glBitmap(8,8,0,0,10,0,@Bitmap[0,1]);&amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;''//Gibt Bit-Spalten 9-16 aus(L)''&amp;lt;/font&amp;gt;&lt;br /&gt;
     glBitmap(8,8,0,0,10,0,@Bitmap[0,2]);&amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;''//Gibt Bit-Spalten 17-24 aus(O)''&amp;lt;/font&amp;gt;&lt;br /&gt;
     glBitmap(8,8,0,0,10,0,@Bitmap[0,3]);&amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;''//Gibt Bit-Spalten 25-32 aus(-)''&amp;lt;/font&amp;gt;&lt;br /&gt;
     glBitmap(20,8,0,0,0,0,@Bitmap[0,0]);&amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;''// Gibt Bit-Spalten 1-20 aus(FL()''&amp;lt;/font&amp;gt;&lt;br /&gt;
     glBitmap(0,0,0,0,-40,0,'''nil''');      &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;''//Zurück''&amp;lt;/font&amp;gt;&lt;br /&gt;
   glBitmap(0,0,0,0,-300,-200,'''nil'''); &amp;lt;font color=&amp;quot;#000080&amp;quot;&amp;gt;''//Zurück''&amp;lt;/font&amp;gt;&lt;br /&gt;
 '''end''';&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[wglUseFontBitmaps]], [[glBegin]], [[glDrawPixels]], [[glRasterPos]], [[glPixelStore]], [[glPixelTransfer]] &lt;br /&gt;
&lt;br /&gt;
Texturloader &amp;quot;[[Glbitmap loader|glBitmap.pas]]&amp;quot;&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:GL|Bitmap]] [[Kategorie:GL1.0]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=glTexImage&amp;diff=21957</id>
		<title>glTexImage</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=glTexImage&amp;diff=21957"/>
				<updated>2008-07-13T18:45:44Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: /* Parameter */ Beschreibung von 'pixels'&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= glTexImage =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
'''glTexImage''' - Einstellungen zum Texturen zeichnen&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Spezifikation ==&lt;br /&gt;
 procedure '''glTexImage1D'''(''target'': TGLenum; ''level'': TGLint; ''internalformat'': TGLint; ''width'': TGLsizei; &lt;br /&gt;
                        ''border'': TGLint; ''format'': TGLenum; ''_type'': TGLenum; '''const''' ''pixels'': PGLvoid); &amp;lt;br&amp;gt;&lt;br /&gt;
 procedure '''glTexImage2D'''(''target'': TGLenum; ''level'': TGLint; ''internalformat'': TGLint; ''width'': TGLsizei; &lt;br /&gt;
                        ''height'': TGLsizei; ''border'': TGLint; ''format'': TGLenum; ''_type'': TGLenum; &lt;br /&gt;
                        '''const''' ''pixels'': PGLvoid); &amp;lt;br&amp;gt;&lt;br /&gt;
 procedure '''glTexImage3D'''(''target'': TGLenum; ''level'': TGLint; ''internalformat'': TGLint; ''width'': TGLsizei; &lt;br /&gt;
                        ''height'': TGLsizei; ''depth'': TGLsizei; ''border'': TGLint; ''format'': TGLenum; &lt;br /&gt;
                        ''_type'': TGLenum; '''const''' ''pixels'': PGLvoid); &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''target''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Gibt an, welche Texture erreicht werden soll.  Muss je nach Funktionsaufruf '''GL_TEXTURE_1D,GL_TEXTURE_2D''' oder '''GL_TEXTURE_3D''' sein.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''level''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Gibt den Detailgrad für das gewünschte Bild an. &amp;lt;br&amp;gt;&lt;br /&gt;
''level'' '''0''' ist das Basisbild. Level n ist die n-te Mipmap reduzierung des Bildes.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''internalformat''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;'''1''' für '''R''' &amp;lt;br&amp;gt; '''2''' für '''R''' und '''A''' &amp;lt;br&amp;gt; '''3''' für '''RGB''' &amp;lt;br&amp;gt; '''4''' für '''RGBA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''width'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Breite = Anzahl der Pixel pro Zeile &amp;lt;br&amp;gt; muss als Wert 2^n (+ 2 * (border) ) für n Integerwerte haben.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''height'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Höhe = Anzahl der Zeilen &amp;lt;br&amp;gt; muss als Wert 2^n (+ 2 * (border) ) für n Integerwerte haben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''depth'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Tiefe = Anzahl der &amp;quot;Scheiben&amp;quot; &amp;lt;br&amp;gt; muss als Wert 2^n (+ 2 * (border) ) für n Integerwerte haben&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''border'',&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Breite des Rahmens || '''0''' oder '''1'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''format''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Bestimmt das Format der Pixeldaten. Folgende symbolische Werte werden akzeptiert: &amp;lt;br&amp;gt;&lt;br /&gt;
'''GL_COLOR_INDEX, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE,''' und '''GL_LUMINANCE_ALPHA'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''_type''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Bestimmt den Pixeltyp für den Inhalt von ''pixels''. Folgende Typen werden unterstützt:&amp;lt;br&amp;gt;&lt;br /&gt;
'''GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_UNSIGNED_INT, GL_INT, GL_FLOAT, GL_BITMAP'''&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''pixels''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Die Texture-Image Daten vom Typ, der in ''format'' angegeben wurde (Array, in dem die Pixel gespeichert sind) &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
Texturierung bildet einen bestimmten Teil eines Texturbildes auf alle [[Primitive|Grafikprimitiven]] ab für die Texturierung aktiviert ist.&lt;br /&gt;
&lt;br /&gt;
Je nachdem welche Texturart aktiviert werden soll ruft man [[glEnable]] mit den Parametern '''GL_TEXTURE_1D, GL_TEXTURE_2D''' oder '''GL_TEXTURE_3D''' auf. Die Deaktivierung erfolgt entsprechend mittels [[glDisable]].&lt;br /&gt;
&lt;br /&gt;
Die Texturbilder werden durch die Funktionen '''glTexImage1D, glTexImage2D''' bzw. '''glTexImage3D''' definiert. Die Argumente der Funktionen beschreiben die Eigenschaften des Texturbildes wie z.B. Breite, Höhe, Tiefe (je nach Dimension), Breite des Randes, [[LOD]]-Nummer (siehe [[glTexParameter]]) und Anzahl der unterstützen Farbkomponenten. Die letzten 3 Argumente beschreiben wie das Bild im Speicher abgelegt wird. Die 3 Argumente sind identisch mit denen, die das Pixelformat bei [[glDrawPixels]] steuern.&lt;br /&gt;
&lt;br /&gt;
Die Daten werden aus ''pixels'' als Sequenz von vorzeichenlosen oder -behafteten Byte-, Shortint- oder Longint-Werten oder als Fließkommazahlen einfacher Genauigkeit gelesen. Der Typ wird über ''type'' festgelegt. &amp;lt;br&amp;gt;&lt;br /&gt;
Die ausgelesen Werte werden abhängig von ''format'' gruppiert zu Gruppen mit je einem, zwei, drei oder vier Werten. Diese Gruppen entsprechen einem Element. &lt;br /&gt;
&lt;br /&gt;
Wenn ''type'' gleich '''GL_BITMAP''' ist, werden die Daten als Folge (orig.: &amp;quot;String&amp;quot;) von vorzeichenlosen Bytewerten angesehen (wobei ''format'' '''GL_COLOR_INDEX''' sein muss). Jedes Byte des Datenblocks wird als Gruppe von 8 1-Bit Elementen interpretiert. Die Reihenfolge der Bits wird durch '''GL_UNPACK_LSB_FIRST''' (siehe [[glPixelStore]]) festgelegt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Der ''format'' Parameter bestimmt die Zusammenstellung der Elemente aus ''pixels''. Folgende 9 möglichen Werte kann ''format'' haben:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''GL_COLOR_INDEX'''&lt;br /&gt;
:Jedes Element entspricht einem einzelnen Wert, dem Farbindex. Jeder Index wird in eine Festkommazahl (mit einer unbestimmten Anzahl 0 Bits rechts vom Komma) konvertiert, abhängig von Wert und Vorzeichen von '''GL_INDEX_SHIFT''' bitweise nach rechts bzw. links verschoben und zu GL_INDEX_OFFSET addiert. Dann werden die Indizes durch ihre entsprechenden Werte aus den Tabellen '''GL_PIXEL_MAP_I_TO_R''', '''GL_PIXEL_MAP_I_TO_G''', '''GL_PIXEL_MAP_I_TO_B''' und '''GL_PIXEL_MAP_I_TO_A''' ersetzt und auf das Interval [0, 1] heruntergerechnet.&lt;br /&gt;
&lt;br /&gt;
'''GL_RED'''&lt;br /&gt;
:Jedes Element entspricht einer roten Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die beiden anderen Farben und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''''c'''''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_GREEN'''&lt;br /&gt;
:Jedes Element entspricht einer grünen Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die beiden anderen Farben und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''''c'''''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_BLUE'''&lt;br /&gt;
:Jedes Element entspricht einer blauen Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die beiden anderen Farben und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''''c'''''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_ALPHA'''&lt;br /&gt;
:Jedes Element entspricht einer Alpha-Farbkomponente. Der Wert wird in eine Fließkommazahl konvertiert und zu einem RGBA Wert ergänzt, indem man 0.0 für die drei anderen Farben hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''''c'''''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_RGB'''&lt;br /&gt;
:Jedes Element entspricht den drei RGB-Farbwerten. Die Werte werden in Fließkommazahlen konvertiert und zu einem RGBA Wert ergänzt, indem man 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''''c'''''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_RGBA'''&lt;br /&gt;
:Jedes Element enthält alle vier Farbkomponenten. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''''c'''''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_LUMINANCE'''&lt;br /&gt;
:Jedes Element entspricht einem Helligkeitswert. Der Wert wird in Fließkommazahlen konvertiert und zu einem RGBA Wert ergänzt, indem man den Helligkeitswert drei mal für R, G und B einsetzt und 1.0 für den Alphakanal hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''''c'''''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
'''GL_LUMINANCE_ALPHA'''&lt;br /&gt;
:Jedes Element entspricht einem Paar aus Helligkeitswert und Alphawert. Beide Werte werden in Fließkommazahlen konvertiert und zu einem RGBA Wert ergänzt, indem man den Helligkeitswert drei mal für R, G und B einsetzt und den Alphawert hinzufügt. Jede Komponente wird mit '''GL_'''''c'''''_SCALE''' multipliziert und zu '''GL_'''''c'''''_BIAS''' addiert, und am Schluss auf den Bereich [0,1] begrenzt, wobei ''c'' durch R, G, B oder A ersetzt werden soll. (siehe [[glPixelTransfer]])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lesen Sie den Artikel [[glDrawPixels]] um eine Beschreibung der zulässigen Werte für ''type'' zu erhalten.&lt;br /&gt;
&lt;br /&gt;
Ein Texturbild kann bis zu 4 Farbkomponenten pro Texturelement ([[Texel]]) besitzen. Dies wird über den Parameter ''internalformat'' geregelt. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild welches nur eine Komponente besitzt, beenutzt nur die Rotwerte der aus ''pixels'' extrahierten RGBA Farbe. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild mit zwei Komponenten benutzt nur die Rot und Alpha Komponenten. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild mit drei Komponenten benutzt nur die Rot, Grün und Blau Komponenten. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein Texturbild mit vier Komponenten benutzt alle RGBA Farbkomponenten. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Verwendungsmöglichkeit===&lt;br /&gt;
Abseits dem einfachen Laden von Texturen wird diese Funktion auch benutzt um Speicherbereiche für die spätere Verwendung zu reservieren. Ruft man glTexImage mit ''pixels'' = '''nil''' auf, wird der Speicherbereich zwar angelegt aber nicht gefüllt. Dies kann zum Beispiel gewünscht sein, wenn man einen Screenshot als Textur verwenden möchte (&amp;quot;Render To Texture&amp;quot;). Man kann dann den [[Framebuffer]] (=Screenshot) mittels [[glCopyTexImage]] in den durch glTexImage reservierten Speicherbereich kopieren. (Siehe dazu auch diesen [http://www.delphigl.com/forum/viewtopic.php?p=59156 Thread im Forum])&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
'''glTexImage3D''' war bis zu OpenGL 1.2 nur eine Erweiterung. Deswegen ist bei manchen Chipsätzen die Funktion nur als '''glTexImage3DEXT''' verfügbar.&lt;br /&gt;
&lt;br /&gt;
Texturierung hat im Farbindexmodus keinen Effekt.&lt;br /&gt;
&lt;br /&gt;
Das Texturbild kann in den selben Datenformaten vorliegen wie die Pixel bei [[glDrawPixels]] ausgenommen '''GL_STENCIL_INDEX''' und '''GL_DEPTH_COMPONENT'''. [[glPixelStore]] und [[glPixelTransfer]] beeinflussen das Texturebild in exakt der Art und Weise, wie sie auch [[glDrawPixels]] beeinflussen.&lt;br /&gt;
&lt;br /&gt;
Eine Textur die 0 Pixel hoch oder breit ist, stellt die NULL-Textur dar. Wenn die NULL-Textur für die LOD-Stufe 0 spezifiziert wird entspricht das Verhalten dem bei deaktivierter Texturierung.&lt;br /&gt;
&lt;br /&gt;
== Änderungen ==&lt;br /&gt;
Folgende Erweiterungen hat die Funktion erfahren:&lt;br /&gt;
&lt;br /&gt;
=== Ab OpenGL Version 1.3 ===&lt;br /&gt;
[[GL_ARB_texture_cube_map]] definiert weitere 6 2D-Texture-Typen welche als ''target'' angegeben werden können.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fehlermeldungen ==&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn ''target'' nicht '''GL_TEXTURE_1D, GL_TEXTURE_2D''' oder '''GL_TEXTURE_3D''' ist. (entsprechend der benutzten Funktion)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn ''format'' ungültige Werte übergeben wurden. Akzeptiert werden alle Formatangaben außer '''GL_STENCIL_INDEX''' und '''GL_DEPTH_COMPONENT''' &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn ''type'' keine gültige Typkonstante übergeben wurde. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM''' wird generiert wenn GL_BITMAP als ''type'' und '''GL_COLOR_INDEX nicht(!)''' als ''format'' angegeben wurde. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn ''level'' kleiner 0 oder größer ld(max) ist, wobei max der Rückgabewert von '''GL_MAX_TEXTURE_SIZE''' ist. (ld = Logarithmus Dualis = Basis 2). &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn für ''internalformat'' etwas anderes als ''1'', ''2'', ''3'' oder ''4'' angegeben wurde. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wird generiert wenn ''width'', ''height'' bzw. ''depth'' (je nach Funktion) kleiner als 0 oder größer als 2 + '''GL_MAX_TEXTURE_SIZE''' ist, oder die Bedingung  2^k + 2 * (border) (k=Integerwerte) nich erfüllt. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE''' wenn ''border'' nicht ''0'' oder ''1'' ist. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_OPERATION''' wird generiert wenn eine '''glTexImage'''-Funktion in einem [[glBegin]]- und [[glEnd]]-Block aufgerufen wird. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Zugehörige Wertrückgaben ==&lt;br /&gt;
[[glGetTexImage]] &amp;lt;br&amp;gt;&lt;br /&gt;
[[glIsEnabled]] mit dem Token '''GL_TEXTURE_1D''', '''GL_TEXTURE_2D''' bzw. '''GL_TEXTURE_2D'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[glTexEnv]], [[glTexGen]], [[glTexSubImage1D]], [[glTexSubImage2D]], [[glTexSubImage3D]], [[glTexParameter]], [[glTexCoord]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:GL|TexImage]]&lt;br /&gt;
 [[Kategorie:GL1.0]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=SDL_GetError&amp;diff=21942</id>
		<title>SDL GetError</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=SDL_GetError&amp;diff=21942"/>
				<updated>2008-07-12T12:03:31Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: /* Siehe auch */ Groß-/Kleinschreibung&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= SDL_GetError =&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
'''SDL_GetError''' - Liefert einen String zurück der den letzten aufgetretenen Fehler näher beschreibt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 function '''SDL_GetError''': PChar;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beschreibung ==&lt;br /&gt;
'''SDL_GetError''' liefert einen String zurück der den letzten aufgetretenen Fehler näher beschreibt. Besonders bei der Initalisierung sollte überprüft werden, ob angeforderte Ressourcen auch zur Verfügung stehen. Wird statt eines Ergebnisses ein NIL-Wert zurückgegeben, empfiehlt es sich mit '''SDL_GetError''' den aufgetretenen Fehler auszugeben. Dies erleichtert in der Praxis sehr häufig die Diagnose eines Problems.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Beispiel ==&lt;br /&gt;
Wir versuchen künstlich einen Fehler hervorzurufen indem wir als gewünschte Bildschirmauflösung negative Werte angeben. Die daraus resultierende Ausgabe lautet: ''Invalid width or height''&lt;br /&gt;
&amp;lt;pascal&amp;gt;[...]&lt;br /&gt;
surface := SDL_SetVideoMode(-800, -600, -32, videoflags);&lt;br /&gt;
if not assigned(surface) then&lt;br /&gt;
begin&lt;br /&gt;
  WriteLn(SDL_GetError);&lt;br /&gt;
  Quit_App;&lt;br /&gt;
end;&lt;br /&gt;
[...]&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[glGetError]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:SDL|GetError]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Blackbox&amp;diff=21926</id>
		<title>Blackbox</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Blackbox&amp;diff=21926"/>
				<updated>2008-07-08T14:14:00Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: Komma eingefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==BlackBox==&lt;br /&gt;
Eine BlackBox beschreibt im Technischen Gebiet eine Schaltung, von der nur ihre Wirkung bekannt ist und daraus Schlussfolgerungen auf den Inhalt gemacht werden.&lt;br /&gt;
&lt;br /&gt;
Blackboxes werden benutzt um Informationsmengen einzuschränken. Denn häufig ist es nur wichtig zu wissen, '''was''' ein Programmteil macht, aber nicht '''wie'''. Deshalb werden die betreffenden Teile durch eine Blackbox ersetzt. Von einer Blackbox ist nur bekannt was sie als Eingaben benötigt und was sie bewirkt bzw. welche Ausgaben sie erzeugt.&lt;br /&gt;
&lt;br /&gt;
==Reverse Engineering==&lt;br /&gt;
Will man den Inhalt einer Blackbox rekonstuieren kann man den Ansatz des Reverse Engenierings versuchen. &lt;br /&gt;
&lt;br /&gt;
Ein Beispiel wäre folgendes:&lt;br /&gt;
&lt;br /&gt;
 function extractfilename(file:string):string;&lt;br /&gt;
 begin&lt;br /&gt;
   //Unbekannt&lt;br /&gt;
   result:=rueckgabewert;&lt;br /&gt;
 end;&lt;br /&gt;
&lt;br /&gt;
Nun fangen wir an alles von hinten aufzurollen und eventuell ein grossteil des Codes zu bekommen.&lt;br /&gt;
&lt;br /&gt;
 function extractfilename(file:string):string;&lt;br /&gt;
 var //Variable zum zwischenspeichern und bearbeiten des strings&lt;br /&gt;
   filename:string;&lt;br /&gt;
 begin&lt;br /&gt;
   filename:=file;&lt;br /&gt;
   //Unbekannt&lt;br /&gt;
   result:=filename;&lt;br /&gt;
 end;&lt;br /&gt;
&lt;br /&gt;
Wir wissen nun, dass der fehlende Code den Dateinamen aus dem String kopiert.&lt;br /&gt;
Des weiterem ist uns bekannt das ein Dateiname am Ende einer Pfadhierachy steht und die Pfade durch ein '/' oder '\' Zeichen getrennt werden. Das bedeutet wir suchen das letze '/' oder '\' Zeichen im String und kopieren alles von der Position bis Stringende.&lt;br /&gt;
&lt;br /&gt;
 function extractfilename(file:string):string;&lt;br /&gt;
 var&lt;br /&gt;
   filename:string;&lt;br /&gt;
   ind:integer;&lt;br /&gt;
 begin&lt;br /&gt;
   filename:=file;&lt;br /&gt;
   for ind:=high(filename) downto 0 do&lt;br /&gt;
     if (filename[ind]='/') or (filename[ind]='\') then break;&lt;br /&gt;
   copy(filenam,ind,length(file)-ind);&lt;br /&gt;
   result:=filename;&lt;br /&gt;
 end;&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Enginepfad&amp;diff=21925</id>
		<title>Enginepfad</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Enginepfad&amp;diff=21925"/>
				<updated>2008-07-08T14:11:03Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: /* Vorbereitung */ Was zum Teufel ist AI? (-&amp;gt; Künstliche Intelligenz)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Der Enginepfad=&lt;br /&gt;
&lt;br /&gt;
==Einführung==&lt;br /&gt;
Willkommen auf dem '''Enginepfad''' des DelphiGL-Wikis. Dieser Pfad soll euch zeigen wie man eine Engine von Grund auf konzipieren und realisieren kann.&lt;br /&gt;
&lt;br /&gt;
Wie funktioniert der Trampelpfad? Im nachfolgenden Abschnitt findet ihr einen Text, der euch etwas über Engines erzählen soll. Dieser Text ist durchsetzt mit Schlagwörtern, welche Links auf andere Artikel im Wiki sind. Wenn ihr diesen Links folgt, erfahrt ihr mehr zu den entsprechenden Themen. &lt;br /&gt;
&lt;br /&gt;
Sinn des Trampelpfades ist es, euch die Artikel aufzuzeigen, welche ihr gelesen haben solltet und welche nützlich für den Einstieg in OpenGL sind. Am Ende dieses Trampelpfades findet ihr noch Links, die euch die Materie genauer erklären werden.&lt;br /&gt;
&lt;br /&gt;
==Der Trampelpfad==&lt;br /&gt;
Am Beginn steht bei den meisten Anfängern zum Thema [[Engine]] die Frage &amp;quot;Was brauch' ich um eine Engine zu entwickeln?&amp;quot;. Je nach dem welches Betriebsystem ihr als Plattform gewählt habt, können sich die Hilfsmittel unterscheiden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Weiterhin ist die Wahl der Sprache zu treffen.&lt;br /&gt;
Wenn ihr mit Object Pascal in seinen vielen Varianten (z.B. '''Delphi''') arbeiten wollt, dann ist der [[DGLOpenGL.pas]]-Header genau das richtige für euch. Wenn es eine andere Sprache sein soll, müsst ihr euch dann nach einen aktuellen Header in Google umschauen. Es ist im vorhinein schon zu erwähnen, dass dieses Wiki Object Pascal in seiner Vielfalt verwendet.&lt;br /&gt;
&lt;br /&gt;
==Vorbereitung==&lt;br /&gt;
Als erstes muss uns klar werden, welches Ausmaß die Engine erreichen soll. Davon abhängig ist unsere Planung zu gestalten:&lt;br /&gt;
:1. Es ist ratsam mit der Plattformunterstützung anzufangen, da diese unsere unterste Schicht bilden wird.&lt;br /&gt;
:Hier ist als erstes zu sagen, je mehr Plattformen unterstütz werden sollen, desto aufwendiger wird das Projekt.&lt;br /&gt;
:Mit Plattformen sind hier z.B. PC mit 32Bit/64Bit, Konsolen (PS1-3, XBox-360, Wii, GP2X, ...) und mobile Geräte (Palm, PSP,...) gemeint.&lt;br /&gt;
:Für jede Plattform gibt es eine oder mehrere Betriebssysteme zur Ansteuerung der Hardware.&lt;br /&gt;
:Hier eine kleine Liste mit verschiedenen Betriebssystemen:&lt;br /&gt;
:*Windows&lt;br /&gt;
:*Linux&lt;br /&gt;
:*MacOS X&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:2. Abhängig davon wählen wir nun unseren Compiler. &lt;br /&gt;
:*[http://www.borland.de/delphi/ Delphi] (Windows 32Bit)&lt;br /&gt;
:*[http://www.freepascal.org/ FreePascal] (Unterstützung für alle erwähnten Plattformen und OS)&lt;br /&gt;
:*[http://www.gnu.org/software/gcc/gcc.html gcc] (Unterstützungen für alle erwähnten Plattformen und OS)&lt;br /&gt;
:*[http://www.borland.de/kylix/ Kylix] (Linux 32Bit) (Veraltet, nicht mehr in Entwicklung)&lt;br /&gt;
:*[http://msdn.microsoft.com/visualc/ VisualC++] (Windows 32/64Bit WinCE)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:3. Nun sollten wir entscheiden, welche Bibliothek wir für das Ansprechen der Grafikkarte verwenden:&lt;br /&gt;
:Es gibt einige wie z.B. DirectX, GDI, AGG und Mesa aber wir wollen uns mit [[OpenGL]] auseinander setzen, denn dieses ist ein OpenGL Wiki.&lt;br /&gt;
{{Hinweis|Dieser [[OpenGL Verwendungspfad|Verweis]] führt Sie auf den Verwendungspfad in diesem Wiki und soll zeigen wie man OpenGL unter den einzelnen OS nutzten kann}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:4. Nun kommen wir zu allgemeinen Bibliotheken für das Ansteuern unserer Hardware.&lt;br /&gt;
:Im Voraus ist zu sagen, dass ALSA und OSS Treiber unter Linux sind, die das Abspielen von Sound ermöglichen. Nur nur ein Bruchteil der Bibliotheken ist für 3D Sound ausgelegt und man müsste bei Bedarf noch einen eigene Dopplereffekt hinzufügen.&lt;br /&gt;
:Sound:&lt;br /&gt;
:*ALSA (Linux)&lt;br /&gt;
:*[http://www.un4seen.com/ BASS]&lt;br /&gt;
:*[[Direct Sound]] (Windows)&lt;br /&gt;
:*[http://www.fmod.org/ FMOD]&lt;br /&gt;
:*[[OpenAL]]&lt;br /&gt;
:*OSS (Nur Linux)&lt;br /&gt;
:*[[SDL]]&lt;br /&gt;
:Netzwerk:&lt;br /&gt;
:*DirectX Net (Windows)&lt;br /&gt;
:*[[SDL_Net]]&lt;br /&gt;
:*Raknet&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:5. Jetzt sollte man entscheiden, ob und welche Bibliotheken man zur Erleichterung der nicht hardwarebezogenen Aufgaben wählt. Um den Rahmen nicht zu sprengen nur ein paar Beispiele.&lt;br /&gt;
:Physik:&lt;br /&gt;
:*[http://www.havok.com/ Havok]&lt;br /&gt;
:*[http://www.physicsengine.com/ Newton]&lt;br /&gt;
:*[http://www.ageia.com/novodex.html NovodeX]&lt;br /&gt;
:*[http://www.ode.org/ ODE]&lt;br /&gt;
:Fenster:&lt;br /&gt;
:*[http://www.gtk.org/ GTK]&lt;br /&gt;
:*[http://www.wxwidget.org/ wxWidget]&lt;br /&gt;
:*[[SDL]]&lt;br /&gt;
:*Win API (Windows)&lt;br /&gt;
:Kompression:&lt;br /&gt;
:*[http://www.zlib.net/ zLib]&lt;br /&gt;
:Künstliche Intelligenz:&lt;br /&gt;
:*[http://opensteer.sourceforge.net/ openSteer]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:6. Nun beachten wir unser eventuell eingeplantes Budget (normalerweise 0 ^_^) und gehen die Liste oben nochmal durch.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:7. Ein Programm teilt sich in der Regel in 3 Teilbereiche (im Bereich Software Engineering auch Pakete genannt), diese sind die GUI, die Programmlogik und die Datenbank.&lt;br /&gt;
:GUI:&lt;br /&gt;
:*Die GUI sorgt dafür, dass alle Informationen dem User grafisch dargestellt werden. Dabei geht dieses natürlich auch in die Gegenrichtung. Also der User gibt Informationen an den Computer.&lt;br /&gt;
:Logik:&lt;br /&gt;
:*Die Logik ist der größte Teil vom Programm, denn hier ist der ganze Code angesiedelt, der das Programm zum laufen bringt.&lt;br /&gt;
:Datenbank:&lt;br /&gt;
:*Das Datenbank Paket, ist der Part wo alle Daten, die das Programm benötigt, zwischengespeichert werden. Das wären z.B. Variablen, Texturdaten, Spielerinformationen und so weiter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:Wer sich in der Material nur ausprobieren will, kann anfangen, so viel wie möglich selber zu programmieren. Wenn es aber darum geht, eine Engine zu schreiben, welche man auch benutzten will, dann sollte man versuchen, so viel Code wie möglich wieder zu verwerten. Viele Programmierer haben schon Funktionen, Strukturen und Lösungen geschrieben und diese gilt es so gut wie möglich wieder zu verwerten. Dies hat viele Vorteile, denn man spart Zeit, man kann sich sicher sein, dass der Code standardmässig läuft und man hat sich viel Zeit mit der Konzeptphase gespart. Man muss in der konstruktiven Entwicklung nicht mehr das Rad neu erfinden. Der Trend in der professionellen Programmierung geht seit vielen Jahren in diese Richtung. [[SDL]], [[OpenAL]], DirectX, [[OpenGL]], zLib und viele andere Bibliotheken haben sich so ihren Stellenwert erkämpft.&lt;br /&gt;
&lt;br /&gt;
==Planung==&lt;br /&gt;
Wir gehen mal von ein &amp;quot;AllInOne Wonder&amp;quot; aus und nutzen FreePascal aufgrund der Plattformunabhängigkeit, SDL und sämtliche Zusatzpakete zur plattformunabhängigen Fensterinitialisierung sowie zum Laden von etlichen Bildformaten. Für die Soundausgabe werden wir aufgrund von Kostengründen auf OpenAL setzen. Für die Physik ist eine vorhandene Bibliothek wie zum Beispiel ODE zu favorisieren, da diese schon ausgereifter als eine selbst entwickelte ist. Doch kann im Gegenzug eine eigene Physik-Bibliothek eventuell schneller und viel schlanker sein, wenn man nur eine handvoll Dinge benötigt.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Geht's nun Los?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Na ja, nun kommt der wahrscheinlich unangenehmste Satz für alle:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Entwicklung einer Engine bedarf einer ausführlichen Planung, was kurz und knapp ein [[Softwarecycle]] bedeutet. Nun sollte man die einzelnen Schritte eines Softwarecycles abarbeiten und ganz am Ende, wenn viel Zeit rum ist, kann man dann endlich anfangen den Compiler flott zu machen. Kleiner Tipp: Macht euch die Mühe, da diese sich umso mehr auszahlt, je grösser das Projekt ist(für ein Packman Clon ist es aber eher Zeitverschwendung). Das Allerwichtigste bei großen Projekten ist, dass Aufgabenpakete/Module geschnürt werden. Diese sollten nach dem [[Blackbox]]-Prinzip erstellt werden. Dadurch können die Module unabhängig voneinander von verschiedenen Personen erstellt werden. Um so etwas realisieren zu können, ist natürlich klar, dass in die Planung der [[Schnittstelle|Schnittstellen]] zwischen den Modulen sehr viel Zeit eingesetzt werden sollte. Änderungen in den Modulen sind kein Problem, Änderungen an der Schnittstelle können Einfluss auf das gesamte Projekt haben. Eine Engine kann entweder auf Low-Level oder High-Level API aufsetzen, idealerweiser sollte man eine Zwischenlösung nutzen, hierzu finden Sie unter [[Low/High-Level|High/Low-Level API]] weitere Informationen.&lt;br /&gt;
&lt;br /&gt;
In der Industrie verwendet man in größeren Engines Wrapper. Dieser ist dazu da, dass OpenGL/SDL und DirectX über eine eigene API angesteuert werden kann und somit ist es möglich die Engine mit den verschiedensten Plattformen (PC, Konsole, etc.) zurecht kommt. Laut einer neueren Umfrage schreiben 75% alle amerikanischen Publisher ihren Entwicklerteams vor, dass sie eine Engine mit genau dieser Eigenschaft nutzen. Des weiteren ist es auch immer häufiger, dass Publisher auf der ganzen Welt ihren Entwicklerteams vorschreiben, dass sie eine fertige Engine (Middleware) zu verwenden haben. Dies hat den Grund, dass der Publisher somit das Risiko eines Spiels vermindert und Geld spart - schließlich kostet das Entwickeln einer Engine eine große Summe an Geld und die Künstler sitzen währenddessen ohne Arbeit herum. Diese kalkulierten Kosten sind in der Summe höher als der Preis einer aktuellen Engine, wie zum Beispiel die &amp;quot;Vision&amp;quot; oder &amp;quot;Source&amp;quot; Engine.&lt;br /&gt;
&lt;br /&gt;
Wenn Sie es noch nicht getan haben, dann schauen Sie sich am besten noch ein Buch oder Artikel über Pattern/Muster an. So sind [[Adapter_Muster|Adapter]], [[Singleton_Muster|Singleton]], [[Observer_Muster|Observer]] Muster sehr sinnvoll zu kennen.&lt;br /&gt;
So kann man z.B. für Materials, Texturen, Shader, Models, Animationen und alle anderen auf Daten basierte Komponenten mit dem [[Adapter Muster]] sehr flexibel sein.&lt;br /&gt;
Für ein SceneGraph kann man das Observer Muster prima anwenden und Singleton kann man für alle Manager verwenden.&lt;br /&gt;
&lt;br /&gt;
{{Hinweis|Siehe die Tutorial Reihe [[Tutorial_Softwareentwicklung1|Softwareentwicklung]]}}&lt;br /&gt;
&lt;br /&gt;
==Die ersten Schritte in eine nicht reelle Welt==&lt;br /&gt;
Nachdem man weiß, was das Projekt einmal enthalten soll, besteht der erste Schritt darin, Manager zu erstellen, die die Arbeit erleichtern. Bei 3D-Spielen ist z.B. ein Leveleditor kein Feature, was am Ende entwickelt wird, sondern der Editor ist fertig, noch bevor das Spiel getestet wird. Deshalb gibt es in Firmen Programmierer, die nichts anderes machen als Tools/Manager für die Erstellung der Inhalte zu fertigen. Dazu gehören:&lt;br /&gt;
&lt;br /&gt;
# [[Leveleditoren]] um die &amp;quot;Welt&amp;quot; zu erstellen.&lt;br /&gt;
# '''Texturmanager''' um den Programmierern den Zugriff auf die Texturen so einfach wie möglich zu machen.&lt;br /&gt;
# '''Soundmanager''' (siehe vorheriges)&lt;br /&gt;
# '''Lademanager''' für eigene Dateiformate.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nun ist es so weit, wir wissen was wir wollen und haben alles durchdacht.&lt;br /&gt;
Nun gilt es die einzelnen Module in die Tat um zu setzen.&lt;br /&gt;
Einige Module die es 3D Anwendungen/Spielen geben könnte:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Grundlagen:'''&lt;br /&gt;
#[[Template]]&lt;br /&gt;
#[[Kamera]]&lt;br /&gt;
#[[Schrift]]&lt;br /&gt;
#[[Input]] (Maus/Tastatur)&lt;br /&gt;
#[[Adapter Muster]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Fortgeschrittene Grundlagen:'''&lt;br /&gt;
#[[Sound]]&lt;br /&gt;
#[[Physik]]&lt;br /&gt;
#[[Texturen]]&lt;br /&gt;
#[[Levelformat]]&lt;br /&gt;
#[[Modelformat]]&lt;br /&gt;
#[[Console]] (Laufzeit-Schnittstelle zur Engine)&lt;br /&gt;
#[[DGL GUI|GUI]] (Game User Interface)&lt;br /&gt;
#[[Netzwerk]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Fortgeschritten:'''&lt;br /&gt;
#[[Shader]]&lt;br /&gt;
#[[Materials]]&lt;br /&gt;
#[[Packformate]]&lt;br /&gt;
#[[VFS]] (Virtual File System)&lt;br /&gt;
#[[Soundformat-Erweiterungen]]&lt;br /&gt;
#[[KI]]&lt;br /&gt;
#[[Script]]&lt;br /&gt;
#[[Scene Graph]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sieht doch eigentlich nach nicht so viel aus oder?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Doch der Schein trügt. In großen Firmen sitzen meist mehrere Programmierer, die in diesen Gebiet erfahren sind, an nur ein, maximal 2 Modulen. Wie ist es dann möglich, dass es trotzdem so viele Spiele/Engines gibt, die nicht von Firmen sind ?&lt;br /&gt;
#die Planung wird bei weitem nicht so groß ausfallen wie in Grossfirmen&lt;br /&gt;
#die Koordination von vielen Person ist sehr schwer und es kann zu großen Zeitlücken kommen&lt;br /&gt;
#meistens wird die Planung sowieso nicht in die Tat umzusetzen sein, es gibt immer ein Problem&lt;br /&gt;
#ein kleines Team kann sich im besten Fall gegenseitig hochpushen und zu mehr anspornen&lt;br /&gt;
#Großfirmen haben selten die Möglichkeit, mal einen Codefetzen in Foren zu setzen und verbessern zu lassen&lt;br /&gt;
#das Nutzen von Bibliotheken ist sehr zeitsparend&lt;br /&gt;
&lt;br /&gt;
==Die Engine ist fertig oder doch nicht?==&lt;br /&gt;
Es gibt ein Unterschied zwischen der Entwicklung von einer Engine und der Entwicklung einer Engine für ein Spiel.&lt;br /&gt;
Die Engine für ein Spiel ist festgelegt und hat ein Endpunkt, was sie leisten soll.&lt;br /&gt;
Eine Engine als selbststehendes Projekt wird hingegen nie fertig, man kann sie immer wieder optimieren und erweitern.&lt;br /&gt;
Doch kommt der Punkt, wo die Qualität den Ansprüchen völlig ausreichend ist.&lt;br /&gt;
Man sollte nun noch überlegen, ob man eventuell ein Tool zur leichteren Handhabung der Engine entwickelt.&lt;br /&gt;
So kann ein GUI-Editor oder Material-Editor die Arbeit um vieles erleichtern, wenn es dann heißt die Engine auch zu nutzen. Diese Tools nennt man dann die Toolchain einer Engine und dort gehören dann neben den Editoren auch Compiler, Libs und Ressourcen hinzu.&lt;br /&gt;
&lt;br /&gt;
Nun bleibt es nur noch zu sagen: viel Glück und Erfolg mit der Entwicklung einer eigenen Engine. Mögen die bereitgestellten Links zur Erleuchtung führen.&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
[http://x-dream.neroneus.de X-Dream Engine]&lt;br /&gt;
&lt;br /&gt;
[http://www.omorphia.de Projekt omorphia]&lt;br /&gt;
&lt;br /&gt;
[http://andorra.sourceforge.net/ Andorra 2D]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Trampelpfad]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Engine&amp;diff=21924</id>
		<title>Engine</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Engine&amp;diff=21924"/>
				<updated>2008-07-08T13:59:57Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: Zweiter Link auf gleichen Artikel entfernt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Engine''' ist Englisch und bedeutet wörtlich übersetzt '''Motor'''.&lt;br /&gt;
&lt;br /&gt;
In Bezug auf Grafik und Computerspiele wurde der Begriff Engine vor allem durch die ersten First Person Shooter geprägt. Die meisten Definitionen, die zu den Begriffen Rendering-, Grafik- und Game-Engine existieren, sind äusserst schwammig. Da sich jedoch in letzter Zeit der Begriff Engine auch im wissenschaftlichen Bereich weiter durchsetzt, findet sich nun auch die ein oder andere brauchbarere Definition wie zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
''In todays modularly constructed games, the games engine refers to that collection of modules of simulation code that do not directly specify the games behavior (game logic) or games environment (level data).''&amp;lt;br&amp;gt;&lt;br /&gt;
[http://planetjeff.net/IndexDownloads/Lewis2002.pdf Game Engines in Scientific Research, CACM, Januar 2002]&lt;br /&gt;
&lt;br /&gt;
Diese Definition besagt also, das eine Game Engine eine Bibliothek ist, die alles übernehmen ''kann'', was nicht direkt mit einem konkreten Spiel zusammenhängt. Der Streitpunkt ist nun, was direkt mit einem Spiel zusammen hängt und was nicht. Da viele Genres ganz andere Bedürfnisse an eine Game-Engine stellen, existieren auch hunderte verschiedene Engines.&lt;br /&gt;
&lt;br /&gt;
Der Sinn hinter einer so strickten Trennung zwischen Game-Engine und eigentlichem Spiel, ist die Wiederverwendbarkeit ein und des selben Sourcecodes für mehrere Spiele und im kommerziellen Bereich zusätzlich noch der Verkauf der Engine an andere Produzenten. Aber auch aus der Sicht eines Softwareentwicklers bietet diese Trennung den Vorteil, dass man ein großes Projekt von vorne herein in zwei große Teilbereiche aufspaltet. Zusätzlich benötigt man bei einer Engine üblicherweise noch Editoren. Durch die Trennung von Spiel und Engine kann man die Engine auch für die Editorentwicklung verwenden, wodurch sich diese Modularisierung selbst bei der Entwicklung eines einzigen Spieles lohnt.&lt;br /&gt;
&lt;br /&gt;
Eine Game-Engine setzt sich üblicherweise aus den folgenden Hauptbereichen zusammen:&lt;br /&gt;
*Grafik&lt;br /&gt;
*Sound&lt;br /&gt;
*[[Physik]]&lt;br /&gt;
*Netzwerk&lt;br /&gt;
*Eingabe&lt;br /&gt;
*Editoren&lt;br /&gt;
*[[KI|Künstliche Intelligenz]]&lt;br /&gt;
&lt;br /&gt;
Da der Grafikbereich üblicherweise verhältnismäßig groß ist, gibt es auch eigene Grafik-Engines. Grafik-Engines sind also Game-Engines, die ausschließlich die Grafik behandeln, nicht die restlichen genannten Teilbereiche. Oder umgekehrt gesagt: eine Game-Engine besitzt eine eigene oder benutzt eine bestehende Grafik-Engine. [[Szenengraph|Szenengraphen]] fallen üblicherweise in die Kategorie Grafik-Engine, obwohl man von einer Engine häufig erst dann spricht, wenn irgend eine Art von Animation im Spiel ist, was bei Szenengraphen nicht zwingend der Fall sein muss. Diese Ansichten sind jedoch auch sehr vage und nicht unumstritten.&lt;br /&gt;
&lt;br /&gt;
Nun existiert noch der Begriff Rendering-Engine, welcher üblicherweise verwendet wird, um noch eine Stufe tiefer zu gehen. Eine Rendering-Engine stellt nur eine sehr strikt definierte, jedoch sehr allgemein anwendbare Funktionalität zur Darstellung von 3D-Szenen zur Verfügung. Man könnte auch sagen, dass eine Rendering-Engine keine eigenen Entscheidungen trifft, welche sich auf das Aussehen der dargestellten Szene auswirken würden. Als bestes Beispiel sei hier [[LOD|Level of Detail]] genannt. Die Wahl des [[LOD|Level of Detail]] überlässt die Rendering-Engine fast ausschließlich den übergeordneten Programmteilen (beispielsweise der Grafik-Engine). [[OpenGL]] und [[Direct3D]] stellen wohl die bekanntesten Vertreter für Rendering-Engines dar. Wieder kann gesagt werden, dass eine Rendering-Engine ausschließlich die Darstellung eines konkreten [[Frame|Frames]] mit konkret gegebenen Parametern übernimmt. Und umgekehrt kann gesagt werden: eine Grafik-Engine besitzt eine eigene oder benutzt eine bestehende Rendering-Engine.&lt;br /&gt;
&lt;br /&gt;
Nun wäre noch der Begriff 3D-Engine zu klären, welcher am vielfältigsten von allen eingesetzt wird. Üblicherweise handelt es sich dabei um einen Überbegriff für Game-, Grafik- und Rendering-Engine aber natürlich mit der Einschränkung, dass es sich um 3D- und nicht um 2D-Szenen handelt.&lt;br /&gt;
&lt;br /&gt;
=Ressourcen=&lt;br /&gt;
*[http://gamearchitect.net/Articles/TheList.html The List], eine umfangreiche Auflistung der Teilgebiete, die bei einer Game-Engine beachtet werden können.&lt;br /&gt;
*[http://www.devmaster.net/engines/ 3D-Engines Liste], eine umfangreiche Sammlung von 3D Game- und Grafik- Engines.&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=glPolygonMode&amp;diff=21684</id>
		<title>glPolygonMode</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=glPolygonMode&amp;diff=21684"/>
				<updated>2008-05-09T12:50:15Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: /* Delphi-Spezifikation */ Delphi-Syntax hinzugefügt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= glPolygonMode =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
&lt;br /&gt;
'''glPolygonMode''' - wählt aus wie die einzelnen Polygone beim Rastern gezeichnet werden sollen.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 procedure '''glPolygonMode'''(''face'', ''mode'': GLenum);&lt;br /&gt;
&lt;br /&gt;
== Parameter ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=1 rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''face''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Definiert auf welche Polygone mode angewendet werden soll. GL_FRONT bewirkt, dass mode nur auf nach Vorne gerichte Polygone angewandt wird. GL_BACK hingegen auf die nach hinten gerichteten. GL_FRONT_AND_BACK wirkt sich auf beide Seiten aus.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;''mode''&amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;Gibt an wie die betroffenen Polygone gezeichnet werden sollen. Mögliche Werte sind GL_POINT, GL_LINE und GL_FILL. &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Standardgemäß''' wird '''GL_FILL''' auf die '''Vorder- und Rückseite''' aller Polygone angewandt.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
&lt;br /&gt;
glPolygonMode beinflusst wie Polygone bei der Rasterung gezeichnet werden. Auf welche Polygone es eine Auswirkung haben soll, kann man mit face festlegen.Der Polygonmodus wirkt sich nur beim letzten Rastervorgang auf die Polygone aus. Möglicherweise wurde der Eckpunkt des Polygones bereits beleuchtet oder durch das Culling beinflusst, bevor der mit glPolygonMode gesetze Effekt einsetzt.&lt;br /&gt;
&amp;lt;table rules=all&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;GL_POINT&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[bild:Gl_point.png]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Die Eckpunkte eines Polygones werden als einfache Punkte ohne Zwischenräume gezeichnet. Punktattribute wie GL_POINT_SIZE und GL_POINT_SMOOTH beinflussen die Wiedergabe der Punkte. Außer GL_POLYGONE_MODE haben andere Attribute keinerlei Auswirkung.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;GL_LINE&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[bild:Gl_line.png]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Miteinander verbundene Eckpunkte werden miteinander durch eine Linie verbunden. Attribute, die die Darstellung von Linien beinflussen wie zum Beispiel GL_LINE_WIDTH und GL_LINE_SMOOTH, verändern auch hier das Aussehen der Linien. Außer GL_POLYGONE_MODE haben andere Attribute keinerlei Auswirkung. Die Darstellung eines solch gezeichneten Models wird häufig als Drahtgitter-Model bezeichnet. Die Linien werden als zusammen gehörende Liniensegmente für das Stippling (siehe [[glLineStipple]] benutzt. Das heißt, das Tüpfelmuster wird zwischen den Linien nicht zurückgesetzt.&lt;br /&gt;
&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;GL_FILL&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;[[bild:Gl_fill.png]]&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;td&amp;gt;Das gesamte Polygon mitsamt seines Inneren also z.B. mit seiner Textur wird gezeichnet. Beachtet bitte, dass andere Attribute wie GL_POLYGON_STIPPLE und GL_POLYGON_SMOOTH ebenfalls die Wiedergabe des Polygons beinflussen könen. GL_FILL ist der Wert, der als Standard beim Initalisieren gesetzt wird.&amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Weitere Beispiele==&lt;br /&gt;
Nachfolgend noch einige Beispiele zum PolygonMode. (Um Vorder- und Rückseite sichtbar zu machen wurde die Kugel mittels [[glClipPlane]] zerschnitten.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div align=&amp;quot;center&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
! GL_FILL &lt;br /&gt;
! GL_LINE&lt;br /&gt;
|-&lt;br /&gt;
|[[Bild:Kugel_FILL.jpg]]&lt;br /&gt;
|[[Bild:Kugel_LINE.jpg]]&lt;br /&gt;
|-&lt;br /&gt;
! GL_POINT&lt;br /&gt;
! Vorderseite GL_FILL &amp;lt;br&amp;gt;Rückseite GL_LINE&lt;br /&gt;
|-&lt;br /&gt;
|[[Bild:Kugel_POINT.jpg]]&lt;br /&gt;
|[[Bild:Kugel_MIX.jpg]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
Eckpunkte werden mit dem &amp;quot;Edge Flag&amp;quot; als an der Grenze anliegend markiert. Diese werden automatisch intern von OpenGL generiert, wenn die Polygone zerlegt werden. Wenn Ihr diese gezielt selbst setzen wollt, müsst ihr [[glEdgeFlag]] nutzen. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fehlermeldungen ==&lt;br /&gt;
&lt;br /&gt;
GL_INVALID_ENUM wird generiert, wenn entweder face oder mode keine gültigen Werte waren.&amp;lt;br&amp;gt;&lt;br /&gt;
GL_INVALID_OPERATION wird generiert, wenn diese Funktion innerhalb eines glBegin/glEnd-Blocks aufgerufen wird.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Zugehörige Wertrückgaben ==&lt;br /&gt;
&lt;br /&gt;
[[glGet]] mit Token GL_POLYGON_MODE &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
&lt;br /&gt;
[[glBegin]], [[glEdgeFlag]], [[glLineStipple]], [[glLineWidth]], [[glPointSize]], [[glPolygonStipple]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:GL|PolygonMode]]&lt;br /&gt;
 [[Kategorie:GL1.0]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=glDepthFunc&amp;diff=21683</id>
		<title>glDepthFunc</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=glDepthFunc&amp;diff=21683"/>
				<updated>2008-05-08T18:24:27Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: /* Parameter */ Unnötiges Komma vor 'und' entfernt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= glDepthFunc =&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Name ==&lt;br /&gt;
Die Funktion glDepthFunc legt fest, wann ein [[Fragment]] den [[Tiefentest]] im [[Tiefenpuffer]] besteht.&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 '''procedure''' glDepthFunc(''func'': TGLenum);&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Parameter ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; rules=&amp;quot;all&amp;quot;&lt;br /&gt;
! ''func'' &lt;br /&gt;
| Legt die Tiefenvergleichsfunktion fest. Folgende symbolische Konstanten sind erlaubt: &amp;lt;br&amp;gt; '''GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL''' und '''GL_ALWAYS'''. Voreingestellt ist '''GL_LESS'''.&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Beschreibung ==&lt;br /&gt;
Die Funktion '''glDepthFunc''' legt fest, wann ein Fragment den Tiefentest im Tiefenpuffer besteht. &lt;br /&gt;
&lt;br /&gt;
Der Parameter ''func'' legt die Tiefenvergleichsfunktion fest. Die Tiefenvergleichsfunktion ist eine Bedingung, die erfüllt sein muss, damit das entsprechende Pixel/Fragment gezeichnet wird.&lt;br /&gt;
&lt;br /&gt;
Folgende Funktionen existieren:&lt;br /&gt;
{| {{Prettytable_B1}}&lt;br /&gt;
! GL_NEVER&lt;br /&gt;
| Neue Fragmente bestehen niemals den Vergleich.&lt;br /&gt;
|-&lt;br /&gt;
! GL_LESS&lt;br /&gt;
| Neue Fragmente bestehen den Vergleich, wenn sie einen geringeren Tiefenwert haben.&lt;br /&gt;
|-&lt;br /&gt;
! GL_EQUAL&lt;br /&gt;
| Neue Fragmente bestehen den Vergleich, wenn sie einen gleichgroßen Tiefenwert haben.&lt;br /&gt;
|-&lt;br /&gt;
! GL_LEQUAL&lt;br /&gt;
| Neue Fragmente bestehen den Vergleich, wenn sie einen kleineren oder gleichgroßen Tiefenwert haben.&lt;br /&gt;
|-&lt;br /&gt;
! GL_GREATER&lt;br /&gt;
| Neue Fragmente bestehen den Vergleich, wenn sie einen größeren Tiefenwert haben.&lt;br /&gt;
|-&lt;br /&gt;
! GL_NOTEQUAL&lt;br /&gt;
| Neue Fragmente bestehen den Vergleich, wenn sie einen anderen Tiefenwert haben.&lt;br /&gt;
|-&lt;br /&gt;
! GL_GEQUAL&lt;br /&gt;
| Neue Fragmente bestehen den Vergleich, wenn sie einen größeren oder gleichgroßen  Tiefenwert haben.&lt;br /&gt;
|-&lt;br /&gt;
! GL_ALWAYS&lt;br /&gt;
| Neue Fragmente bestehen immer den Test.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
Der Standartwert von ''func'' ist '''GL_LESS'''.&amp;lt;br&amp;gt;&lt;br /&gt;
Nach der Initalisierung der GL ist der Tiefentest deaktiviert. Den Tiefentest kann man mit [[glEnable#GL_DEPTH_TEST|glEnable('''GL_DEPTH_TEST''')]] aktivieren.&lt;br /&gt;
&lt;br /&gt;
== Fehlermeldungen ==&lt;br /&gt;
GL_INVALID_ENUM wird generiert wenn ''func'' ein ungültiger Wert übergeben wird.&amp;lt;br&amp;gt;&lt;br /&gt;
GL_INVALID_OPERATION wird generiert wenn '''glDepthFunc''' innerhalb eines [[glBegin]]-[[glEnd]] Blocks aufgerufen wird. &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
==  Zugehörige Wertrückgaben ==&lt;br /&gt;
[[glGet]] mit Token GL_DEPTH_FUNC&amp;lt;br&amp;gt;&lt;br /&gt;
[[glIsEnabled]] mit Token GL_DEPTH_TEST&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
[[Tiefenpuffer]], [[glDepthRange]], [[glEnable]]&lt;br /&gt;
&lt;br /&gt;
Hintergrundwissen: [[Tiefentest]]&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:GL|DepthFunc]]&lt;br /&gt;
 [[Kategorie:GL1.0]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=glGetError&amp;diff=21682</id>
		<title>glGetError</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=glGetError&amp;diff=21682"/>
				<updated>2008-05-08T16:51:51Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: /* Fehlerwerte */ Groß- und Kleinschreibung, Zusammen- und Getrenntschreibung. Ein paar Fehler korrigiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= glGetError =&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Name ==&lt;br /&gt;
'''glGetError''' - liefert Informationen über OpenGL-Fehler.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Delphi-Spezifikation ==&lt;br /&gt;
 '''Function''' glGetError : GLenum;&lt;br /&gt;
&lt;br /&gt;
== Beschreibung == &lt;br /&gt;
'''glGetError''' liefert den Wert des Error-Flags. &lt;br /&gt;
Jeder bemerkbare Fehler hat OpenGL-Intern einen numerischen Wert und einen symbolischen Namen.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn ein OpenGL-Fehler auftritt wird das Error-Flag auf den dafür vorgesehen Wert gesetzt.&amp;lt;br&amp;gt;&lt;br /&gt;
Sobald dies geschehen ist, werden keine anderen OpenGL-Fehler mehr registriert bis '''glGetError''' aufgerufen wird. &amp;lt;br&amp;gt;&lt;br /&gt;
(Das heißt, es wird immer nur der Fehler zurückgegeben, der zuerst auftrat.)&lt;br /&gt;
&lt;br /&gt;
Durch den Aufruf von '''glGetError''' wird der Fehlercode zurückgegeben, und das &lt;br /&gt;
Error-Flag wieder auf '''GL_NO_ERROR''' gesetzt.&amp;lt;br&amp;gt;&lt;br /&gt;
Wenn ein Aufruf von '''glGetError''' '''GL_NO_ERROR''' zurückgibt, bedeutet dies, dass kein registrierbarer Fehler seit dem letzten Aufruf von '''glGetError'''(bzw. seit dem die GL initialisiert wurde) aufgetreten ist.&lt;br /&gt;
&lt;br /&gt;
===Verteilte Implementationen===&lt;br /&gt;
&lt;br /&gt;
Bei verteilten Implementationen, kann es mehrere Error_Flags geben. Sobald eins dieser Flags einen Fehler registriert hat, wird, bei einem Aufruf von '''glGetError''', der Wert dieses Flags zurück geliefert und das entsprechende Flag auf '''GL_NO_ERROR''' gesetzt. &amp;lt;br&amp;gt;&lt;br /&gt;
Wenn mehrere Flags einen Fehler registriert haben, liefert und löscht '''glGetError''' den Wert eines zufällig ausgewählten Flags. Aus diesem Grund sollte man '''glGetError''' in einer Schleife solange abrufen bis '''GL_NO_ERROR''' zurückgegeben wird.&lt;br /&gt;
&lt;br /&gt;
===Fehlerwerte===&lt;br /&gt;
Der Initialisierungszustand des Error-Flags ist '''GL_NO_ERROR'''.&lt;br /&gt;
&lt;br /&gt;
In der aktuellen OpenGL Version sind folgende Fehler definiert:&lt;br /&gt;
&lt;br /&gt;
'''GL_NO_ERROR'''&lt;br /&gt;
:Kein Fehler ist aufgetreten.&lt;br /&gt;
:Der Wert dieser symbolischen Konstante ist garantiert immer 0.&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_ENUM'''&lt;br /&gt;
:Ein nicht akzeptierter Wert wurde einem numerischen Argument übergeben.&lt;br /&gt;
:Der fehlerhafte Befehl wird nicht ausgeführt und hat, abgesehen vom Setzen des Error_Flags keine weiteren Seiteneffekte.&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_VALUE'''&lt;br /&gt;
:Ein numerisches Argument ist außerhalb des vorgesehenen Intervalls. (out of range)&lt;br /&gt;
:Der fehlerhafte Befehl wird nicht ausgeführt und hat, abgesehen vom Setzen des Error_Flags keine weiteren Seiteneffekte.&lt;br /&gt;
&lt;br /&gt;
'''GL_INVALID_OPERATION'''&lt;br /&gt;
:Der spezielle Befehl ist im momentanen Zustand von OpenGl nicht zulässig.&lt;br /&gt;
:Der fehlerhafte Befehl wird nicht ausgeführt und hat, abgesehen vom Setzen des Error_Flags keine weiteren Seiteneffekte.&lt;br /&gt;
&lt;br /&gt;
'''GL_STACK_OVERFLOW'''&lt;br /&gt;
:Der entsprechende Befehl würde zum Überlaufen des Stacks führen. (Overflow)&lt;br /&gt;
:Der fehlerhafte Befehl wird nicht ausgeführt und hat, abgesehen vom Setzen des Error_Flags keine weiteren Seiteneffekte.&lt;br /&gt;
:(Dieser Fehler tritt vor allem dann auf, wenn es mehr Aufrufe von  [[glPushMatrix]] als von [[glPopMatrix]] gibt.)&lt;br /&gt;
&lt;br /&gt;
'''GL_STACK_UNDERFLOW''' &lt;br /&gt;
:Der entsprechende Befehl würde zum Unterlaufen des Stacks führen. (Underflow)&lt;br /&gt;
:Der fehlerhafte Befehl wird nicht ausgeführt und hat, abgesehen vom Setzen des Error_Flags keine weiteren Seiteneffekte.&lt;br /&gt;
:(Dieser Fehler tritt vor allem dann auf, wenn es mehr Aufrufe von [[glPopMatrix]] als von [[glPushMatrix]] gibt.)&lt;br /&gt;
&lt;br /&gt;
'''GL_OUT_OF_MEMORY'''&lt;br /&gt;
:Es existiert nicht genug Speicher um den Befehl auszuführen. &lt;br /&gt;
:Der Status von OpenGL ist nach dem Auftrten dieses Fehlers undefiniert (abgesehen von den Error-Flags).&lt;br /&gt;
&lt;br /&gt;
== Hinweise ==&lt;br /&gt;
Wenn ein Error-Flag gesetzt wird, ist nur im Falle '''GL_OUT_OF_MEMORY''' das Ergebnis der OpenGL undefiniert. In allen anderen Fällen wird der fehlerauslösende Befehl ignoriert und hat damit keine Auswirkungen auf den Status der GL oder den Inhalt des [[Framebuffer|Framebuffers]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fehlermeldungen ==&lt;br /&gt;
'''GL_INVALID_OPERATION''' wird generiert wenn '''glGetError''' innerhalb eines &lt;br /&gt;
[[glBegin]]-[[glEnd]] Blocks aufgerufen wird.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==  Zugehörige Wertrückgaben ==&lt;br /&gt;
'''glGetError''' liefert ihnen den Wert des Fehlers zurück, der als erstes, seit dem letzen Aufruf von '''glGetError''', aufgetreten ist.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
andere Wertrückgabefunktionen: [[glGet]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:GL|GetError]]&lt;br /&gt;
 [[Kategorie:GL1.0]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=TGA_Bilder_laden&amp;diff=21632</id>
		<title>TGA Bilder laden</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=TGA_Bilder_laden&amp;diff=21632"/>
				<updated>2008-05-02T16:35:30Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: Inhaltsverzeichnis angepasst &amp;amp; Kategorie: Tutorial&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= TGA Bilder laden =&lt;br /&gt;
&lt;br /&gt;
== TGA Dateien - Warum? ==&lt;br /&gt;
&lt;br /&gt;
In diesem Artikel geht es um das manuelle Laden von Truevision&lt;br /&gt;
Bilddateien mit der allseits bekannten Endung &amp;quot;.tga&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Dieses Dateiformat ist für den Anfang aus verschiedenen Gründen auf voller&lt;br /&gt;
Linie empfehlenswert. Es ist sehr einfach aufgebaut und die Pixeldaten liegen&lt;br /&gt;
auch schon in einer von &amp;quot;neueren&amp;quot; OpenGL-Implementierungen (konkret: 1.2) direkt benutzbaren&lt;br /&gt;
Ordnung vor.&lt;br /&gt;
&lt;br /&gt;
Komprimierte TGA-Dateien lassen wir außen vor,&lt;br /&gt;
da sie leider einige Nachteile mit sich bringen: Es ist schwieriger die Datei&lt;br /&gt;
einzulesen, das Dekodieren benötigt wertvolle Rechenzeit und die&lt;br /&gt;
RLE-Kompression, die in den TGA-Dateien zum Einsatz kommt, ist vergleichsweise&lt;br /&gt;
schlecht.&lt;br /&gt;
&lt;br /&gt;
== Landkarte und Kompass - oder besser GPS? ==&lt;br /&gt;
&lt;br /&gt;
Zuerst stellen wir uns die Frage, wie eine TGA-Datei intern aufgebaut ist.&lt;br /&gt;
Da es sich um eine Binärdatei handelt, lässt sich die Bedeutung der Daten nicht&lt;br /&gt;
erraten - wir sind also auf fremde Dokumentation angewiesen.&lt;br /&gt;
Eine ganze Sammlung solcher &amp;quot;Datei-Spickzettel&amp;quot; findet man auf der Internetseite&lt;br /&gt;
http://www.wotsit.org/.&lt;br /&gt;
&lt;br /&gt;
Nachdem wir uns das entsprechende Dokument von dort besorgt und kritisch&lt;br /&gt;
überflogen haben, fällt wohl erstmal ins Auge, dass es verschiedene Typen von&lt;br /&gt;
TGA-Dateien zu geben scheint.&lt;br /&gt;
&lt;br /&gt;
Wir beschäftigen uns hier nur mit Typ 2 (24/32-Bit TGA ohne Kompression), da es&lt;br /&gt;
das gebräuchlichste Format ist.&lt;br /&gt;
&lt;br /&gt;
== Definition eines Datentyps ==&lt;br /&gt;
&lt;br /&gt;
Welche Daten aus der TGA-Datei sind nun wirklich für unsere Zwecke interessant?&lt;br /&gt;
&lt;br /&gt;
  Image Type Code     - zum überprüfen, ob die Datei das richtige Format hat.&lt;br /&gt;
   Width of Image&lt;br /&gt;
  Height of Image&lt;br /&gt;
 Image Pixel Size     - anhand dieser können wir u.a. ermitteln, ob ein Alphakanal&lt;br /&gt;
                        vorhanden ist.&lt;br /&gt;
 Image Data Field     - die eigentlichen Pixeldaten&lt;br /&gt;
&lt;br /&gt;
Damit haben wir alles benötigte zusammen und können diese Informationen schon&lt;br /&gt;
mal in einen Verbundtyp packen (Die Datentypen entnehmen wir der &amp;quot;Length&amp;quot;-Spalte&lt;br /&gt;
in unserem Dokument von wotsit):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
type&lt;br /&gt;
  TTGAFile = record&lt;br /&gt;
    iType: byte;  // should be 2&lt;br /&gt;
     w, h: word;  // Width, Height&lt;br /&gt;
      bpp: byte;  // Byte per Pixel&lt;br /&gt;
     data: ^byte; // Pixels, dynamic length&lt;br /&gt;
  end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Die Datei laden ==&lt;br /&gt;
&lt;br /&gt;
Die Schritte, die nun erforderlich sind, um diese Struktur mit Leben zu Füllen&lt;br /&gt;
sind denkbar einfach. Zuerst wird die Datei binär geöffnet; der Dateizeiger mit&lt;br /&gt;
Seek positioniert (siehe &amp;quot;Offset&amp;quot;-Spalte in unserem Dokument) und mit Blockread&lt;br /&gt;
gelesen. Die Felder w, h und bpp liegen in der Datei nebeneinander; deshalb&lt;br /&gt;
können sie mit nur einer einzigen (anstatt 3) Seek/Blockread-Kombination&lt;br /&gt;
eingelesen werden. Da wir mit &amp;quot;Bit pro Pixel&amp;quot; wenig anfangen können teilen wir&lt;br /&gt;
bpp anschließend durch 8 und erhalten &amp;quot;Bytes pro Pixel&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Hinweis: Für den, der es an dieser Stelle lieber objektorientiert mag, bieten&lt;br /&gt;
sich natürlich auch Streams an. Allerdings ist dies für diesen konkreten Fall nicht von Belang.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
function LoadTGA(const filename: string): TTGAFile;&lt;br /&gt;
var f: file; bytes: longword;&lt;br /&gt;
begin&lt;br /&gt;
  assign(f, filename);&lt;br /&gt;
  reset(f, 1);&lt;br /&gt;
&lt;br /&gt;
  // type&lt;br /&gt;
  seek(f, 2);&lt;br /&gt;
  blockread(f, result.iType, 1);&lt;br /&gt;
&lt;br /&gt;
  // w, h, bpp&lt;br /&gt;
  seek(f, 12);&lt;br /&gt;
  blockread(f, result.w, 5);&lt;br /&gt;
  result.bpp := result.bpp div 8;&lt;br /&gt;
&lt;br /&gt;
  // data&lt;br /&gt;
  bytes := result.w * result.h * result.bpp;&lt;br /&gt;
  getmem(result.data, bytes);&lt;br /&gt;
  seek(f, 18);&lt;br /&gt;
  blockread(f, result.data^, bytes);&lt;br /&gt;
&lt;br /&gt;
  close(f);&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Diese Funktion lädt alle benötigten Daten aus der Datei; reserviert auf Basis&lt;br /&gt;
dieser Informationen genug Speicher für die Pixeldaten und liest sie dann ein.&lt;br /&gt;
Der Pointer kann anschließend direkt in OpenGL verwendet werden, wenn die&lt;br /&gt;
Implementierung die Formate GL_BGR und GL_BGRA unterstützt (je nach dem, ob&lt;br /&gt;
&amp;quot;bpp&amp;quot; den Wert 3 oder 4 erhalten hat).&lt;br /&gt;
&lt;br /&gt;
== Datei rein - Textur raus ==&lt;br /&gt;
&lt;br /&gt;
Die eigentliche Erzeugung des Texturobjektes gleicht dem &amp;quot;SDL-Weg&amp;quot;. Nur wird&lt;br /&gt;
hier unser eigenes Record anstatt einer SDL-Surface verwendet. Nicht vergessen&lt;br /&gt;
den dynamisch reservierten Speicher für die Pixeldaten nach der Verwendung mit&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
FreeMem(TGARecord.data);&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
wieder freizugeben!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pascal&amp;gt;&lt;br /&gt;
procedure TGATexture(const filename: string; var TexID: longword);&lt;br /&gt;
var&lt;br /&gt;
  tex: TTGAFile;&lt;br /&gt;
  glFormat: longword;&lt;br /&gt;
begin&lt;br /&gt;
  tex := LoadTGA(filename);&lt;br /&gt;
  if tex.iType = 2 then&lt;br /&gt;
  begin&lt;br /&gt;
    glGenTextures(1, @TexID);&lt;br /&gt;
    glBindTexture(GL_TEXTURE_2D, TexID);&lt;br /&gt;
&lt;br /&gt;
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);&lt;br /&gt;
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);&lt;br /&gt;
&lt;br /&gt;
    if tex.bpp = 3 then glFormat := GL_BGR&lt;br /&gt;
      else glFormat := GL_BGRA;&lt;br /&gt;
&lt;br /&gt;
    glTexImage2D(GL_TEXTURE_2D, 0, tex.bpp, tex.w, tex.h,&lt;br /&gt;
      0, glFormat, GL_UNSIGNED_BYTE, tex.data);&lt;br /&gt;
&lt;br /&gt;
    FreeMem(tex.data);&lt;br /&gt;
  end;&lt;br /&gt;
end;&lt;br /&gt;
&amp;lt;/pascal&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ich hoffe dieser Artikel war hilfreich (Ich will Feedback!) und wünsche euch&lt;br /&gt;
viel Spaß und Erfolg bei euren zukünftigen Projekten.&lt;br /&gt;
&lt;br /&gt;
Gruß Waran.&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Tutorial]]&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Benutzer:Yogu&amp;diff=21631</id>
		<title>Benutzer:Yogu</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Benutzer:Yogu&amp;diff=21631"/>
				<updated>2008-05-02T11:20:59Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: Rechtschreibfehler: Groß-/Kleinschreibung. fixed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hallo,&lt;br /&gt;
&lt;br /&gt;
ich möchte mich hier kurz vorstellen. Ich heiße Yogu (zumindest hier ;-)), programmiere seit dem 2. September 2004 in Delphi (ist zumindest meine älteste DPR), habe einen Monat davor mit [http://www.blitzbasic.com BlitzBasic] angefangen (und aufgehört!) und mehrere Delphi-Bücher durchgelesen, nochmal durchgelesen, gewartet, ein weiteres Mal durchgelesen und schließlich verstanden ;-)&lt;br /&gt;
&lt;br /&gt;
Ich hab in allen Möglichen Programmierbereichen mal reingeschaut, und manche auch etwas weiter verfolgt, z. B. einen Movie-Manager, einen Audio-Player und auch mal eine &amp;quot;3D-Engine&amp;quot; mit Canvas.Pixels ;-).&lt;br /&gt;
&lt;br /&gt;
Bevor ich auf OpenGL gestoßen bin, hab ich mit [http://www.genesis3d.com/ Genesis 3D] gearbeitet. Das war in einem [http://www.amazon.de/Game-Programming-Kids-Hans-Georg-Schumann/dp/3826608372 Buch] sehr anschaulich und einfach erklärt. Als ich dann jedoch vor kurzem angefangen habe, diese Engine etwas OOP-freundlicher zu verwalten, musste ich feststellen, dass sie doch Grenzen aufweist.&lt;br /&gt;
&lt;br /&gt;
Und dann hat mich gestern jemand im [http://www.delphi-forum.de Delphi-Forum] (übrigens eine sehr gute Adresse im Thema Delphi-Probleme!) durch einen Post wieder auf OpenGL aufmerksam gemacht. Ja, vor einiger Zeit war ich hier schon mal - damals hatte ich aber noch sehr viel weniger Ahnung vom 3D-Programmieren.&lt;br /&gt;
&lt;br /&gt;
Wenn du mir eine Nachricht hinterlassen willst, kannst du das in meiner [[Benutzer Diskussion:Yogu|Diskussionsseite]] tun.&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Benutzer_Diskussion:Yogu&amp;diff=21630</id>
		<title>Benutzer Diskussion:Yogu</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Benutzer_Diskussion:Yogu&amp;diff=21630"/>
				<updated>2008-05-02T11:20:18Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: Rechtschreibfehler: Groß-/Kleinschreibung. fixed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hallo,&lt;br /&gt;
&lt;br /&gt;
hier kannst du mir ([[Benutzer:Yogu|Yogu]]) eine Nachricht hinterlassen. Bitte füge deine Mitteilung an das Ende dieser Seite hinzu, indem du auf das [http://de.wikipedia.org/w/index.php?title=Benutzer_Diskussion:Yogu&amp;amp;action=edit&amp;amp;section=new Plus-Zeichen] hinter ''Seite bearbeiten'' klickst.&lt;br /&gt;
&lt;br /&gt;
Ich würde mich freuen, wenn du deine Nachricht freundlich verfasst und daran denkst, dass ich unfreundliche Mitteilungen nicht beachten werde.&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Benutzer_Diskussion:Yogu&amp;diff=21626</id>
		<title>Benutzer Diskussion:Yogu</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Benutzer_Diskussion:Yogu&amp;diff=21626"/>
				<updated>2008-05-01T19:12:20Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: Benutzerdiskussionsseite erstellt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hallo,&lt;br /&gt;
&lt;br /&gt;
hier kannst du mir ([[Benutzer:Yogu|Yogu]]) eine Nachricht hinterlassen. Bitte füge deine Mitteilung an das Ende dieser Seite hinzu, indem du auf das [http://de.wikipedia.org/w/index.php?title=Benutzer_Diskussion:Yogu&amp;amp;action=edit&amp;amp;section=new Plus-Zeichen] hinter ''Seite bearbeiten'' klickst.&lt;br /&gt;
&lt;br /&gt;
Ich würde mich freuen, wenn du Deine Nachricht freundlich verfasst und daran denkst, dass ich unfreundliche Mitteilungen nicht beachten werde.&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	<entry>
		<id>https://wiki.delphigl.com/index.php?title=Benutzer:Yogu&amp;diff=21625</id>
		<title>Benutzer:Yogu</title>
		<link rel="alternate" type="text/html" href="https://wiki.delphigl.com/index.php?title=Benutzer:Yogu&amp;diff=21625"/>
				<updated>2008-05-01T19:11:14Z</updated>
		
		<summary type="html">&lt;p&gt;Yogu: Benutzerseite erstellt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hallo,&lt;br /&gt;
&lt;br /&gt;
ich möchte mich hier kurz vorstellen. Ich heiße Yogu (zumindest hier ;-)), programmiere seit dem 2. September 2004 in Delphi (ist zumindest meine älteste DPR), habe einen Monat davor mit [http://www.blitzbasic.com BlitzBasic] angefangen (und aufgehört!) und mehrere Delphi-Bücher durchgelesen, nochmal durchgelesen, gewartet, ein weiteres Mal durchgelesen und schließlich verstanden ;-)&lt;br /&gt;
&lt;br /&gt;
Ich hab in allen Möglichen Programmierbereichen mal reingeschaut, und manche auch etwas weiter verfolgt, z. B. einen Movie-Manager, einen Audio-Player und auch mal eine &amp;quot;3D-Engine&amp;quot; mit Canvas.Pixels ;-).&lt;br /&gt;
&lt;br /&gt;
Bevor ich auf OpenGL gestoßen bin, hab ich mit [http://www.genesis3d.com/ Genesis 3D] gearbeitet. Das war in einem [http://www.amazon.de/Game-Programming-Kids-Hans-Georg-Schumann/dp/3826608372 Buch] sehr anschaulich und einfach erklärt. Als ich dann jedoch vor kurzem angefangen habe, diese Engine etwas OOP-freundlicher zu verwalten, musste ich feststellen, dass sie doch Grenzen aufweist.&lt;br /&gt;
&lt;br /&gt;
Und dann hat mich gestern jemand im [http://www.delphi-forum.de Delphi-Forum] (übrigens eine sehr gute Adresse im Thema Delphi-Probleme!) durch einen Post wieder auf OpenGL aufmerksam gemacht. Ja, vor einiger Zeit war ich hier schon mal - damals hatte ich aber noch sehr viel weniger Ahnung vom 3D-Programmieren.&lt;br /&gt;
&lt;br /&gt;
Wenn du mir eine Nachricht hinterlassen willst, kannst Du das in meiner [[Benutzer Diskussion:Yogu|Diskussionsseite]] tun.&lt;/div&gt;</summary>
		<author><name>Yogu</name></author>	</entry>

	</feed>