Welcome to the new Friends-of-FPC!

Here you can find all kinds of information about the FreePascal Compiler. We have many tutorials and howtos as well as a selection of tools to help you with your programming. We also have some example codes for you. And if you want to contribute some information/ sources/ tools yourself you can do so.
Also we have finally relaunched the FoFPC forum. It's your chance for some Q&A about everything FreePascal.

Friends-of-FPC

Tutorials: Learn how to code with FreePascal.

Source Codes: A collection of examples, miscellaneous source codes and open source stuff.

Tools and Help Files: Intro- duction of some tools that might help you with FPC.

Community

Forum: Ask or answer questions about the FreePascal Compiler, programming or just babble about coding.

Contribute! Contribute your own Tutorial, Source Codes or Tools and send them to us!

Website

About: Information about Friends-of-FPC.org.

Einführung in OpenGL - Teil 3 - by Delax

Nachdem wir nun unser OpenGL Fenster haben müssen wir "nur noch" etwas darstellen. Dazu muß jedoch zuerst OpenGL initialisiert werden.

"Haben wir das nicht vorhin gemacht?" fragt ihr euch vielleicht. Nein, bis jetzt fand alles auf Windows Ebene statt. Nun folgen Initialisierungen wie "Welche Größe hat meine Matrix?", "Welches Koordinatensystem will ich?" und "Welche Form von Perspektive will ich verwenden?". So was halt.

In OpenGL kommt es immer erst zu einer grundlegenden Initialisierung der Darstellung, dann werden Features aktiviert bzw. deaktiviert und schließlich noch was auch immer dargestellt. Fangen wir mit der Initialisierung an.

PROCEDURE OpenGL_Init;
begin

  glClearColor( 0.0, 0.0, 0.0, 0.0 );

  glViewport( 0, 0, width, height );
  glMatrixMode( GL_PROJECTION );
  glLoadIdentity();

  glOrtho( -2, 2, -2*height/width, 2*height/width, -2, 2);

  glMatrixMode( GL_MODELVIEW );
  glLoadIdentity();

end;

Die erste Zeile kennen wir schon. Danach folgt glViewport(). Dies definiert die Ausmaße des Sichtfeldes. Die ersten beiden Werte sind sind die Koordinaten links oben (meißtens 0,0). Die beiden Maximalwerte (rechts unten) setzen wir auf width und height, die ja unsere Fensterausmaße enthalten.

Dies kann dazu benutzt werden, um zum Beispiel nur in einer Hälfte des Fensters zu zeichnen. Dazu definiert man einfach den Viewport von 0,0 bis width/2, heigh/2. Anschließend kann man in der anderen Hälfte z.B. Windows Controls und Buttons einfügen.

glMatrixMode() setzt die Art der Matrixoperationen fest, die OpenGL durchführen soll. Das ist etwas kompliziert zu verstehen. Wann immer man die Matrix beeinflussen will, muß man angeben was genau man verändern will.

Es gibt 3 Arten von Matrixoperationen, von denen wir hier 2 kennen lernen. Die erste ist GL_MODELVIEW. Damit manipuliert man die Ansicht auf die Matrix bzw. deren Ausmaße. Mit GL_PROJECTION beeinflusst man die Darstellung bzw. Projektion der Matrix. Hmm...besser kann ich das, ohne in die 3D und Matrix Theorie einzutauchen, leider nicht erklären und das wäre etwas vorbei am Sinn dieses Tutorials.

Wichtiger als die Ansagen sind die Aktionen, die wir in diesen Manipulationen durchführen. glLoadIdentity(); werdet ihr sicherlich oft benutzen. Es ist ein Reset unserer Matrix.

Jetzt erzeugen wir eine Projektion für unsere Darstellung. Es gibt 2 Arten von Projektion: orthographisch und perspektivisch. Beides sind eigentlich Perspektiven, nur basieren sie auf verschiedenen Annahmen. Perspektivische Projektion ist das, was wir aus dem Alltag her kennen - Gegenstände werden kleiner je weiter sie entfernt sind. Bei orthographischer Projektion ist das anders: Gegenstände haben die selbe Größe, egal wie weit entfernt. Es ist die 2D Umsetzung einer 3D Welt. Macht ein Auge zu und ihr habt orthographisches Sehen (auch wenn euer Hirn versucht das zu kompensieren).

