OpenGl mit C++ - Thomas Cassebaum

Transcription

OpenGl mit C++ - Thomas Cassebaum
Thomas Cassebaum
OpenGl mit C++
Kursskript 2012
Thomas Cassebaum
OpenGL mit C++
Seite 2
INHALTSVZEICHNIS
1.
OpenGl, eine OpenSource - Grafikbibliothek
1.1 Einleitung ................................................................................................................................................................ 3
1.2 Die Zusatzbibliotheken GLU und GLUT ................................................................................................................... 3
1.3 OpenGL - Grundstrukturen ..................................................................................................................................... 3
1.4 Das Frustum ............................................................................................................................................................ 4
1.5 Der Befehlsaufbau in OpenGL ................................................................................................................................ 5
1.6 Farbe, Licht und Oberflächen ................................................................................................................................. 5
1.7 Erstes OpenGL-Programm mit maximaler Kommentierung (Zeichnen einiger 2D-Linien) ................................... 7
2.
Algeo, eine Bibliothek zur vereinfachten Realisierung, algebraisch-geometrischer Objekte
2.1 Grundidee ............................................................................................................................................................... 8
2.2. Basisfunktionalität von ALGEO ............................................................................................................................... 8
2.3 Erstes ALGEO-Programm mit Kommentierung....................................................................................................... 9
Aufgaben zu ALGEO ...................................................................................................................................................... 10
OpenGL und GLUT API - Auszug ................................................................................................................................ 11
ALGEO API - Auszug.................................................................................................................................................. 12
Glossar zu 3D-Begriffen, RGB-Farbtabelle mit Werten für Algeo-Farbvektoren ......................................................... 14
Linksammlung zum Thema und Literaturquellen......................................................................................................... 15
Thomas Cassebaum
1. OPENGL
OpenGL mit C++
Seite 3
EINE FREIE GRAFIKBIB LIOTHEK
1.1 Einleitung
OpenGL ist eine plattformunabhängige Grafikbibliothek, die inzwischen zu einem weltweiten Standard für 3D-Grafikprogrammierung geworden ist. Sie wird sehr vielfältig verwendet: In der Industrie, in Forschungszentren, in der Spieleprogrammierung
und in der Lehre.
Die Plattformunabhängigkeit wird dadurch erreicht, dass OpenGL tatsächlich nur die Spezifikation einer Bibliothek ist, für die
verschiedene Versionen existieren, die von verschiedenen Grafikkarten, Betriebssystemen und Programmiersprachen unterstützt werden. Es existieren Pascal-Varianten in Borland Delphi, in den meisten Anwendungen wird aber eine C- Syntax genutzt.
Die wichtigsten Elemente von OpenGL sind:

Geometrische Objekte wie Punkte, Geraden, Kreise, Polygone, Dreiecksnetze, Ebenen, Kugeln, Quader, Quadriken und
weitere spezielle 2- oder 3-dimensionale geometrische Objekttypen,

Transformationen (Streckung, Drehung, Spiegelung, Scherung), Projektionen (Parallel- und Zentralprojektion),

Orthogonales oder perspektivisches Frustum-Modell, Clipping planes, Kameradefinitionen,

Bilddarstellung (Rendering) in hoher Qualität, Entfernen verdeckter Flächen, mehrfache Lichtquellen, Oberflächenmaterial, Texturen, Farbverlauf, Nebel, Blending, Antialiasing, Bewegungsunschärfe, weiche Schatten, Tiefeneffekte …,

