Einsteigerpfad: Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
K (Nochn bisl rumkorrigiert ;))
(Der Trampelpfad)
 
(13 dazwischenliegende Versionen von 7 Benutzern werden nicht angezeigt)
Zeile 9: Zeile 9:
  
 
==Der Trampelpfad==
 
==Der Trampelpfad==
Am Beginn steht bei den meisten [[OpenGL]] Anfängern die Frage "Was brauch ich um OpenGL zu benutzen?".  
+
Am Beginn steht bei den meisten [[OpenGL]] Anfängern die Frage "Was brauch ich um OpenGL zu benutzen?". Auf eurem Rechner sollte OpenGL verfügbar sein. Dazu wird ein '''Grafiktreiber''' benötigt. Unter Windows gibt es eine z.B. OpenGL.dll die vorhanden sein muss. Ihr braucht weiterhin eine Möglichkeit diesen Treiber anzusprechen, dafür gibt es '''Header/Bindings''' für eure Programmiersprachen. Für Delphi/Pascal bietet die DGL Community einen stets aktuell gehaltenen Header - die [[dglOpenGL.pas]]. Auf Wikipedia ist im OpenGL-Artikel eine Liste mit allen Sprachen für die es OpenGL Bindings gibt hinterlegt. Die Bindings findet man dann mit der Suchmaschine eurer Wahl. <br>
Wenn ihr mit Delphi arbeiten wollt dann ist der [[DGLOpenGL.pas]]-Header genau das richtige für euch. (Für alle anderen sollte [http://Google.de Google] die nötigen Dateien anbieten.) Für den schnellen Einstieg in OpenGL ist auch ein [[OpenGL Template]] keine schlechte Idee.
+
Für den schnellen Einstieg in OpenGL ist auch ein [[OpenGL Template]] keine schlechte Idee. Templates sind vorlagen die den immer gleichen Code für die Initialisierung bereits beinhalten, so dass ihr schneller zu Ergebnissen kommt. Idealerweise lest ihr euch an dieser Stelle den [[Tutorial quickstart|'''OpenGL Quickstart''']] durch, der erklärt wie man selber ein Template schreibt und grundlegende Infos für den OpenGL-Anfänger bereitstellt. (Viele weitere Hilfsmittel, Header usw. findet ihr im [[DGLSDK]].)
  
 
Mit diesen Hilfsmitteln seit ihr bereit einen Blick auf die OpenGL zu werfen. Wenn ihr euch ein Template besorgt habt findet ihr in diesem bestimmt eine Procedur oder Funktion welche "DrawScene" oder "Render" heißt. Dort kommen die Aufrufe der OpenGL-Befehle rein. Das Wiki verfügt über eine [[OpenGL-Funktionsübersicht|Übersicht]] aller OpenGL-, [[GLU]]-, [[WGL]]-, [[GLX]]- und [[GLUT]]-Funktionen.  
 
Mit diesen Hilfsmitteln seit ihr bereit einen Blick auf die OpenGL zu werfen. Wenn ihr euch ein Template besorgt habt findet ihr in diesem bestimmt eine Procedur oder Funktion welche "DrawScene" oder "Render" heißt. Dort kommen die Aufrufe der OpenGL-Befehle rein. Das Wiki verfügt über eine [[OpenGL-Funktionsübersicht|Übersicht]] aller OpenGL-, [[GLU]]-, [[WGL]]-, [[GLX]]- und [[GLUT]]-Funktionen.  
Zeile 35: Zeile 35:
 
  SwapBuffers(DC);
 
  SwapBuffers(DC);
  
Dieser kleine Schnipsel (welcher den kompletten Inhalt einer kleinen Renderprocedure darstellt) zeigt schon mehr von OpenGL als im Ramen des Einsteigerpfades erklärt werden soll. Zu aller erst etwas allgemeines. Was die einzelnen OpenGL bzw. GLU Befehle wirklich machen kann man ganz einfach herausfinden. Das Wiki enthält zu allen Befehlen (na gut, im Moment fehlen noch ein paar) Erklärungen. Unter anderem auch zu [[glBegin]], [[glVertex]], [[glColor]] und [[glTranslate]]. Die Erklärungen findet ihr in der [[OpenGL-Funktionsübersicht]].
+
Dieser kleine Schnipsel (welcher den kompletten Inhalt einer kleinen Renderprocedure darstellt) zeigt schon mehr von OpenGL als im Ramen des Einsteigerpfades erklärt werden soll (Dafür gibt es unsere [[Tutorial]]s). Zu aller erst etwas allgemeines. Was die einzelnen OpenGL bzw. GLU Befehle wirklich machen kann man ganz einfach herausfinden. Das Wiki enthält zu (fast) allen Befehlen Erklärungen. Unter anderem auch zu [[glBegin]], [[glVertex]], [[glColor]] und [[glTranslate]]. Die Erklärungen findet ihr in der [[OpenGL-Funktionsübersicht]].
  
 
'''Was macht aber nun der obige Code?''' <br>
 
'''Was macht aber nun der obige Code?''' <br>
Zu aller erst wird der Tiefenpuffer und der Farbpuffer gelöscht. Hier nur soviel dazu: Der Farbpuffer speichert für jedes Pixel die Farbkomponenten und der Tiefenpuffer die Tiefe des Pixels im Bildraum.  
+
Zu aller erst wird der [[Tiefenpuffer]] und der [[Farbpuffer]] gelöscht. Hier nur soviel dazu: Der Farbpuffer speichert für jedes Pixel die Farbkomponenten und der Tiefenpuffer die Tiefe des Pixels im Bildraum.  
 
Anschließend wird etwas sehr wichtiges gemacht: Es wird die aktuelle [[Matrix]] gewählt. OpenGL kennt 3 verschiedene Matrizen. Je nachdem was man machen will, kann man mittels [[glMatrixMode]] die entsprechende Matrix auswählen. <br>
 
Anschließend wird etwas sehr wichtiges gemacht: Es wird die aktuelle [[Matrix]] gewählt. OpenGL kennt 3 verschiedene Matrizen. Je nachdem was man machen will, kann man mittels [[glMatrixMode]] die entsprechende Matrix auswählen. <br>
 
Zuerst wird die "Kamera" postiert. Dazu wechselt man in die Projektionsmatrix. Dort angekommen setzt man diese erst einmal zurück. Danach wird festgelegt wie man auf die Scene schauen will und dann bestimmt man noch mittels [[glTranslate]] wie weit man vom Koordinatenursprung weg sein will.<br>
 
Zuerst wird die "Kamera" postiert. Dazu wechselt man in die Projektionsmatrix. Dort angekommen setzt man diese erst einmal zurück. Danach wird festgelegt wie man auf die Scene schauen will und dann bestimmt man noch mittels [[glTranslate]] wie weit man vom Koordinatenursprung weg sein will.<br>
 
Anschließend möchte man den eigentlichen Inhalt der Szene zeichnen. Dazu wird die Modelviewmatrix benutzt. Auch diese wird ersteinmal zurückgesetzt. Doch dann kommt der eigentlich interessante Teil.  
 
Anschließend möchte man den eigentlichen Inhalt der Szene zeichnen. Dazu wird die Modelviewmatrix benutzt. Auch diese wird ersteinmal zurückgesetzt. Doch dann kommt der eigentlich interessante Teil.  
  
Durch [[glBegin]] teilen wir der OpenGL mit, dass wir Vierecke zeichnen wollen. Dann kommt ein Aufruf von [[glColor]] mit dem wir OpenGL sagen welche Farbe alle nachfolgenden Punkte haben sollen. Dann wird der erste Punkt an OpenGL übergeben. Nachdem alle Punkte übergeben wurde teilt man OpenGL mit, dass die Punktdefinition beendet ist sorgt dafür, dass der Inhalt der Puffer auf den Monitor kommt.
+
Durch [[glBegin]] teilen wir der OpenGL mit, dass wir Vierecke zeichnen wollen. Dann kommt ein Aufruf von [[glColor]] mit dem wir OpenGL sagen welche Farbe alle nachfolgenden Punkte haben sollen (da wir vor jedem glVertex die Farbe ändern, hat jeder Eckpunkt eine andere Farbe). Dann wird der erste Punkt mittels glVertex an OpenGL übergeben. Nachdem alle Punkte übergeben wurde teilt man OpenGL mit, dass die Punktdefinition beendet ist und sorgt dafür, dass der Inhalt des Puffers auf den Monitor kommt. Wir zeichnen nämlich nicht direkt auf den Bildschirm, sondern nutzen Doublebuffering.
  
 
Das hätte man sich auch denken können oder? Stimmt deshalb hier noch einige Informationen, die Ihr wissen solltet:
 
Das hätte man sich auch denken können oder? Stimmt deshalb hier noch einige Informationen, die Ihr wissen solltet:
  
:OpenGL ist eine Statemachine. Das bedeutet, dass man durch die einzelnen Befehle OpenGL in einen neuen Status bringt. Zum Beispiel ist der Farbstatus nach der Initialisierung (1,1,1) (=Weiß). Durch glColor setzt man einen neuen Farbstatus. D.h. alle nachfolgenden [[Vertices]] werden in dieser Farbe gezeichnet. Genauso ist es mit all den Eigenschaften die man mittels [[glEnable]] an- und mit [[glDisable]] ausschalten kann.
+
:OpenGL ist eine Statemachine. Das bedeutet, dass man durch die einzelnen Befehle OpenGL in einen neuen Status bringt. Zum Beispiel ist der Farbstatus nach der Initialisierung (1,1,1) (=Weiß). Durch glColor setzt man einen neuen Farbstatus. D.h. alle nachfolgenden [[Vertices]] werden in dieser Farbe gezeichnet. Genauso ist es mit all den Eigenschaften die man mittels [[glEnable]] an- und mit [[glDisable]] ausschalten kann. Ein Status ist solange gültig bis er durch neue Werte ersetzt wird. Das bedeutet auch, dass das Ende der Zeichenfunktion die Werte nicht wieder zurücksetzt. Wenn die "Szene Zeichnen"-Function erneut aufgerufen wird, sind alle Einstellungen noch so wie beim Verlassen der Funktion. Aus diesem Grund muss z.B. [[glClear]] und [[glLoadIdentity]] in jedem Durchgang erneut aufgerufen werden.
  
 
:Um dem Anwender keine unfertigen Bilder zu präsentieren läßt man OpenGL meißt mit [[Doppelpufferung]] arbeiten. Hat man sich für Doppelpfferung entschieden so muss man unter Windows am Ende des Zeichenvorgangs '''SwapBuffers''' aufrufen.
 
:Um dem Anwender keine unfertigen Bilder zu präsentieren läßt man OpenGL meißt mit [[Doppelpufferung]] arbeiten. Hat man sich für Doppelpfferung entschieden so muss man unter Windows am Ende des Zeichenvorgangs '''SwapBuffers''' aufrufen.
  
:OpenGL unterscheidet zwischen Vorder- und Rückseiten. Das klingt auf den ersten Blick etwas seltsam aber schaut euch nocheinmal den obigen Code an. OpenGL zeichnet nicht ein, sondern zwei Vierecke. Einmal die Vorder- und einmal die Rückseite. Solange man sicher ist, dass man eh nur die Vorderseite sehen will kann man durch [[Backfaceculling]] die unnötigen Polygone vom Zeichenvorgang ausschließen.
+
:OpenGL unterscheidet zwischen Vorder- und Rückseiten. Das klingt auf den ersten Blick etwas seltsam aber schaut euch noch einmal den obigen Code an. OpenGL zeichnet nicht ein, sondern zwei Vierecke. Einmal die Vorder- und einmal die Rückseite. Solange man sicher ist, dass man eh nur die Vorderseite sehen will kann man durch [[Backfaceculling]] die unnötigen Polygone vom Zeichenvorgang ausschließen.
  
:Die Reihenfolge der Eckpunkte ist wichtig. Durch [[glVertex]] übergebt ihr OpenGL ja Punktkoordinaten im Raum. Um daraus ein Polygon zu machen werden diese Punkte in einer bestimmten reihenfolge Verbunden (Wie bei [[glBegin]] beschrieben). Wenn die Eckpunkte in Uhrzeigerrichtung übergeben wurden ist die entstehende Fläche für OpenGL eine Rückseite. Die Richtung kann mittels [[glFrontFace]] eingestellt werden, sollte aber nach Möglichkeit auf dem standard bleiben um nicht in Fremdcode plötzlich durcheinander zu kommen.
+
:Die Reihenfolge der Eckpunkte ist wichtig. Durch [[glVertex]] übergebt ihr OpenGL ja Punktkoordinaten im Raum. Um daraus ein Polygon zu machen werden diese Punkte in einer bestimmten Reihenfolge verbunden (Wie bei [[glBegin]] beschrieben). Wenn die Eckpunkte in Uhrzeigerrichtung übergeben wurden ist die entstehende Fläche für OpenGL eine Rückseite. Die Richtung kann mittels [[glFrontFace]] eingestellt werden, sollte aber nach Möglichkeit auf dem Standard bleiben um nicht in Fremdcode plötzlich durcheinander zu kommen. (Allgemein, sollte man Defaultwerte erst ändern wenn man es wirklich muss bzw. wenn man weiß warum. "Das ist so aber komisch." ist kein guter Grund.
  
 
==Tutorials==
 
==Tutorials==
Auf DelphiGL.com findet man eine Vielzahl [http://www.delphigl.com/tutorials.php Tutorials]. <br>
+
Man findet hier im Wiki eine Vielzahl an [[Tutorial|Tutorials]]. <br>
 
Für den Anfänger sind vorallem die '''Einsteiger Tutorials''' zu empfehlen.
 
Für den Anfänger sind vorallem die '''Einsteiger Tutorials''' zu empfehlen.
 +
 +
[[Kategorie:Trampelpfad]]

Aktuelle Version vom 16. Februar 2010, 23:17 Uhr

Der Einsteigerpfad

Einführung

Willkommen auf dem Einsteigerpfad des DelphiGL-Wikis. Dieser Pfad soll euch das DGL-Wiki näherbringen und dabei Euch einen Einblick in die Welt von OpenGL bieten.

Wie funktioniert der Trampelpfad? Im nachfolgenden Abschnitt findet ihr einen Text der euch etwas über OpenGL 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.

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 zu OpenGL-Tutorials die euch die Materie OpenGL genauer erklären werden.

Der Trampelpfad

Am Beginn steht bei den meisten OpenGL Anfängern die Frage "Was brauch ich um OpenGL zu benutzen?". Auf eurem Rechner sollte OpenGL verfügbar sein. Dazu wird ein Grafiktreiber benötigt. Unter Windows gibt es eine z.B. OpenGL.dll die vorhanden sein muss. Ihr braucht weiterhin eine Möglichkeit diesen Treiber anzusprechen, dafür gibt es Header/Bindings für eure Programmiersprachen. Für Delphi/Pascal bietet die DGL Community einen stets aktuell gehaltenen Header - die dglOpenGL.pas. Auf Wikipedia ist im OpenGL-Artikel eine Liste mit allen Sprachen für die es OpenGL Bindings gibt hinterlegt. Die Bindings findet man dann mit der Suchmaschine eurer Wahl.
Für den schnellen Einstieg in OpenGL ist auch ein OpenGL Template keine schlechte Idee. Templates sind vorlagen die den immer gleichen Code für die Initialisierung bereits beinhalten, so dass ihr schneller zu Ergebnissen kommt. Idealerweise lest ihr euch an dieser Stelle den OpenGL Quickstart durch, der erklärt wie man selber ein Template schreibt und grundlegende Infos für den OpenGL-Anfänger bereitstellt. (Viele weitere Hilfsmittel, Header usw. findet ihr im DGLSDK.)

Mit diesen Hilfsmitteln seit ihr bereit einen Blick auf die OpenGL zu werfen. Wenn ihr euch ein Template besorgt habt findet ihr in diesem bestimmt eine Procedur oder Funktion welche "DrawScene" oder "Render" heißt. Dort kommen die Aufrufe der OpenGL-Befehle rein. Das Wiki verfügt über eine Übersicht aller OpenGL-, GLU-, WGL-, GLX- und GLUT-Funktionen.

Um nicht völlig aus dem Nichts OpenGL erklären zu müssen, gibts hier einen kleinen OpenGL-Codeschnipsel.

glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(45.0, ClientWidth/ClientHeight, 1, 1000);

glTranslatef(0,0,-5);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity;

glBegin(GL_QUADS);
  glColor3f(1,0,0);  glVertex3f(0,0,0);
  glColor3f(0,1,0);  glVertex3f(1,0,0);
  glColor3f(0,0,1);  glVertex3f(1,1,0);
  glColor3f(1,1,0);  glVertex3f(0,1,0);
glEnd;

SwapBuffers(DC);

Dieser kleine Schnipsel (welcher den kompletten Inhalt einer kleinen Renderprocedure darstellt) zeigt schon mehr von OpenGL als im Ramen des Einsteigerpfades erklärt werden soll (Dafür gibt es unsere Tutorials). Zu aller erst etwas allgemeines. Was die einzelnen OpenGL bzw. GLU Befehle wirklich machen kann man ganz einfach herausfinden. Das Wiki enthält zu (fast) allen Befehlen Erklärungen. Unter anderem auch zu glBegin, glVertex, glColor und glTranslate. Die Erklärungen findet ihr in der OpenGL-Funktionsübersicht.

Was macht aber nun der obige Code?
Zu aller erst wird der Tiefenpuffer und der Farbpuffer gelöscht. Hier nur soviel dazu: Der Farbpuffer speichert für jedes Pixel die Farbkomponenten und der Tiefenpuffer die Tiefe des Pixels im Bildraum. Anschließend wird etwas sehr wichtiges gemacht: Es wird die aktuelle Matrix gewählt. OpenGL kennt 3 verschiedene Matrizen. Je nachdem was man machen will, kann man mittels glMatrixMode die entsprechende Matrix auswählen.
Zuerst wird die "Kamera" postiert. Dazu wechselt man in die Projektionsmatrix. Dort angekommen setzt man diese erst einmal zurück. Danach wird festgelegt wie man auf die Scene schauen will und dann bestimmt man noch mittels glTranslate wie weit man vom Koordinatenursprung weg sein will.
Anschließend möchte man den eigentlichen Inhalt der Szene zeichnen. Dazu wird die Modelviewmatrix benutzt. Auch diese wird ersteinmal zurückgesetzt. Doch dann kommt der eigentlich interessante Teil.

Durch glBegin teilen wir der OpenGL mit, dass wir Vierecke zeichnen wollen. Dann kommt ein Aufruf von glColor mit dem wir OpenGL sagen welche Farbe alle nachfolgenden Punkte haben sollen (da wir vor jedem glVertex die Farbe ändern, hat jeder Eckpunkt eine andere Farbe). Dann wird der erste Punkt mittels glVertex an OpenGL übergeben. Nachdem alle Punkte übergeben wurde teilt man OpenGL mit, dass die Punktdefinition beendet ist und sorgt dafür, dass der Inhalt des Puffers auf den Monitor kommt. Wir zeichnen nämlich nicht direkt auf den Bildschirm, sondern nutzen Doublebuffering.

Das hätte man sich auch denken können oder? Stimmt deshalb hier noch einige Informationen, die Ihr wissen solltet:

OpenGL ist eine Statemachine. Das bedeutet, dass man durch die einzelnen Befehle OpenGL in einen neuen Status bringt. Zum Beispiel ist der Farbstatus nach der Initialisierung (1,1,1) (=Weiß). Durch glColor setzt man einen neuen Farbstatus. D.h. alle nachfolgenden Vertices werden in dieser Farbe gezeichnet. Genauso ist es mit all den Eigenschaften die man mittels glEnable an- und mit glDisable ausschalten kann. Ein Status ist solange gültig bis er durch neue Werte ersetzt wird. Das bedeutet auch, dass das Ende der Zeichenfunktion die Werte nicht wieder zurücksetzt. Wenn die "Szene Zeichnen"-Function erneut aufgerufen wird, sind alle Einstellungen noch so wie beim Verlassen der Funktion. Aus diesem Grund muss z.B. glClear und glLoadIdentity in jedem Durchgang erneut aufgerufen werden.
Um dem Anwender keine unfertigen Bilder zu präsentieren läßt man OpenGL meißt mit Doppelpufferung arbeiten. Hat man sich für Doppelpfferung entschieden so muss man unter Windows am Ende des Zeichenvorgangs SwapBuffers aufrufen.
OpenGL unterscheidet zwischen Vorder- und Rückseiten. Das klingt auf den ersten Blick etwas seltsam aber schaut euch noch einmal den obigen Code an. OpenGL zeichnet nicht ein, sondern zwei Vierecke. Einmal die Vorder- und einmal die Rückseite. Solange man sicher ist, dass man eh nur die Vorderseite sehen will kann man durch Backfaceculling die unnötigen Polygone vom Zeichenvorgang ausschließen.
Die Reihenfolge der Eckpunkte ist wichtig. Durch glVertex übergebt ihr OpenGL ja Punktkoordinaten im Raum. Um daraus ein Polygon zu machen werden diese Punkte in einer bestimmten Reihenfolge verbunden (Wie bei glBegin beschrieben). Wenn die Eckpunkte in Uhrzeigerrichtung übergeben wurden ist die entstehende Fläche für OpenGL eine Rückseite. Die Richtung kann mittels glFrontFace eingestellt werden, sollte aber nach Möglichkeit auf dem Standard bleiben um nicht in Fremdcode plötzlich durcheinander zu kommen. (Allgemein, sollte man Defaultwerte erst ändern wenn man es wirklich muss bzw. wenn man weiß warum. "Das ist so aber komisch." ist kein guter Grund.

Tutorials

Man findet hier im Wiki eine Vielzahl an Tutorials.
Für den Anfänger sind vorallem die Einsteiger Tutorials zu empfehlen.