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 10 - by Delax

Jetzt kommt mal wieder etwas völlig anderes. Wenn ihr das Beispiel aus dem letzten Teil anschaut, oder euch vielleicht selbst Objekte gebaut habt, wird euch sicherlich auffallen, das da etwas nicht stimmt. Die Perspektive ist falsch.

Nun, wie zu Anfang schon gesagt verwenden wir orthographische Projektion. Diese funktioniert anders als die perspektivische. So werden zum Beispiel Gegenstände in der Ferne nicht kleiner und so wirkt unsere ganze Darstellung eines Objekts einfach falsch.

Jetzt heißt das nicht, das orthographische Projektion keinen Sinn macht, im Gegenteil. Es ist aber so das bei der Darstellung von 3D Objekten die perspektivische Darstellung besser für den Betrachter wirkt.

Um die perspektivische Projektion zu aktivieren benötigt man etwas Hilfe "von außen". Genauer gesagt von der Unit "GLU". GLU ist die "OpenGL Utility Library" und kümmert sich um eine handvoll spezieller Dinge. Unter anderem um die Berechnung der Perspektive, aber auch um Kurven und gekrümmte Flächen. Diese Unit binden wir wie die bisherigen Units in unsere Uses-Sektion ein.

USES
  windows,      // Windows API Stuff
  gl_sl,        // OpenGL API Stuff
  glu_sl,       // OpenGL Utility Lib
  OpenGL32;     // OpenGL API Stuff

Nun können wir mit der Hilfe von GLU die Perspektive setzen. Dazu ändern wir die OpenGL_Init etwas ab.

  glClearColor( 0.0, 0.0, 0.0, 0.0 );

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

  gluPerspective(45.0,width/height,0.1,100.0);

  glMatrixMode( GL_MODELVIEW );
  glLoadIdentity();

  glClearDepth(1.0);                  // Depth Buffer Setup
  glEnable(GL_DEPTH_TEST);            // Enables Depth Testing
  glDepthFunc(GL_LEQUAL);             // The Type Of Depth Test To Do

Im Prinzip ist alles gleich geblieben, nur definieren wir die Projektion jetzt nicht mehr mit glOrtho, sondern mit gluPerspective. Beachtet das jede Funktion als Prefix den Bezeichner ihrer OpenGL Unit hat. Also alle Funktionen der GLU Unit tragen auch das glu-Prefix.

gluPerspective hat 4 Parameter und unterscheidet sich sowohl vom Aufruf als auch in der Funktionsweise doch sehr von glOrtho. Der erste Parameter ist Gradzahl des Sichtfeldes in Einheiten auf der Y-Achse. Also stellt euch vor, ihr seht von oben auf ein Fußballfeld. An einem Ende steht eine Person und schaut auf das Feld. Wenn wir nun sein direktes Sichtfeld sichtbar machen würden käme in etwa folgendes dabei heraus...

Also der blaue Punkt ist der Betrachter. Das rot eingefärbte ist sein Sichtfeld. Die Gradzahl des Winkels, mit welchem das Sichtfeld von ihm ausgeht ist der erste Parameter. Alles klar?

Der zweite Parameter ist der Aspekt des Fensters. Das kennen wir schon von früher (siehe Teil 3). Hier wird berechnet, wie sich die X-Achse zur Y-Achse verhält. Und da wir über die Y-Achse schon Angaben gemacht haben (der erste Parameter) kann OpenGL somit Rückschlüsse auf die Größe und Berechnung der X-Achse machen.

Der dritte Wert definiert, in welcher Entfernung vom Betrachter (0/0/0) etwas dargestellt wird. Also einmal angenommen wir setzen diesen Wert auf 1.0 und zeichnen einen Punkt bei Z=0.5, so würde dieser nicht dargestellt. Er würde geclippt werden. Wir setzen also den Wert, in welcher Entfernung vom Betrachter das Sichtfeld beginnt. Aber Überraschung. Dieser Wert kann nur positiv sein. Es geht also NICHT wie bei orthographischer Projektion einen Bereich von -2.0z bis +2.0z zu erzeugen.

Mit dem vierten Parameter gibt man das Ende des Sichtbereiches an. Also bei welchem Z-Wert das Sichtfeld des Betrachters endet. Noch einmal der Hinweis: bei den letzten beiden Werten handelt es sich nicht um Koordinaten auf der Z-Achse, sondern um Werte, die vom Betrachter ausgehen. Also ein Wert von 100 als 4. Parameter heißt NICHT 100 auf der Z-Achse, sondern 100 Einheiten Sichtweite! Selbiges gilt für den dritten Parameter.

Hier noch einmal eine Übersicht welcher Parameter für was gut ist.

Alles klar? Ist nicht wirklich schwer, nur eben anders. Und dieses "anders" beinhaltet auch das eure Objekte etwas anders gebaut werden müssen. Von nun an müssen Transformationen und Rotationen geschickter eingesetzt werden, eben weil der Mittelpunkt der Matrix nicht mehr unbedingt im Mittelpunkt des Fensters liegt.

Unsere Draw_OpenGL Prozedur ändert sich wiefolgt.

  glTranslatef(0.0,0.0,-5.0);
  glRotatef( rotation, 1.0, 1.0, 0.0 );                         

     glBegin( GL_TRIANGLES );

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

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

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

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

     glEnd();

     glBegin( GL_QUADS );

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

     glEnd();

Der einzige Unterschied ist, das wir die Matrix um 5 Einheiten in den Bildschirm hinten verschieben. Wenn wir die nicht tun, würden wir die Pyramide um den Nullpunkt (0/0/0) herum bauen. Das ging vorhin nur, weil wir den Nullpunkt als Zentrum unserer Matrix definiert haben. Jetzt ist der Nullpunkt aber der Betrachter. Also bringen wir etwas Abstand zwischen uns und das Objekt. Und siehe da - es erscheint vor uns. Und sogar mit einer "richtigen" Perspektive.

Hier der komplette Source zum Beispiel.

Anmerkung: In einigen Versionen des OpenGL Packages von FPC hat sich ein Fehler eingeschlichen. Bei der glu_sl Datei ist als Bezeichnung der Unit "glu" angegeben. Da aber Units als Bezeichnung immer ihren Dateinamen haben müssen, beschwert sich der Compiler folgendermaßen: glu_sl.pp(36,6) Error: Illegal unit name: GLU. Wenn das der Fall ist, müsst ihr eure GLU_SL Datei ändern. Löscht dazu in eurem Verzeichnis C:\PP\UNITS\WIN32\ (oder wo auch immer ihr FPC installiert habt) die Datei "GLU_SL.PPW" und "GLU_SL.OW" (oder besser noch: benennt die Dateien in "GLU_SL.PPW.OLD" o.ä. um). Dann wechselt ihr in das Verzeichnis C:\PP\SOURCE\PACKAGES\OPENGL\WIN32\ und öffnet die Datei "GLU_SL.PP" mit einem Editor. Gebt als "PROGRAM" Bezeichner statt "GLU" einfach "GLU_SL" an. Nun kompiliert die Unit und kopiert anschließend die Dateien nach C:\PP\UNITS\WIN32\. Jetzt sollte das Problem behoben sein.

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

Back to previous page

Useful Links









Link to us