GLSL (Graphics Library Shading Language) ab OpenGL 2.0.
1.2 Die Zusatzbibliotheken GLU und GLUT
Die Zusatzbibliothek GLU (OpenGL Utility Library) stellt reichhaltigere Zeichenprimitive zur Verfügung als OpenGL, Kurven, Flächen und Funktionen zur Spezifikation von 3D-Szenen. Alle Namen der GLU-Funktionen beginnen mit dem Präfix “glu“.
z.B. gluPerspective(..); zur Definition des perspektivischen Modells mit Winkel, „aspect ratio“ und den „clipping planes“.
Eine weitere Zusatzbibliothek GLUT (OpenGL Utility Toolkit) behandelt die Interaktion. Sie stellt Funktionen zum Aufbau von Fenstern und zum Behandeln von Tastatur- und Mausereignissen zur Verfügung. Außerdem enthält sie Möglichkeiten zum Aufbau
grafischer Benutzeroberflächen. Schließlich definiert GLUT noch einige komplexe geometrische Objekte wie Polyeder und die
berühmte „Teekanne“. Alle GLUT-Funktionen erkannt man an dem Kommando-Präfix “glut“.
Vor der ersten Verwendung der beiden Bibliotheken müssen die Header „glut.h“ und „glu.h“ in das include-Verzeichnis des
Compilers kopiert werden und später in jeden GLUT/GLU-Quelltext mit #include <glut.h> eingefügt werden.
1.3 OpenGL - Grundstrukturen
Ein „Fenster“ von OpenGL ist eine rechteckige Fläche auf einem physikalischen Darstellungsmedium, in das die Grafiken zeichnet
werden. Ein OpenGL-Fenster entspricht meist im Stil einem Fenster des Fenstermanagers im verwendeten Betriebssystem. Es
besitzt einen Titeltext, eine Breite und eine Höhe in Pixeln. Auf Wunsch kann von Beginn an die Vollbilddarstellung für das
OpenGL-Fenster aktiviert werden.
Ein Ereignis tritt ein, wenn der Benutzer ein Eingabemedium (Maus, Tastatur …) betätigt. Für jedes Ereignis, das eintreten kann,
sollte eine eigene Behandlungsfunktion („handle“) als callback function mit einer definierten Reaktion existieren, die nach dem
Eintreten des Ereignisses durch OpenGL automatisch veranlasst werden soll.
Nach einigen Vorbereitungen zur Initialisierung der beteiligten Systeme startet eine OpenGL-Anwendung automatisch eine
Schleife, die während des gesamten Renderings nicht mehr endet. Diese Hauptereignisschleife prüft zyklisch, ob Ereignisse
stattgefunden haben und ruft die zugehörigen „handles“ als Reaktion auf.
Die Hauptereignisschleife verhält sich in Pseudocode wie folgt:
void glutMainLoop (void)
while ( true)
{
if ( Grafik geändert )
DISPLAY - handle starten ;
if ( Fenster verschoben oder Größe geändert ) RESHAPE - handle starten ;
if ( Tastatur- oder Mausereignis )
KEYBOARD - oder MOUSE - handle starten ;
IDLE-handle starten ; // idle - dt: untätig
}
Die handles sind vom Programmierer selbst zu benennen und als Funktion zu definieren.
Thomas Cassebaum
OpenGL mit C++
Seite 4
1.4 Das Frustum
Frustum (dt. Stumpf) oder häufig auch als "viewing frustum" bezeichnet, steht im Bereich der 3D-Grafik für einen Körper, dessen
Inhalt in irgendeiner Form auf dem Bildschirm dargestellt wird. Die Projektionsebene ist das das 2D-Bild des Frustums. Das menschliche Auge
Near Clipping Plane
überführt ein perspektives Frustum auf die Netzhaut: Mit steigender
Entfernung wird ein Objekt direkt proportional kleiner.
Die schwarze Projektionsebene stellt die Netzhaut dar. Alles was hinter
(links) der grünen Near clipping Plane und vor (rechts) der roten Far
Clipping Plane liegt, wird durch die Linse auf die Netzhaut übertragen und
wird damit sichtbar, wenn es nicht von einem anderen Objekt verdeckt
wird. Das „viewing frustum“ ist also der Pyramidenstumpf, der sich links
der grünen Ebene bis zur roten Ebene erstreckt.
Far Clipping Plane
Das Perspektive Frustum
Projektionsebene
Bildquelle: SmallCpp, ALGEO, Cassebaum
Das perspektive Frustum in OpenGL ist dem menschlichen Auge sehr ähnlich. Als Projektionsebene dient jedoch nicht die
Netzhaut, sondern ein virtueller Bildschirm im Speicher. Alles was vor dem Bildschirm liegt, soll nicht angezeigt werden und wird
deshalb von der Near Clipping Plane (im oberen Bild grün dargestellt) zum Betrachter hin abgeschnitten. Das gilt für alles was
über, unter, rechts und links des Frustums liegt und auch für alles, was sich hinter der Far-Clipping Plane befindet (Im Bild durch
die rot dargestellt).
Um ein perspektives Frustum in OpenGl zu definieren wählt man zuerst die Projektionsmatrix an, lädt die Einheitsmatrix und
benutzt gluPerspective, um die Sichtpyramide zu definieren.
Beispiel: Das zeichnerische Ergebnis macht sichtbar, dass die hinteren fünf Flächen trotz der zentriert ausgerichteten Lage
sichtbar sind. Die hintere Fläche (in der Grafik das innere Quadrat) des Beispielwürfels ist weiter vom Betrachter entfernt und
erscheint deshalb perspektivisch kleiner als die vorderen Würfelfläche.
//Projektionsmatrix zurücksetzen
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//Perspektivische Darstellung
// (Winkel,Aspekt-Ratio,NearClipping-Abstand,FarClipping-Abstand)
gluPerspective(60.0f,1.0f,1.0f,20.0f);
glMatrixMode(GL_MODELVIEW);
Bildquelle: SmallCpp, ALGEO, Cassebaum
Das Orthogonale Frustum
Ein orthogonales Frustum erzeugt ein ganz anderes Bild unserer Umgebung. Gleich große Objekte werden, wenn sie parallel
liegen auch immer gleich groß angezeigt. Ihre Positionierung im Raum hat auf ihre Größe dagegen keinen Einfluss. Das orthogonale Frustum wird von 6 Würfelseiten (links, rechts, oben, unten, vorne, hinten) eingegrenzt.
Diese Art der Darstellung wird meist verwendet, wenn man Objekte isometrisch oder 2-Dimensional anzeigen möchte. Oder
auch, wenn eine der für CAD Programme typischen Seitenansichten gefragt ist. Um ein solches Frustum in OpenGl einzusetzen,
kann man die Funktionen glOrtho und gluOrtho2D verwenden.
Beispiel: In der Frontansicht sind die Ränder der hinteren Flächen des Würfels bei einer orthogonalen Ausrichtung trotz
transparenter Frontfläche nicht sichtbar, weil sie durch die Ränder Frontfläche genau überdeckt sind. Die Frontfläche erscheint
genau so groß wie die hintere Würfelfläche.
//Projektionsmatrix zurücksetzen
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Orthogonale Darstellung
// (left, right, bottom, top, znear, zfar)
glOrtho(0, 639, 0, 479, 1., 100.);
glMatrixMode(GL_MODELVIEW);
Bildquelle: SmallCpp, ALGEO, Cassebaum
Das orthogonale Frustum ist für 2D-Darstellungen vorgesehen. Im 3D-Modell wirkt die fehlende
Perspektive räumlich verfälschend. Bei Kamerabewegungen wirkt eine Verringerung der Distanz
zur Szene nicht wie im perspektiven Modell vergrößernd oder umgekehrt eine Distanzvergrößerung nicht verkleinernd auf die
Zeichenobjekte.
Thomas Cassebaum
OpenGL mit C++
Seite 5
1.5 Der Befehlsaufbau in OpenGL
Die OpenGL-Befehle verwenden den Präfix gl und große Anfangsbuchstaben.
Ähnlich beginnen OpenGL definierte Konstanten mit GL_, benutzen nur Großbuchstaben.
Manche Befehlen wurden zugehörige Buchstaben und Ziffern hinzugefügt wurden.
z.B. glClearColor()
z.B. GL_COLOR_BUFFER_BIT
z.B.: glColor3f().
Es wurde mehr als einer dieser Befehle definiert, damit verschiedene Argument- bzw. Datentypen benutzt werden können. Der
Farbvektor im Beispielbefehl wird mit drei Komponenten (RGB) vom Typ float definiert. Der Befehl glColor4d() tut fast das
gleiche, benutzt zur Farbwahl aber einen 4-dimensionalen Farbvektor, der mit der vierten (Alpha)-Komponente zur Darstellung
transparenter Bereiche geeignet ist.
Die 3 im Befehl steht dafür, daß drei Argumente übergeben werden; die andere Version des Befehls erwartet vier Argumente.
Das f im Befehl weist darauf hin, daß die Argumente Zahlen vom Typ float sind. Die Buchstaben, die OpenGL-Befehle abschließen, sind in folgender Tabelle dargestellt.
Buchst.
B
S
I
F
D
Ub
Ub
Us
Ui
OpenGL-Datentyp
Bitlg.
GLbyte
GLshort
GLint, GLsizei
GLfloat, GLclampf
GLdouble, GLclampd
GLubyte
GLboolean
GLushort
GLuint, GLenum, GLbitfield
8
16
32
32
64
8
8
16
32
Erklärung
Ganzzahlig mit Vorzeichen (integer)
Ganzzahlig mit Vorzeichen (integer)
Ganzzahlig mit Vorzeichen
Gleitkomma (Reell bis 7 Stellen genau)
Gleitkomma (Reell bis 15 Stellen genau)
Ganzzahlig ohne Vorzeichen
Ganzzahlig ohne Vorzeichen (logisch)
Ganzzahlig ohne Vorzeichen
Ganzzahlig ohne Vorzeichen
entsprechender
C/C++-Typ
signed char
short
int
float
double
unsigned char
bool
unsigned short
unsigned int
Die zwei Befehle glVertex2i(1,2); und glVertex2f(1.0f,2.0f); sind nahezu äquivalent, aber der erste die Eckpunktkoordinaten als 32-Bit Integer spezifiziert, und der zweite sie als Gleitkommazahlen mit einfacher Genauigkeit festlegt. Die
Parameterwerte 1.0f und 2.0f sind C-Literale vom C-Typ float und passen deshalb zum gegebenen Befehl.
Manche OpenGL-Befehle haben einen abschließenden Buchstaben v. Der Befehl benötigt im Argument einen Zeiger auf einen
Vektor (Feld, Array). Viele Befehle haben eine solche Zeiger- wie auch eine Richtzeiger-Version. Die folgenden Zeilen zeigen
Ihnen, wie Sie möglicherweise eine Vektor- und eine Nicht-Vektor Version des Befehls verwenden.
1.6 Farbe, Licht und Oberflächen
RGBA - Farbmodell
Damit die Objekte betrachtet werden können, müssen eine oder besser mehrere Lichtquellen vorhanden sein. Natürliches Licht
ist eine elektromagnetische Welle mit einer Wellenlänge l zwischen 380 nm und 780 nm. Die menschliche Farbwahrnehmung
ordnet den Wellenlängen einen bestimmten Farbeindruck zu. Bestimmte Farben wie Braun kommen in diesem Spektrum nicht
vor. Für die Darstellung der Farben werden mehrere Farbmodelle verwendet. OPENGL arbeitet mit dem (additiven) RGB-Modell,
in dem jede Farbe durch das Mischen
von Rot, Grün und Blau dargestellt
wird. Weiß entspricht dabei dem Tripel
(1, 1, 1) und Schwarz (0, 0, 0).
Die 4. Farbkomponente, der Alpha-Kanal wird zur Angabe der Transparenz
der Farbe benutzt. Ein Alpha-Wert 0
entspricht eine völlig transparenten
(unsichtbare) Farbe, einem Alpha-Wert
von 1 eine undurchsichtige Färbung.
Der Farbvektor ( 0.8, 0.8, 1.0, 0.5 ) erzeugt eine halbdurchsichtige hellblaue
Farbe.
Quelle: Jens-Peer Kuska, Graphik-Programmierung mit OpenGL
Thomas Cassebaum
OpenGL mit C++
Seite 6
Licht
Jede OPENGL-Lichtquelle sendet drei Arten von Licht aus. Ambientes, diffuses und spektakuläres Licht. Die Wirkung der
einzelnen Lichtanteile wird erst deutlich, wenn sie auf eine Oberfläche treffen. Üblich ist, die Intensitäten von diffusen und
spektakulärem Lichtanteil gleich zu wählen und den ambienten Anteil deutlich kleiner anzusetzen.
Ambientes Licht färbt die Körper gleichmäßig ohne jegliche Schattierung. Diffuses Licht hat zwar eine Richtung, wird aber von
der Oberfläche in alle Raumrichtungen gestreut. Spektakuläres (spiegelndes) Licht wird von einer Oberfläche in der Ebene
reflektiert und nur wenn die reflektierte Richtung in die Kamera zeigt, erhöht sich die Lichtintensität.
Für jede einzelne Komponente des Lichts kann eine RGBa-Farbe angegeben werden mit
glLightfv(GL_LIGHT0,GL_AMBIENT,ambient)
für ambientes Licht,
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse)
für diffuses Licht und
glLightfv(GL_LIGHT0,GL_SPECULAR,specular)
für spektakuläres Licht.
Der Standard schreibt mindestens acht Lichter vor, die einzeln mit glEnable( GL_LIGHTi ) eingeschaltet werden müssen. Mit
glLightfv(GL_LIGHT0, GL_POSITION, lpos) wird die Position der Lichtquelle angegeben.
Oberfläche
Die Farbe eine Körpers entsteht durch eine Kombination von Absorption und Reflexion des einfallenden Lichtes. Die Absorption
wird vor allem durch das Material des Körpers bestimmt.
Die Reflexion wird von der Rauigkeit der Oberfläche
beinflußt.
An einer rauen Oberfläche werden die reflektierten
Strahlen eines Bündels aus Lichtstrahlen in alle Raumrichtungen reflektiert. Die Rauigkeit sorgt dafür, dass der
reflektierte Anteil in alle Raumrichtungen gestreut wird.
Lichtbündel bei diffuser (links) und spektakulärer (rechts) Reflexion
Bildquelle: J.-Peer Kuska, Graphik-Programmierung mit OpenGL
Punkte im Raum
Generell werden alle Objekte, die gezeichnet werden können in Paare aus glBegin() und glEnd()
eingeschlossen. Schachteln der Paare ist nicht erlaubt. Es können jedoch die Farbe, Linienattribute,
die Texturkoordinaten und die Oberflächeneigenschaften geändert werden.
Für Punkt-Vertices werden die Vertex-Blöcke mit
glBegin(GL_POINTS); begonnen. Punkte haben
mindestens die Größe eines Pixels. Zwischen diesen
Paaren können mehrere Punkte gesetzt werden. Die
Koordinaten eines Punktes werden als Ortsvektor
mit einer 2-dimensionalen glVertex2f(x,y) oder
einer dreidimensionalen glVertex3f(x,y,z) –
Anweisung übergeben.
Im Bild wurde der Punkt mit glVertex3f(3.0,2.0,4.0); übergeben.
Bildquelle: ALGEO,SmallCpp, Cassebaum
Doppelpufferung
Dieses Prinzip dient dazu das Flackern bewegter Bilder zu vermeiden. Es gibt einen zweiten Bildpuffer der wechselnd vom Programm mit Bildinformation gefüllt wird oder der Hardware zum Lesen und Erzeugen der Bilder störungsfrei überlassen wird. Die
Voreinstellung des einfachen Bildpuffers kann überschrieben werden mit
void glutInitDisplayMode (unsigned int mode);
Für mode kann GLUT_SINGLE oder GLUT_DOUBLE (es gibt noch weitere modes ) eingetragen werden. Das eigentliche Doppelpuffern wird dann durch einen Aufruf von
glutSwapBuffers();
anstelle von glFlush() in display() ausgelöst.
Thomas Cassebaum
OpenGL mit C++
Seite 7
1.7 Erstes OpenGL-Programm mit maximaler Kommentierung (Zeichnen einiger 2D-Linien)
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include <glut.h>
// Header für GLUT
void display()
// Renderfunktion
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Pufferinhalte mit Standardfarbe füllen
glColor3f(1.0f, 0.0f, 0.0f);
// Farbe (hier: rot)
glLineWidth(50.f);
// Strichdicke (hier: 5)
glBegin(GL_LINES);
glVertex2f(-0.5f,-0.5f);
glVertex2f( 0.5f, 0.5f);
glEnd();
// Vertexblock für eine Linie
//
Linienstart (hier: x=-0.5, y=-0.5f)
//
Linienziel (hier: x=+0.5, y=+0.5f)
// Ende des Vertex-Blockes
glColor3f(0.0f, 0.0f, 0.0f);
glLineWidth(1.f);
// Farbe (hier: schwarz)
// Strichdicke (hier: 1)
glBegin(GL_LINES);
glVertex2f(0.0f,-1.0f);
glVertex2f(0.0f, 1.0f);
glVertex2f( 1.0f,0.0f);
glVertex2f(-1.0f,0.0f);
glEnd();
// Vertexblock für zwei schmale Linien
//
1. Linienstart (hier: x=0,
//
1. Linienziel (hier: x=0,
//
2. Linienstart (hier: x=0,
//
2. Linienziel (hier: x=0,
// Ende des Vertex-Blockes
glFlush();
glutSwapBuffers();
// Warten auf das Beenden aller Operationen
// Tauscht Back- und Front-Puffer
y=-1) (senkrechte Linie)
y=1)
y=-1) (waagerechte Linie)
y=1)
}
void justify()
//
{
glClearColor(1.0f,1.0f,0.8f,1.0f); //
glMatrixMode(GL_PROJECTION);
//
glLoadIdentity();
//
glOrtho(-1.0f,1.0f,-1.0f,1.0f,0,0);//
glMatrixMode(GL_MODELVIEW);
//
}
Initialisierungsfunktion
Hintergrundfarben setzen (hier: hellgelb)
Projektionsmatrix einstellen
Einheitsmatrix zum Beginn setzen
Orthogonales Frustum für 2D setzen x:-1...+1, y:-1...+1
Modellmatrix einstellen
int main(int argc, char** argv)
// Hauptfunktion mit Kommandozeilenparametern
{
glutInit(&argc, argv);
// Initialsierung der GLUT-Bibliothek
glutInitDisplayMode( GLUT_DOUBLE | // Doppelter Puffer (unsichtbare Bildaufbauphase)
GLUT_DEPTH | // Tiefenpuffer (z-Puffer) ist für 3D aktiviert
GLUT_RGB);
// Farbpuffer mit Rot, Grün und Blau verwenden
glutInitWindowSize(700, 700);
// Größe des OpenGL-Fensters [in Pixeln]
glutInitWindowPosition(0,0);
// Position der rechten oberen Ecke des OpenGL-Fensters
glutCreateWindow("OpenGL: Ein diagonaler Strich"); // Festlegung Bildschirmtitel
justify();
// Initialisierungsfunktion starten
glutDisplayFunc(display);
glutMainLoop();
return 0;
// Displayfunktionsnamen definieren
// Neustart der OpenGL-Hauptschleife
// Beenden des C++-Programmes, RC = 0
}
Das Ergebnis des dargestellten C++Programmes könnte nach dem Start
der OpenGL-Funktionen etwa so wie
dargestellt aussehen.
Bildquelle: SmallCpp, OpenGL, Cassebaum
Thomas Cassebaum
2. ALGEO
OpenGL mit C++
Seite 8
EINE EINFACHE GRAFIK-API FÜR OPENGL
2.1 Grundidee
ALGEO (Algebra und Geometrie Bibliothek) ist eine Sammlung Grafikfunktionen, die einfache grafische Gestaltungen auf Basis
von OpenGL ermöglichen soll. Das Ziel von ALGEO ist die Erstellung von 3D-Grafiken mit C++ für bildhafte Darstellungen mit geringen Kenntnissen zu den vielfältigen Möglichkeiten von OpenGL.
Als Einstieg in die Arbeit mit ALGEO empfehle ich den Test der Beispiele mit meiner freien C++-IDE SmallCpp ab Version 0.5. Bei
Verwendung einer anderen Entwicklungsumgebung weise ich darauf hin, dass die Beispiele mit dem freien Compiler Borland
Builder C++ Compiler 5.5 sowie mit MINGW übersetzt und getestet wurden.
Die ALGEO-Header „algeo.h“ und „algeoproc.h“, die ALGEO –Anwendungsbeispiele und dieses Skript können gemeinsam mit der
freien IDE SmallCpp unter http://www.t-cassebaum.de/software.htm frei heruntergeladen werden.
In Windows-Systemen steht die Open-Source-Software OpenGL schon nach der Installation des Betriebssystems zur Verfügung.
Viele moderne Grafikkarten unterstützen OpenGL mit hardwarebeschleunigenden Funktionalitäten. Diese Freundlichkeit verdanken wir dem Umstand, dass es sehr viel Anwendungssoftware gibt, die OpenGL zur Grafikdarstellung nutzt (CAD-Programme,
Spiele, Medien, Simulationen, Navigation, Landkarten, Werbung, …).
Wer dennoch Probleme haben sollte, kann sich von vielen Anbietern OpenGL in unterschiedlichen Versionen im Internet frei und
legal herunterladen. Einfach mal googeln. Das Utility Kit GLUT kann man auch gleichzeitig mit SmallCpp automatisch ohne manuelle Einflussnahme installieren lassen.
2.2. Basisfunktionalität von ALGEO
Jedes C++-Programm, das im Standard von ALGEO aufgebaut wurde, besitzt von automatisch bestimmte Basisfunktionalitäten.
So kann mit der Maus, wenn die linke Maustaste gehalten und die Maus dabei bewegt wird, die gesamte gerenderte Szene
gedreht werden. Wird die rechte Maustaste gehalten und die Maus dabei bewegt wird das Objekt näher oder ferner vom
Betrachter gesetzt.
Szenendarstellung
Mit den in Spielen oft genutzten Buchstabentasten „A“, „S“, „D“, „W“ werden Dreh- und mit den Pfeiltasten  Schiebewirkungen der Kamera und damit der Szene ausgelöst.
Die Tasten + und – zoomen das Objekt näher oder ferner zum Betrachter.
Weit im Hintergrund des Zentralpunktes der Szene entsteht durch die der Hintergrundfarbe angepassten Nebelwirkung eine
immer verschwommener werdende Objektdarstellung, die eine optische Darstellung von „Ferne“ verstärken soll. Dieser Effekt
kann mit „F“ ein- oder ausgeschaltet werden.
Mit „T“ werden durch den Alpha-Kanal im RGBA-Farbmodell transparente Darstellungen aktiviert/ deaktiviert.
Mit „U“ wird versucht, den Urzustand der Objektdarstellung unmittelbar nach dem Programmstart wieder herzustellen.
Die Taste (Shift) „V“ bewirkt die Darstellung im Vollbild, die Taste „V“ setzt auch das Vollbild in die Darstellung im WindowsFenster zurück.
Das Koordinatensystem
Die Taste „C“ schaltet das automatisch dargestellte Koordinatensystem aus und auch wieder ein. Mit „P“ wird zwischen der
Ansicht des positiven Quadranten und der aller Quadranten umgeschaltet.
Es gibt je eine quadratische Fläche, die von einer der drei Achsen senkrecht so durchstoßen wird, dass die Fläche den Wert 0 der
Achse trifft. Diese Flächen können einzeln mit den Taste „X“, „Y“, „Z“ un-/ sichtbar gemacht werden.
Mit „L“ kann ein Liniengitter auf den Flächen zur Orientierung de-/aktiviert werden.
Hilfsvariablen und -linien
Mit den Tasten „0“ … „9“ können die Variablen A_0, …, A_9, die im C++-Programm durch den Programmierer zur Beeinflussung
der Szene verwendet werden, um 1 inkrementiert werden. Die gleichen Variablen werden dekrementiert, wenn man die Zifferntaste mit der Shift-Taste gemeinsam drückt.
Die Hilfsvariable A_x kann mit den Tasten „K“ und „G“ kleiner oder größer eingestellt werden.
Eine Hilfsliniendarstellung zu verwendeten Vektoren wird mit „H“ ein-/ausgeschaltet.
Thomas Cassebaum
OpenGL mit C++
Seite 9
2.3 Erstes ALGEO-Programm mit Kommentierung (Zeichnen eines transparenten 3D-Würfels mit Koordinatensystem)
00
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
#include <iostream.h>
// C++ Standardheader
#define A_SPEED .5f
// Bewegungsgeschwindigkeit der ALGEO-Basisfunktionen
#include <algeo.h>
// ALGEO Header
void display()
// Renderfunktion
{ A_Model(A_NIGHT);
// ALGEO FarbModell mit dunkelblauem Hintergrund
A_Coord();
// Koordinatensystem aktivieren
TextAus(vect(-10,4,4),"Perspektiv. Modell",vect(GELB));
// Textausgabeobjekte erzeugen
TextAus(vect(-10,3.5,4),"eines Wuerfels",vect(GELB));
// Wuerfel(Mittelpunkt,Richtung,FlächenFarbe,Linienfarbe,Seitenlänge,Liniendicke)
Wuerfel(vect(ZERO),vect(1,0,0),vect(T_WEISS),vect(GELB),8,2);
// Würfelobjekt erzeugen
}
void justify(){}
// Initialisierungsfunktion
int main(int argc, char** argv)
// Hauptfunktion mit Kommandozeilenparametern
{ glutInit(&argc, argv);
// Initialsierung der GLUT-Bibliothek
A_Init("Perspektiv. Frustum",A_PERSP,6); // Perspektivisches Modell, 6 Achseneinheiten
return 0;
// Beenden des C++-Programmes, RC = 0
}
Das Ergebnis des dargestellten C++-Programmes könnte nach dem Start und
der Nutzung der ALGEO-Funktionen
etwa so wie dargestellt aussehen.
Der Würfel wurde mit der Maus etwas
gedreht und mit dem Aktivieren der yTaste wurde die senkrecht zur y-Achse
stehende Koordinatenebene sichtbar.
Bildquelle: SmallCpp, ALGEO, Cassebaum
Nach den Präprozessoranweisungen (mit # beginnend in den Zeilen 01…03) folgt der wesentlichste Teil von ALGEO, die
Renderfunktion „display()“ in den Zeilen 04…10, die bis zum Programmende in einer Dauerschleife läuft. Im obigen Beispiel
sieht man einen möglichen Inhalt dieser Funktion.
Die Anweisung A_Model(A_NIGHT) aktiviert ein vorgefertigtes Modell, das die Grafik in einer schwarz-blauen Umgebung
zeigt. Alle weiteren Zeilen bauen die grafische Szene aus Raum- und Farb-Vektoren, Texten, Linien und dem fertigen ALGEOKoordinatensystem A_Coord() zusammen. Versuchen Sie auch „A_BOOK“ als Modell.
In den Zeilen 6/7 und 9 werden die ALGEO-Klassen „TextAus“ und „Wuerfel“ zu einem Zeichenobjekten instanziert. TextAus
liefert den Text „Perspektivisches Modell eines Wuerfels“ und Wuerfel zeichnet den in der Szene sichtbaren Würfel. Der
Datentyp vect(…) ist ebenfalls eine ALGEO-Klasse. Er wird für mehrdimensionale Vektoren benötigt, die im Beispiel Orts- und
Farb-vektoren beschreiben.
Ab Zeile 12 wird die ALGEO-Beispielquelle mit der Hauptfunktion main(int argc, char **argv) -Funktion fortgesetzt.
ALGEO basiert neben „OpenGL“ auf „GLUT“, das zur Anwendung mit der passenden Anweisung „glutInit(&argc,argv);“
initialisiert werden muss.
Auch ALGEO selbst benötigt eine Initialisierung, die mit „ A_Init(titel,A_PERSP)“ erledigt wird. Der Parameter A_PERSP
steht für eine perspektivische dreidimensionale Szene. Für eine orthogonale zweidimensionale Szene wird einfach A_ORTH=
eingesetzt. Die Funktion A_Init(Title,ViewMod,AxUnits,AxLine,width,height); initialisiert die ALGEO-Umgebung
mit einem Titel, dem Viewmodus (A_PERSP/A_ORTHO), Anzahl der Achseinheiten, Achsendicke, Bildbreite, Bildhöhe.
Das Schließen des OpenGL-Grafikfensters beendet die Dauerschleife der display()-Funktion und damit auch die meist beachtliche
Leistungsanforderung an den Haupt- und die Grafikprozessoren des Systems.
Thomas Cassebaum
OpenGL mit C++
Seite 10
Aufgaben zu ALGEO
1. Zeichnen Sie ein Bild der linearen Funktion f(x) = ⅓x im Intervall [ -5 ; +5 ] in einem orthogonalen, zweidimensionalen
Koordinatensystem, das für das geforderte Intervall ein Hilfsliniengitter zu den ganzzahligen x- und y-Werten enthält.
2. Zeichnen Sie fünf unterschiedliche Rechtecke mit verschiedenen Größen, Farben und Lagen in einem orthogonalen,
zweidimensionalen Modell ohne sichtbares Koordinatensystem. Die Rechtecke berühren sich nicht. Versuchen Sie die ViewModelle A_BOOK und A_DARK.
3. Zeichnen Sie ein perspektivisches dreidimensionales Modell eines altgriechischen Tempels mit 6 gleich dicken Säulen und
einem passenden Quader als Dach. Färben Sie alle Teilobjekte.
4. Zeichnen Sie eine kugelrunde Wuschelbürste die nur rote und weiße Borsten in gleicher Länge besitzt.
5. Zeichnen Sie einen regelmäßigen Tetraeder, der eine seiner Fläche innerhalb der x-z-Ebene zentriert um den Ursprung
anordnet. Das Objekt zeigt in den positiven y-Bereich und schneidet in der oberen Spitze die y-Achse. Die Seiten sind
halbtransparent und besitzen die Farben rot, grün, gelb und blau.
6. Zeichnen Sie die Olympischen Ringe als 5 ineinander verschlungene flache Disks. Baue die Ringe komplett innerhalb eines
stark transparenten Quaders mittig auf.
7. Zeichnen Sie 2000 gleichseitige Dreiecke mit zufälligen Farben und zufälligen Seitenlängen im Intervall [0.5…2.0]. Alle
Dreiecke befinden sich in dem Würfel zwischen den diagonalen Eckpunkten (5,5,5) und (-5,-5,-5).
8. Stellen Sie eine Ebene mit einer zufälligen Normalen halbtransparent dar und positionieren Sie 1000 Punkte in zufälligen
Farben an zufälligen Orten nur innerhalb der Ebene.
Zwei Lösungen
Aufgabe 1
00
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
#include <iostream.h>
// C++ Standard-Header einfügen
#define A_SPEED 2.f
// Bewegungsgeschwindigkeit der ALGEO-Basisfunktionalität
#include <algeo.h>
// ALGEO-Header einfügen
void display()
// Renderfunktion - läuft als Dauerschleife nach justify()
{ A_Model(A_NIGHT);
// View-Modell einstellen (hier: A_NIGHT, d.h. dunkelblau)
A_Coord(6);
// Koordinatensystem mit 6 Grid-Einheiten aktivieren
TextAus(vect(-10,4),"Aufgabe 1",vect(GELB));
// Zwei Textobjekte instanzieren und zeichnen
TextAus(vect(-10,3.5),"f(x)=1/3x",vect(GELB));
Strecke(vect(-6,-2),vect(12,4),vect(ROT),5);
// Streckenobjekt instanzieren und zeichnen
}
void justify() { A_zPlane = true; }
// Einstellungen vor dem Start der Hauptschleife
int main(int argc, char** argv)
// Hauptfunktion mit Kommandozeilenparametern
{ glutInit(&argc, argv);
// Initialsierung der GLUT-Bibliothek
A_Init("Aufgabe 1",A_ORTHO,7,8);
// Initialisierung der ALGEO-Bibliothek mit Fenstertitel
// orthogonalem Modell, 7 Achseinheiten, Achsdicke 8
return 0; }
// Beenden des C++-Programmes, RC = 0
Aufgabe 2
00
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
#include <iostream.h>
// C++ Standard-Header einfügen
#include <algeo.h>
// ALGEO-Header einfügen
void display()
// Renderfunktion - läuft als Dauerschleife nach justify()
{ A_Model(A_NIGHT);
// View-Modell einstellen (hier: A_NIGHT, d.h. dunkelblau)
TextAus(vect(-10,4),"Aufgabe 2",vect(GELB));
TextAus(vect(-10,3.5),"5 Rechtecke zeichnen",vect(GELB));
Rechteck(vect(-3,-1),vect(-3,0),vect(0,3),vect(WEISS),vect(ROSA),3);
Rechteck(vect(1,4),vect(-4,0),vect(0,3),vect(WEISS),vect(HELLBLAU),3);
Rechteck(vect(2,2),vect(3,0),vect(0,4),vect(WEISS),vect(HELLCYAN),3);
Rechteck(vect(.1,-1),vect(6,0),vect(0,-3),vect(WEISS),vect(HELLGRUEN),3);
Rechteck(vect(-2,3),vect(3,0),vect(0,-2),vect(WEISS),vect(GELB),3);
}
void justify(){ }
// Initialisierungsfunktion
int main(int argc, char** argv)
// Hauptfunktion mit Kommandozeilenparametern
{
glutInit(&argc, argv);
// Initialsierung der GLUT-Bibliothek
A_Init("Aufgabe 2",A_ORTHO,7,8);
return 0; }
// Beenden des C++-Programmes, RC = 0
Thomas Cassebaum
OpenGL mit C++
Seite 11
ANHANG
OpenGL API - Auszug
glBegin
(GLEnum mode)
glClear
(GLbitfield mask)
glClearColor
(Rot,Grün,Blau,Alpha)
glColor[3f,4f,...]
glBegin und glEnd umschließen eine Liste von Eckpunkten (Vertices) die einePrimitive oder Gruppe
von Primitiven darstellt. glBegin erhält ein einzelnes Argument (mode), das angibt, auf welche Art und Weise
die Eckpunkte (Vertices) interpretiert werden.
Leert die im Parameter festgelegten Puffer (Buffer), indem sie mit einen Leerwert gefüllt werden.
z.B. GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, GL_ACCUM_BUFFER_BIT, ...
Legt die Farbe fest welche ein Farbpuffer nach seiner Leerung mit glClear enthält, d.h. die Hintergrundfarbe der
künftigen Szene wird festgelegt.
(Rot,Grün,Blau,Alpha)
Setzt die aktuelle Farbe
z.B. glColor4f(1.0, 0.0, 0.0, 0.5); Setzt auf „Rot, halbtransparent).
glEnd()
↑ glBegin
glFlush()
Erzwingt die Ausführung aller anstehenden OpenGL-Befehle in einem end
glLightfv
Lichteinstellung“GL_LIGHTi“ (I =Lichtnummer)
„mode“ = GL_POSITION, GL_AMBIENT, GL_SPECULAR,
GL_DIFFUSE „par“ – spezifischer Wert zu „mode“ passend
(GL_LIGHT0,mode,par)
glLineWidth
(float width)
Setzt die vertex-spezifische Strichdicke für Primitive auf den Wert „width“ (nur positive Werte erlaubt).
Diese Anweisung ist ausschließlich vor oder in Vertex-Blöcken einsetzbar.
glLoadIdentity()
Ersetzt die aktuelle Matrix durch die Einheitsmatrix (Identitätsmatrix). Meist zur Grundeinstellung der Matrix
am Ende der Renderschleife benutzt.
glMatrixMode
Legt fest, welche Matrix gerade aktiv ist. Nachfolgende Operationen erfolgen im gesetzten mode.
z.B. GL_MODELVIEW, GL_PROJECTION, GL_TEXTURE, GL_COLOR
(GLEnum mode)
glOrtho(left, right,
bottom, top, znear, zfar )
aktiviert einen orthogonalen 2D-Rendermodus. Die 6 Parameter geben den Abstand der Clipping-planes (6
Schnittflächen, die den im Bildschirm sichtbaren Raum begrenzen) vom Ursprung an.
glPointSize(size)
Setzt die vertex-spezifische Punktgröße für Primitive auf den Wert „size“ (nur positive Werte erlaubt).
glVertex[2f,3f,...]
Bestimmt die Koordinaten eines Vertex. Ein Vertex (Mehrzahl: Vertices) ist ein Punkt im Raum.
z.B. glVertex3f(0.0, 0.0, 0.0); Setzt den Vertex in den Ursprung.
(x,y[,z])
gluPerspective
(fovy,aspect,zNear,zFar)
Erstellt eine perspektivische Projektionsmatrix mit dem Winkel in Grad „fovy“, dem Breite/Höhe (aspect-ratio) Verhältnis „aspect“ und den Entfernungen „zNear“ und „zFar“ zu den clipping planes.
GLUT API - Auszug
glutCreateWindow
(char* title)
glutDisplayFunc
(renderfunction)
glutInit
(&argc, argv)
glutInitDisplayMode
( GLUT_DOUBLE|
GLUT_DEPTH|GLUT_RGB)
glutInitWindowPosition
(left, top)
glutInitDisplayMode
(unsigned int mode)
glutInitWindowSize
(width, height)
glutMainLoop()
glutSwapBuffers()
Baut das OpenGL-Fenster mit den voher eingestellten Werten auf. Der Parameter Title liefert den Text zur
Beschriftung der Kopfzeile des OpenGL-Fensters.
Definiert den Namen der Displayfunktion, der im Parameter als Text ohne Anführungsstriche und ohne
Datentyp anzugeben ist. z.B. glutDisplayFunc(display);
Initialisierung der GLUT-Bibliothek, die Bereitstellung der Kommandozeilenparameter aus
main(int argc,char **argv) ist für die Nutzung erforderlich.
Aufbau der Pufferarten, die genutzt werden sollen. Die Angaben mit dem bitweisen ODER „|“ trennen.
GLUT_DOUBLE
Doppelter Puffer: Bildaufbau im BACK-Puffer, die Darstellung aus dem FRONT-Puffer
GLUT_DEPTH
Tiefenpuffer (z-Puffer): Wird für 3D-Räume benötigt.
GLUT_RGB
Farbpuffer mit den Basisfarben Rot, Grün und Blau definieren.
Bestimmt die linke, obere Pixelposition des aufzubauenden OpenGL-Bildschirmfensters. Als Parameter wird
die Pixelposition des linken (left) und die des oberen Randes (top) des OpenGL-Fensters angegeben.
Wird zur Einstellung der Pufferzahl mit mode = GLUT_DOUBLE auf Doppelpufferung eingesetzt. Mit dem
Parameterwert GLUT_SINGLE wird die Arbeit mit einem Einzelpuffer gewählt.
Bestimmt die Größe des aufzubauenden OpenGL-Bildschirmfensters. Als Parameter wird die Breite (width)
und die Höhe (height) in Pixeln angegeben.
Aktiviert den erneuten Beginn der Anweisungen der Hauptschleife zum Rendern der OpenGL-Szene.
Bei Doppelpufferung anstelle von glFlush() in der Renderfunktion display einsetzen.
Thomas Cassebaum
OpenGL mit C++
Seite 12
ALGEO API - Auszug
ALGEO - Klassen
Dreieck [Objekt] (vect
S, D, D2,CB,CF,
float width=1., bool
fill=true, border=true)
Ebene [Objekt](float*
pos, dir1 ,dir2 ,Color )
Kreis [Objekt](vect mp,
normale,color,float
orad=1., irad=0.9 )
Kugel [Objekt] ( vect mp,
color, float radius=1.f )
Ortsvektor [Objekt](vect
pos,color,float width=5.)
Parallelogramm [Objekt]
(vect S, D, D2,CB,CF,
float width=1., bool
fill=true, border=true)
Punkt [Objekt](vect pos,
color, float width=1.f )
Quader[Objekt] (vect S,
D1, D2, D3, CB, CF,
float width=1., bool
fill=true, border=true)
Rechteck [Objekt] (vect
S, D1, D2, CB, CF,
float width=1., bool
fill=true, border=true)
Strecke( vect start,dir,
color, float width=2.f )
StreckeV [Objekt](vect
start,dir,color,float
width=1.,int stip=0)
TextAus [Objekt](pos,
text,col)
vect [Objekt]() oder
(float x,y,z,a)oder
(float* GLvect)
Vektor [Objekt] (vect
start,dest, color, float
width=5.f )
Wuerfel [Objekt](pos,dir,
colf,coll,slen,thickness)
Klasse, die ein Dreieck mit Stützpunkt „S“, in dir Richtungen „D“ und „D2“, den Rand mit der Dicke
„width“ in der Randlinienfarbe „CB“ (nur falls Randfärbung mit „border“=true gesetzt ist) und der
Füllfarbe „CF“ (nur falls Füllung mit „fill“=true gesetzt ist) zeichnet.
Zeichnet ein Ebene mit Linienmuster für den Stützvektor „pos“, die Richtungsvektoren „dir1“ und „dir2“
in der Farbe „Color“. Die Ebene enthält zur besseren Sichtbarkeit ein automatisches Gittermuster.
Klasse, die einen Kreis mit Mittelpunkt „pos“, mit Normalenrichtung „normale“, in der Vektorfarbe
„color“ zeichnet. Der Kreis wird als Disk mit einem äußeren Radius „orad“ ( Standard: 1.0 ) und einem
inneren Radius „irad“ ( Standard: 0.9 ) als Diskscheibenfläche mit Mittelloch gezeichnet.
Klasse, die eine Kugel in 3D mit Mittelpunkt „mp“, in der Vektorfarbe „color“ und dem Radius „radius“
(Standard: 1.) zeichnet.
Klasse, die einen Ortsvektor als „3D-Schlauch“ mit Position bei „pos“, in der Vektorfarbe „color“ und der
Größe „width“ (Standard: 5.) zeichnet.
Klasse, die ein Parallelogramm mit Stützpunkt „S“, in dir Richtungen „D“ und „D2“, den Rand mit der
Dicke „width“ in der Randlinienfarbe „CB“ (nur falls Randfärbung mit „border“=true gesetzt ist) und der
Füllfarbe „CF“ (nur falls Füllung mit „fill“=true gesetzt ist) zeichnet.
Klasse, die einen Punkt mit Position bei Ortsvektor „pos“, in der Vektorfarbe „color“ und der Größe
„width“ (Standard: 1.) zeichnet.
Klasse, die einen Quader mit Stützpunkt „S“, in die Richtungen „D1“ ,„D2“ und„D3“, den Rand mit der
Dicke „width“ in der Randlinienfarbe „CB“ (nur falls Randfärbung mit „border“=true gesetzt ist) und der
Füllfarbe „CF“ (nur falls Füllung mit „fill“=true gesetzt ist) zeichnet.
Klasse, die ein Rechteck mit Stützpunkt „S“, in die Richtungen „D1“ und „D2“, den Rand mit der Dicke
„width“ in der Randlinienfarbe „CB“ (nur falls Randfärbung mit „border“=true gesetzt ist) und der
Füllfarbe „CF“ (nur falls Füllung mit „fill“=true gesetzt ist) zeichnet.
Klasse, die eine Strecke als „3D-Schlauch“ mit Start bei Ortsvektor „start“, in Richtung und Länge des
Vektors „dir“, mit der Vektorfarbe „color“ und der Dicke „width“ (Standard: 2) zeichnet.
Klasse, die eine Strecke als „Vertex-line“ mit Start bei Ortsvektor „start“, in Richtung und Länge des
Vektors „dir“, mit der Vektorfarbe „color“ und der Dicke „width“ (Standard: 2) zeichnet. Der „stip“Parameter sorgt für verschiedene Arten einer Strichelung bei stip = 1…5.
Klasse, die den Text „text“ an der Ortsvektorposition „pos“ in der Vektorfarbe „col“ erzeugt und
zeichnet. Ein Objektname kann vergeben werden, muss aber nicht.
Klasse, die einen vierdimensionalen Vektor speichert. Sollten nur 1…3 Parameter angegeben sein, so
werden die fehlenden auf den Wert „0“ gesetzt. In der Klammer kann auch der Name eines in OpenGL
übliches mehrdimensionales (bis 4) Feld für Punkt- oder Farb-definitionen angegeben werden. Es sind
eine Reihe von Vektoroperationen möglich: + Addition, - Subtraktion, * Skalarprodukt und
Skalarmultiplikation, % Vektorprodukt, = Ergibtanweisung, = und != für Vergleiche,
Methoden: int length() errechnet den Betrag, char* vectstr() liefert einen char*-String im Stil (x|y|z|a),
float* GLvect() liefert ein 4D-OpenGL-Feld mit den Vektorwerten, float x() liefert den x-Wert, …usw.
Klasse, die einen Vektor als „3D-Schlauch“ mit Stützposition bei „start“, in Richtung „dest“ in der
Vektorfarbe „color“ und der Dicke „width“ (Standard: 5.) zeichnet.
Klasse, die einen Würfel in 3D mit Mittelpunkt bei Ortsvektor „pos“, in Richtung des Vektors „dir“, mit
der Flächen-Vektorfarbe „colf“, der Linien-Vektorfarbe „coll“, der Seitenlänge „slen“ und der Strichdicke
„thickness“ erzeugt und zeichnet. Es gibt die Methode „zeichne()“, die den Würfel erneut zeichnen kann.
ALGEO Funktionen
A_AngToCart
(float theta, psi)
A_Coord()
A_Init
(title, frustum,
units, thickness,
width, height)
A_Model(model);
void justify(){
}
Liefert für eine Richtung durch zwei Winkel ausgedrückt, den passenden kartesischen 3D-vektor als
float-Array zurück.
Zeigt ein kartesisches 2D- oder 3D-Koordinatensystem an, das mit den ALGEO-Basisfunktionen arbeitet.
Initialisiert die ALGEO-Umgebung. Muss nach der GLUT-Initialisierung in main() gerufen werden. Der
Parameter „title“ legt den Fenstertitel fest, „frustum“ das Modell A_PERSP oder A_ORTHO, „units“
bestimmt die Anzahl der positiven Einheiten auf den Koordinatenachsen und „thickness“ legt die Stärke
der Koordinatenachsen fest. Das Fenster wird auf die Pixelgröße width x height gesetzt.
Setzt die ALGEO-Grafik auf eines der Modelle „A_BOOK“, „A_DARK“ oder „A_NIGHT“.
Diese parameterlose Funktion muss in jeder ALGEO-Anwendung definiert werden. Es ist die
Initialisierungsfunktion für Statusvariablen, die vor dem Start der Renderschleife gesetzt werden sollen.
Thomas Cassebaum
OpenGL mit C++
Seite 13
ALGEO - Statusvariablen
bool A_Csyst=true
Koordinatensystem E(true)/A(false)
Koordinatenachsenrotation 0 – z vorn, 1 – x vorn, 2 – y vorn
Vollbildmodus E(true)/A(false)
Lichtpositionen der vier Lichter (Standard: LightPos0)
unsigned short A_Rotor=0;
bool A_full=true;
GLfloat lightPos0[4]
= LightPos0;
GLfloat A_CoordColor[4]
GLfloat A_CoordColor1[4]
GLfloat A_CoordColor2[4]
= A_KOORDWHITE
= A_KOORDBLUE
= A_KOORDGRAY
GLfloat A_GridNIGHT[4]
= A_T_WHITE
GLfloat A_GridDARK[4]
= A_T_WHITE
GLfloat A_GridBOOK[4]
= A_T_BLACK
int A_0=A_1=A_2=A_3=A_4=A_5=A_6=A_7=A_8=A_9=1
float A_distance = 1.f
bool
A_extmode = false
bool
A_Foggy = true
bool
A_HelpLines=false
float A_sx = A_sy = A_sz = 0.f
float A_phi=0.f;
float A_theta=0.f;
bool
A_Gatt=true
bool
A_Positiv=false
float A_turn[3]={0.f,1.f,0.f}
float A_x=1.f
bool
A_xPlane=A_yPlane=A_zPlane=false
Koordinatenfarben (Standard; Weiss, Blau, Grau)
Gitterfarben der Koordinatenflächen für die Modelle
Ganzzahlige Variablen !_i für Benutzersteuerung mit Tasten ‚i‘ | ‚Strg/i‘
Distanz der Kamera zum Ursprung (Standard: 1)
Extended Mode der Benutzeranwendung [Taste ‚E‘: E(true)/A(false) ]
Nebel E(true)/A(false) (Standard: true)
Hilfslinien (nur für ALGEO-Vektoren) : E(true)/A(false) (Standard:false)
Kameraverschiebung in Achsenrichtung (Standard: alle 0)
Kamera-Rotation um die y-Achse (5° entspricht der Angabe 5./180.*M_PI)
Kamera-Rotation um die x-Achse (5° entspricht der Angabe 5./180.*M_PI)
Koordinatenflächen-Gitterlinien E(true)/A(false) (Standard:true)
Nur Positiven Quadranten zeigen E(true)/A(false) (Standard:false)
Vektor zur Rotation mit der Fkt. A_Turn() der Achsen in Uhrzeigerrichtung
Relle Benutzervariable [Steuerung mit Tasten ‚K‘ (kleiner) und ‚G‘ (größer)]
A_iPlane – Fläche, die durch die i-Achse durchstoßen wird E(true)/A(false)
ALGEO - vordefinierte Farben und Positionen
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
ZERO
UNIT_X
UNIT_Y
UNIT_Z
UNIT_XY
UNIT_XZ
UNIT_YZ
UNIT_XYZ
UNIT_X_M
UNIT_Y_M
UNIT_Z_M
UNIT_XY_M
UNIT_XZ_M
UNIT_YZ_M
UNIT_XYZ_M
#define TRANSP
#define URSPRUNG
0.f, 0.f, 0.f
1.f, 0.f, 0.f
0.f, 1.f, 0.f
0.f, 0.f, 1.f
1.f, 1.f, 0.f
1.f, 0.f, 1.f
0.f, 1.f, 1.f
1.f, 1.f, 1.f
-1.f, 0.f, 0.f
0.f,-1.f, 0.f
0.f, 0.f,-1.f
-1.f,-1.f, 0.f
-1.f, 0.f,-1.f
0.f,-1.f,-1.f
-1.f,-1.f,-1.f
0.f,0.f,0.f,.0f
0.f,0.f,0.f,.0f
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
WEISS
1.f, 1.f, 1.f, 1.f
BLAU
0.f, 0.f, 1.f, 1.f
ROT
1.f, 0.f, 0.f, 1.f
GRUEN
0.f, 1.f, 0.f, 1.f
GELB
1.f, 1.f, 0.f, 1.f
CYAN
0.f, 1.f, 1.f, 1.f
MAGENTA
1.f, 0.f, 1.f, 1.f
SCHWARZ
0.f, 0.f, 0.f, 1.f
GRAU
.5f, .5f, .5f, 1.f
HELLGRAU
.6f, .6f, .6f, 1.f
HELLBLAU
.3f, .3f, 1.f, 1.f
HELLROT
1.f, .3f, .3f, 1.f
ROSA
1.f, .3f, .3f, 1.f
HELLGRUEN .3f, 1.0f,.3f, 1.f
HELLGELB
1.f, 1.f, .3f, 1.f
HELLCYAN
.3f, 1.f, 1.f, 1.f
HELLMAGENTA 1.f,.3f, 1.f, 1.f
DUNKELGRAU .3f, .3f, .3f, 1.f
DUNKELBLAU 0.f, 0.f, .5f, 1.f
DUNKELROT .5f, 0.f, 0.f, 1.f
DUNKELGRUEN 0.f,.5f, 0.f, 1.f
DUNKELGELB .5f, .5f, 0.f, 1.f
DUNKELCYAN 0.f, .5f, .5f, 1.f
DUNKELMAGENTA .5f,0.f,.5f,1.f
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
#define
T_GLASS
1.f, 1.f, 1.f, .33f
T_WEISS
1.f, 1.f, 1.f, .33f
T_BLAU
0.f, 0.f, 1.f, .33f
T_ROT
1.f, 0.f, 0.f, .33f
T_GRUEN
0.f, 1.f, 0.f, .33f
T_GELB
1.f, 1.f, 0.f, .33f
T_CYAN
0.f, 1.f, 1.f, .33f
T_MAGENTA 1.f, 0.f, 1.f, .33f
T_SCHWARZ 0.f, 0.f, 0.f, .33f
T_GRAU
.5f, .5f, .5f, .33f
T_HELLGRAU .6f, .6f, .6f, .5f
T_HELLBLAU .3f, .3f, 1.f, .5f
T_HELLROT 1.f, .3f, .3f, .5f
T_ROSA
1.f, .3f, .3f, .5f
T_HELLGRUEN .3f,1.0f,.3f, .5f
T_HELLGELB 1.f, 1.f, .3f, .5f
T_HELLCYAN .3f, 1.f, 1.f, .5f
T_HELLMAGENTA 1.f,.3f,1.f,.5f
T_DUNKELGRAU .3f,.3f,.3f,.33f
T_DUNKELBLAU 0.f,0.f,.5f,.33f
T_DUNKELROT .5f,0.f,0.f,.33f
T_DUNKELGRUEN 0.f,.5f,0.,.33f
T_DUNKELGELB .5f,.5f,0.f,.33f
T_DUNKELCYAN 0.f,.5f,.5f,.33f
T_DUNKELMAGENTA .5,0.,.5,.33f
Thomas Cassebaum
OpenGL mit C++
Seite 14
Glossar zu 3D-Begriffen
Alpha Blending: Das Alpha Blending kennzeichnet die Auswertung des Alpha Wertes (auch: Alpha Kanal) zur Bestimmung der
Transparenz eines Objektes. Der Alpha Wert kann als zusätzliche Farbinformation in einem 32 Bit RGBA Format (Rot, Grün, Blau,
Alpha) angegeben werden.
Anisotrope Texturfilterung: Verbessert die Darstellung von Texturen bei der Betrachtung unter einem flachen Winkel.
Antialiasing: Künstlich erzeugt Unschärfe durch farblich veränderte Nachbarpixel. Vermeidet den Treppeneffekt beim Zeichnen
von Linien.
API: Application Programming Interface. Eine Schnittstelle, die dem Programmierer Funktionen der Hardware oder des Betriebssystems zugänglich macht.
Backface Culling: Es werden nur die Flächen gezeichnet, deren Normalenvektoren zum Betrachter hin weisen. Durch diese Technik läßt der Rechenaufwand für eine Szene erheblich verringern.
Bilineare Filter: Eine speziell bei Texturen verwendete Form des Antialiasings, die auf jeweils 2x2 Texel (Texture Element) beschränkt ist. Aus den Farbwerten dieser Texel wird der gemeinsame Mittelwert gebildet. Dadurch erhält man einen weichen
Farbverlauf und vermeidet grobe Pixel beim Heranzoomen.
Color Key Transparenz: Eine durch den Color Key gekennzeichnete Farbe ist vollkommen transparent. Diese Technik ermöglicht
zum Beispiel die Darstellung einer lichten Baumkrone durch eine einzige Textur, in dem die Freiräume zwischen den Blättern
durch die Color Key Farbe gekennzeichnet werden.
Flat Shading: Die Farbe einer Polygonfläche entspricht der Farbzuweisung des ersten Eckpunktes.
Fogging: Simuliert Nebel und Raumtiefe durch Überlagerung des Bildes mit einer zusätzlichen Farbe.
Gouraud Shading (Smooth Shading): Der Farbverlauf über eine Polygonfläche wird durch eine Interpolation über die Farbwerte
aller Eckpunkte bestimmt.
MIP Mapping: Für eine vorgegebene Textur werden verschiedene Auflösungen berechnet und gespeichert. In Abhängigkeit von
der jeweiligen Entfernung zum Objekt wird automatisch eine ausreichend präzise Auflösung gewählt.
Phong Shading: Bei diesem Verfahren werden die Normalenvektoren der Eckpunkte über die Polygonfläche interpoliert und
dann die aus dem Beleuchtungsmodell resultierenden Farbwerte für jeden Pixel separat berechnet. Dieses Verfahren ist für eine
Berechnung in Echtzeit nicht geeignet.
Trilineares MIP Mapping: Kennzeichnet eine Funktion, die innerhalb von Texturen mit bilinearer Filterung arbeitet und
außerdem noch die Mittelwerte aus aufeinanderfolgenden Texturstufen bildet.
RGB-Farbtabelle mit Werten für ALGEO-Farbvektoren
Noch besser ist diese Farbübersicht zu Farbcodes: http://www.farb-tabelle.de/de/farbtabelle.htm
Thomas Cassebaum
OpenGL mit C++
Seite 15
Einige Links zum Thema:














http://www.t-cassebaum.de
Meine private Homepage
http://www.opengl.org/
Die OpenGL-Seite, alles was man braucht
http://www.codegear.com/downloads/free/cppbuilder
Borland-Downloadseite, mit bcc55 (freier Borland C++ Compiler 5.5)
http://www.inf.tu-dresden.de/content/institutes/smt/cg/teaching/labcourses/PraktikumComputergraphik06/
public/OpenGL/Lehrheft%20OpenGL.pdf
Gutes kostenloses Lehrheft in deutscher Sprache zu OpenGl, von Stefan Rippert und Tobias Pietzsch, 2003 herausgegeben
an der TU Dresden von K.Hoedt und W.Mascolus
http://nehe.gamedev.net/
„Nehe“-Seite (englisch)
http://www.joachimrohde.com/cms/xoops/modules/articles/index.php?cat_id=1
Beispielsammlung als deutsches Tutorial zu OpenGl, übersetzt von Joachim Rohde von der „Nehe-Seite“
http://www.xmission.com/~nate/glut.html
Seite von Nate Robins mit GLUT for Win32
http://phong.informatik.uni-leipzig.de/~kuska/oglscript/openglsc.pdf
OpenGl Tutorial Peter Kuska Dresden
http://www.it.hs-esslingen.de/~schmidt/vorlesungen/vr/seminar/ws9899/virtuellerealitaet.htm
OpenGl-Tutorial deutsch!!!
http://www.gamedev.net/reference/articles/article1698.asp
Abrash-Tutorial (Michael Abrash, Graphics Preogramming Black Book)
http://www.povray.org
Das legendäre povray-Grafiksystem
http://www.grafikprogrammierung.de/
Lehrbuch der Grafikprogrammierung
http://www.irrlicht3d.de
Irrlicht - Deutschsprachiges Portal
http://www.farb-tabelle.de/de/farbtabelle.htm
Farbtabellen und Codes in verschiedenen Farbtabellen
Literaturquellen
[1]
Marius Apetri, 3D-Grafik Programmierung
mitp-Verlag, 2. Auflage, Heidelberg 2008
ISBN 978-3-8266-1767-6
[2]
Ulla Kirch-Prinz, Peter Prinz, C++ Lernen und professionell anwenden
mitp-Verlag, 3. Auflage, Bonn 2005
[3]
Charles Petzold, Windows Programmierung,
Das Entwicklerhandbuch zur Win32-API
Microsoft Press, 5th.edition, 2000
ISBN-10: 3-86063-188-8
ISBN-13: 978-3-86063-188-1
[4]
Jens-Peer Kuska, Graphik-Programmierung mit OPENGL
2000
Internet
[5]
W. P. Kowlak, Spieleentwicklung mit OpenGL uns Java oder „JOGLn in Java“
Universität Oldenburg, 2005
ISBN 3-8266-1534-4