Wir beginnen mit einer orthographischen Projektion. Wir definieren das mit glOrtho( -2, 2, -2*height/width, 2*height/width, -2, 2); Na gut, was bedeuten die Zahlen? Die ersten beiden sind Min und Max auf der X-Achse. Drei und vier sind Min und Max auf der Y-Achse und die letzten beiden sind Min und Max auf der Z-Achse. Was immer wir innerhalb dieses Raumes zeichnen, wird dargestellt.

"Wieso so krumme Zahlen auf der Y Achse?" fragt ihr euch vielleicht. Nun, ganz einfach. Das Fenster ist ja auch kein Rechteck, sondern meißtens breiter als hoch. Bsp: 640x480, 800x600, usw. Also muß zusätzlich zur normalen Länge (in unserem Fall 2) der Aspekt des Fensters mit eingerechnet werden. Diesen bekommt man, indem einfach die Höhe durch die Breite geteilt wird und dieses Ergebnis mit der Normlänge multipliziert wird. In den meißten Fällen ist der Fensteraspekt 4:3, also ~1.3.

Am Modelview ändern wir nichts und führen nur ein Reset durch. So, und damit ist OpenGL konfiguriert und es kann mit dem zeichnen los gehen. Hierzu nutzen wir eine neue Proc namens "Draw_OpenGL".

PROCEDURE Draw_OpenGL;
begin

  glClear( GL_COLOR_BUFFER_BIT );

  glColor3f( 1.0, 0.0, 0.0 );

  glBegin(GL_TRIANGLES);

    glVertex3f(0.0, 1.0, 0.0);
    glVertex3f(-1.0, -1.0, 0.0);
    glVertex3f(1.0, -1.0, 0.0);

  glEnd();  

end;

Die erste Aktion, die wir durchführen ist den Bildschirm zu löschen. Dies besorgt glClear();. In dem Aufruf wird angegeben, was eigentlich gelöscht werden soll. In unserem Fall haben wir ja eine Hintergrundfarbe definiert, mit der wir den Bildschirm löschen wollen, die über unsere Buffer geschrieben wird.

Mit glColor3f(); legt man die Farbe des zu zeichnenden Objektes fest. Diese gilt so lange, bis eine andere Farbe definiert wird.

Hier kommen wir auch gleich zu der Erklärung dieser Endungen. Die normale Anweisung lautet glColor gefolgt von der Anzahl der Parameter und der Datentyps. "3f" steht für 3 float, also 3 Fließkommatypen. "3ub" würde für "3 unsigned byte" stehen, also 3 Werte von 0 bis 255. Anstatt also von 0.0 (minimal) bis 1.0 (maximal) kann man hier die RGB Werte von 0 (minimal) bis 255 (maximal) angeben. Jedem das seine eben. Von den Werten <> 3 lassen wir erst noch die Finger.

Nun kommen wir zum wesentlichen. Mit glBegin(); beginnen wir etwas auszugeben. Was wir ausgeben wollen muß mit angegeben werden. Im Moment wollen wir Dreiecke zeichnen (Triangles). Folglich müssen wir innerhalb von glBegin(); und glEnd; mindestens drei Vertices ( Vertex = Punkt im Raum) angeben. Wenn man mehr als nur ein Dreieck zeichnen will, kann man auch mehrere Vertices innerhalb von glBegin(GL_TRIANGLES); angeben. Man sollte aber darauf achten bei einem Vielfachen von 3 zu bleiben.

Ein Vertex gibt man bei OpenGL mit glVertex3f(); an. 3f steht in dem Fall für "3 Float", also 3 Angaben (für X/ Y und Z koordinate) und Float für eine Fließkommazahl. Es gibt auch noch andere glVertex Varianten, wie wir später sehen werden.

Wir geben also 3 Punkte für je ein Eckpunkt unseres Dreiecks an. Beachtet auch, wie wir das Dreieck zeichnen bzw. die Vertices setzen:

Wenn man ein GL_TRIANGLE zeichnet, so ist die Frontseite stets gegen den Uhrzeigersinn gezeichnet. Also wäre die linke Darstellung die Frontseite und die rechte Darstellung die Rückseite des Dreiecks.

Danach beenden wir die OpenGL Zeichnung und die Prozedur.

Und das wars eigentlich auch schon. Wir geben ein simples, rotes Dreieck aus. Das komplette Programm gibt es hier als Download. Kompiliert es, spielt mit den Farben und Vertices, fügt neue Dreiecke hinzu und so weiter. Kurz: spielt damit. Und damit: bis zum nächsten Mal.

Delax/ Sundancer Inc.
[delax@sundancerinc.de]

Back to previous page

Useful Links









Link to us