OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum...

15
Thomas Cassebaum OpenGl mit C++ Kursskript 2012

Transcript of OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum...

Page 1: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

Thomas Cassebaum

OpenGl mit C++

Kursskript 2012

Page 2: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

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

Page 3: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

Thomas Cassebaum OpenGL mit C++ Seite 3

1. OPENGL EINE FREIE GRAFIKBIBLIOTHEK

1.1 Einleitung

OpenGL ist eine plattformunabhängige Grafikbibliothek, die inzwischen zu einem weltweiten Standard für 3D-Grafikprogram-mierung 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 unter-stü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ächenmate-rial, 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 Fen-stern 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.

Page 4: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

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 Pro-jektionsebene ist das das 2D-Bild des Frustums. Das menschliche Auge ü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.

Das Perspektive Frustum

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 orthogo-nale 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.); Bildquelle: SmallCpp, ALGEO, Cassebaum glMatrixMode(GL_MODELVIEW); 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.

Bildquelle: SmallCpp, ALGEO, Cassebaum

Far Clipping Plane

Near Clipping Plane

Projektionsebene

Page 5: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

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. z.B. glClearColor() Ähnlich beginnen OpenGL definierte Konstanten mit GL_, benutzen nur Großbuchstaben. z.B. GL_COLOR_BUFFER_BIT Manche Befehlen wurden zugehörige Buchstaben und Ziffern hinzugefügt wurden. 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. OpenGL-Datentyp Bitlg. Erklärung entsprechender C/C++-Typ

B GLbyte 8 Ganzzahlig mit Vorzeichen (integer) signed char

S GLshort 16 Ganzzahlig mit Vorzeichen (integer) short

I GLint, GLsizei 32 Ganzzahlig mit Vorzeichen int

F GLfloat, GLclampf 32 Gleitkomma (Reell bis 7 Stellen genau) float

D GLdouble, GLclampd 64 Gleitkomma (Reell bis 15 Stellen genau) double

Ub GLubyte 8 Ganzzahlig ohne Vorzeichen unsigned char

Ub GLboolean 8 Ganzzahlig ohne Vorzeichen (logisch) bool

Us GLushort 16 Ganzzahlig ohne Vorzeichen unsigned short

Ui GLuint, GLenum, GLbitfield 32 Ganzzahlig ohne Vorzeichen unsigned int

Die zwei Befehle glVertex2i(1,2); und glVertex2f(1.0f,2.0f); sind nahezu äquivalent, aber der erste die Eck-punktkoordinaten 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-Ka-nal 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 ) er-zeugt eine halbdurchsichtige hellblaue Farbe.

Quelle: Jens-Peer Kuska, Graphik-Programmierung mit OpenGL

Page 6: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

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 Raum-richtungen 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 wer-den können in Paare aus glBegin() und glEnd() eingeschlossen. Schachteln der Paare ist nicht er-laubt. Es können jedoch die Farbe, Linienattribute, die Texturkoordinaten und die Oberflächeneigen-schaften 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 Pro-gramm 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 Dop-pelpuffern wird dann durch einen Aufruf von

glutSwapBuffers(); anstelle von glFlush() in display() ausgelöst.

Page 7: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

Thomas Cassebaum OpenGL mit C++ Seite 7

1.7 Erstes OpenGL-Programm mit maximaler Kommentierung (Zeichnen einiger 2D-Linien)

01 #include <glut.h> // Header für GLUT 02 03 void display() // Renderfunktion 04 { 05 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Pufferinhalte mit Standardfarbe füllen 06 glColor3f(1.0f, 0.0f, 0.0f); // Farbe (hier: rot) 07 glLineWidth(50.f); // Strichdicke (hier: 5) 08 09 glBegin(GL_LINES); // Vertexblock für eine Linie 10 glVertex2f(-0.5f,-0.5f); // Linienstart (hier: x=-0.5, y=-0.5f) 11 glVertex2f( 0.5f, 0.5f); // Linienziel (hier: x=+0.5, y=+0.5f) 12 glEnd(); // Ende des Vertex-Blockes 13 14 glColor3f(0.0f, 0.0f, 0.0f); // Farbe (hier: schwarz) 15 glLineWidth(1.f); // Strichdicke (hier: 1) 16 17 glBegin(GL_LINES); // Vertexblock für zwei schmale Linien 18 glVertex2f(0.0f,-1.0f); // 1. Linienstart (hier: x=0, y=-1) (senkrechte Linie) 19 glVertex2f(0.0f, 1.0f); // 1. Linienziel (hier: x=0, y=1) 20 glVertex2f( 1.0f,0.0f); // 2. Linienstart (hier: x=0, y=-1) (waagerechte Linie) 21 glVertex2f(-1.0f,0.0f); // 2. Linienziel (hier: x=0, y=1) 22 glEnd(); // Ende des Vertex-Blockes 23 24 glFlush(); // Warten auf das Beenden aller Operationen 25 glutSwapBuffers(); // Tauscht Back- und Front-Puffer 26 } 27 28 void justify() // Initialisierungsfunktion 29 { 30 glClearColor(1.0f,1.0f,0.8f,1.0f); // Hintergrundfarben setzen (hier: hellgelb) 31 glMatrixMode(GL_PROJECTION); // Projektionsmatrix einstellen 32 glLoadIdentity(); // Einheitsmatrix zum Beginn setzen 33 glOrtho(-1.0f,1.0f,-1.0f,1.0f,0,0);// Orthogonales Frustum für 2D setzen x:-1...+1, y:-1...+1 34 glMatrixMode(GL_MODELVIEW); // Modellmatrix einstellen 35 } 36 37 int main(int argc, char** argv) // Hauptfunktion mit Kommandozeilenparametern 38 { 39 glutInit(&argc, argv); // Initialsierung der GLUT-Bibliothek 40 glutInitDisplayMode( GLUT_DOUBLE | // Doppelter Puffer (unsichtbare Bildaufbauphase) 41 GLUT_DEPTH | // Tiefenpuffer (z-Puffer) ist für 3D aktiviert 42 GLUT_RGB); // Farbpuffer mit Rot, Grün und Blau verwenden 43 glutInitWindowSize(700, 700); // Größe des OpenGL-Fensters [in Pixeln] 44 glutInitWindowPosition(0,0); // Position der rechten oberen Ecke des OpenGL-Fensters 45 glutCreateWindow("OpenGL: Ein diagonaler Strich"); // Festlegung Bildschirmtitel 46 47 justify(); // Initialisierungsfunktion starten 48 49 glutDisplayFunc(display); // Displayfunktionsnamen definieren 50 glutMainLoop(); // Neustart der OpenGL-Hauptschleife 51 return 0; // Beenden des C++-Programmes, RC = 0 52 }

Bildquelle: SmallCpp, OpenGL, Cassebaum

Das Ergebnis des dargestellten C++-

Programmes könnte nach dem Start

der OpenGL-Funktionen etwa so wie

dargestellt aussehen.

Page 8: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

Thomas Cassebaum OpenGL mit C++ Seite 8

2. ALGEO 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 ge-ringen 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 ver-danken 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 manu-elle 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 Schie-bewirkungen 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 Windows-Fenster 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 Ziffern-taste 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.

Page 9: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

Thomas Cassebaum OpenGL mit C++ Seite 9

2.3 Erstes ALGEO-Programm mit Kommentierung (Zeichnen eines transparenten 3D-Würfels mit Koordinatensystem)

00 #include <iostream.h> // C++ Standardheader 01 #define A_SPEED .5f // Bewegungsgeschwindigkeit der ALGEO-Basisfunktionen 02 #include <algeo.h> // ALGEO Header 03 void display() // Renderfunktion 04 { A_Model(A_NIGHT); // ALGEO FarbModell mit dunkelblauem Hintergrund 05 A_Coord(); // Koordinatensystem aktivieren 06 TextAus(vect(-10,4,4),"Perspektiv. Modell",vect(GELB)); // Textausgabeobjekte erzeugen 07 TextAus(vect(-10,3.5,4),"eines Wuerfels",vect(GELB)); 08 // Wuerfel(Mittelpunkt,Richtung,FlächenFarbe,Linienfarbe,Seitenlänge,Liniendicke) 09 Wuerfel(vect(ZERO),vect(1,0,0),vect(T_WEISS),vect(GELB),8,2); // Würfelobjekt erzeugen 10 } 11 void justify(){} // Initialisierungsfunktion 12 int main(int argc, char** argv) // Hauptfunktion mit Kommandozeilenparametern 13 { glutInit(&argc, argv); // Initialsierung der GLUT-Bibliothek 14 A_Init("Perspektiv. Frustum",A_PERSP,6); // Perspektivisches Modell, 6 Achseneinheiten 15 return 0; // Beenden des C++-Programmes, RC = 0 16 }

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 ALGEO-Koordinatensystem 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.

Das Ergebnis des dargestellten C++-Pro-grammes 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 y-Taste wurde die senkrecht zur y-Achse stehende Koordinatenebene sichtbar.

Page 10: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

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 View-Modelle 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 #include <iostream.h> // C++ Standard-Header einfügen 01 #define A_SPEED 2.f // Bewegungsgeschwindigkeit der ALGEO-Basisfunktionalität 02 #include <algeo.h> // ALGEO-Header einfügen 03 void display() // Renderfunktion - läuft als Dauerschleife nach justify() 04 { A_Model(A_NIGHT); // View-Modell einstellen (hier: A_NIGHT, d.h. dunkelblau) 05 A_Coord(6); // Koordinatensystem mit 6 Grid-Einheiten aktivieren 06 TextAus(vect(-10,4),"Aufgabe 1",vect(GELB)); // Zwei Textobjekte instanzieren und zeichnen 07 TextAus(vect(-10,3.5),"f(x)=1/3x",vect(GELB)); 08 Strecke(vect(-6,-2),vect(12,4),vect(ROT),5); // Streckenobjekt instanzieren und zeichnen 09 } 10 void justify() { A_zPlane = true; } // Einstellungen vor dem Start der Hauptschleife 11 int main(int argc, char** argv) // Hauptfunktion mit Kommandozeilenparametern 12 { glutInit(&argc, argv); // Initialsierung der GLUT-Bibliothek 13 A_Init("Aufgabe 1",A_ORTHO,7,8); // Initialisierung der ALGEO-Bibliothek mit Fenstertitel 14 // orthogonalem Modell, 7 Achseinheiten, Achsdicke 8 15 return 0; } // Beenden des C++-Programmes, RC = 0

Aufgabe 2

00 #include <iostream.h> // C++ Standard-Header einfügen 02 #include <algeo.h> // ALGEO-Header einfügen 03 void display() // Renderfunktion - läuft als Dauerschleife nach justify() 04 { A_Model(A_NIGHT); // View-Modell einstellen (hier: A_NIGHT, d.h. dunkelblau) 05 TextAus(vect(-10,4),"Aufgabe 2",vect(GELB)); 06 TextAus(vect(-10,3.5),"5 Rechtecke zeichnen",vect(GELB)); 07 Rechteck(vect(-3,-1),vect(-3,0),vect(0,3),vect(WEISS),vect(ROSA),3); 08 Rechteck(vect(1,4),vect(-4,0),vect(0,3),vect(WEISS),vect(HELLBLAU),3); 09 Rechteck(vect(2,2),vect(3,0),vect(0,4),vect(WEISS),vect(HELLCYAN),3); 10 Rechteck(vect(.1,-1),vect(6,0),vect(0,-3),vect(WEISS),vect(HELLGRUEN),3); 11 Rechteck(vect(-2,3),vect(3,0),vect(0,-2),vect(WEISS),vect(GELB),3); 12 } 13 void justify(){ } // Initialisierungsfunktion 14 int main(int argc, char** argv) // Hauptfunktion mit Kommandozeilenparametern 15 { glutInit(&argc, argv); // Initialsierung der GLUT-Bibliothek 16 A_Init("Aufgabe 2",A_ORTHO,7,8); 17 return 0; } // Beenden des C++-Programmes, RC = 0

Page 11: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

Thomas Cassebaum OpenGL mit C++ Seite 11

ANHANG

OpenGL API - Auszug

glBegin

(GLEnum mode)

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.

glClear (GLbitfield mask)

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, ...

glClearColor (Rot,Grün,Blau,Alpha)

Legt die Farbe fest welche ein Farbpuffer nach seiner Leerung mit glClear enthält, d.h. die Hintergrundfarbe der künftigen Szene wird festgelegt.

glColor[3f,4f,...] (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 (GL_LIGHT0,mode,par)

Lichteinstellung“GL_LIGHTi“ (I =Lichtnummer) „mode“ = GL_POSITION, GL_AMBIENT, GL_SPECULAR, GL_DIFFUSE „par“ – spezifischer Wert zu „mode“ passend

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

(GLEnum mode)

Legt fest, welche Matrix gerade aktiv ist. Nachfolgende Operationen erfolgen im gesetzten mode. z.B. GL_MODELVIEW, GL_PROJECTION, GL_TEXTURE, GL_COLOR

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,...] (x,y[,z])

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.

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)

Baut das OpenGL-Fenster mit den voher eingestellten Werten auf. Der Parameter Title liefert den Text zur Beschriftung der Kopfzeile des OpenGL-Fensters.

glutDisplayFunc (renderfunction)

Definiert den Namen der Displayfunktion, der im Parameter als Text ohne Anführungsstriche und ohne Datentyp anzugeben ist. z.B. glutDisplayFunc(display);

glutInit (&argc, argv)

Initialisierung der GLUT-Bibliothek, die Bereitstellung der Kommandozeilenparameter aus main(int argc,char **argv) ist für die Nutzung erforderlich.

glutInitDisplayMode ( GLUT_DOUBLE| GLUT_DEPTH|GLUT_RGB)

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.

glutInitWindowPosition (left, top)

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.

glutInitDisplayMode (unsigned int mode)

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.

glutInitWindowSize (width, height)

Bestimmt die Größe des aufzubauenden OpenGL-Bildschirmfensters. Als Parameter wird die Breite (width) und die Höhe (height) in Pixeln angegeben.

glutMainLoop() Aktiviert den erneuten Beginn der Anweisungen der Hauptschleife zum Rendern der OpenGL-Szene.

glutSwapBuffers() Bei Doppelpufferung anstelle von glFlush() in der Renderfunktion display einsetzen.

Page 12: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

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)

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.

Ebene [Objekt](float* pos, dir1 ,dir2 ,Color )

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.

Kreis [Objekt](vect mp, normale,color,float orad=1., irad=0.9 )

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.

Kugel [Objekt] ( vect mp, color, float radius=1.f )

Klasse, die eine Kugel in 3D mit Mittelpunkt „mp“, in der Vektorfarbe „color“ und dem Radius „radius“ (Standard: 1.) zeichnet.

Ortsvektor [Objekt](vect pos,color,float width=5.)

Klasse, die einen Ortsvektor als „3D-Schlauch“ mit Position bei „pos“, in der Vektorfarbe „color“ und der Größe „width“ (Standard: 5.) zeichnet.

Parallelogramm [Objekt] (vect S, D, D2,CB,CF, float width=1., bool fill=true, border=true)

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.

Punkt [Objekt](vect pos, color, float width=1.f )

Klasse, die einen Punkt mit Position bei Ortsvektor „pos“, in der Vektorfarbe „color“ und der Größe „width“ (Standard: 1.) zeichnet.

Quader[Objekt] (vect S, D1, D2, D3, CB, CF, float width=1., bool fill=true, border=true)

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.

Rechteck [Objekt] (vect S, D1, D2, CB, CF, float width=1., bool fill=true, border=true)

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.

Strecke( vect start,dir, color, float width=2.f )

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.

StreckeV [Objekt](vect start,dir,color,float width=1.,int stip=0)

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.

TextAus [Objekt](pos, text,col)

Klasse, die den Text „text“ an der Ortsvektorposition „pos“ in der Vektorfarbe „col“ erzeugt und zeichnet. Ein Objektname kann vergeben werden, muss aber nicht.

vect [Objekt]() oder (float x,y,z,a)oder (float* GLvect)

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.

Vektor [Objekt] (vect start,dest, color, float width=5.f )

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.

Wuerfel [Objekt](pos,dir, colf,coll,slen,thickness)

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)

Liefert für eine Richtung durch zwei Winkel ausgedrückt, den passenden kartesischen 3D-vektor als float-Array zurück.

A_Coord() Zeigt ein kartesisches 2D- oder 3D-Koordinatensystem an, das mit den ALGEO-Basisfunktionen arbeitet.

A_Init (title, frustum, units, thickness, width, height)

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.

A_Model(model); Setzt die ALGEO-Grafik auf eines der Modelle „A_BOOK“, „A_DARK“ oder „A_NIGHT“.

void justify(){ } 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.

Page 13: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

Thomas Cassebaum OpenGL mit C++ Seite 13 ALGEO - Statusvariablen

bool A_Csyst=true Koordinatensystem E(true)/A(false)

unsigned short A_Rotor=0; Koordinatenachsenrotation 0 – z vorn, 1 – x vorn, 2 – y vorn

bool A_full=true; Vollbildmodus E(true)/A(false)

GLfloat lightPos0[4] = LightPos0;

Lichtpositionen der vier Lichter (Standard: LightPos0)

GLfloat A_CoordColor[4] = A_KOORDWHITE

GLfloat A_CoordColor1[4] = A_KOORDBLUE

GLfloat A_CoordColor2[4] = A_KOORDGRAY

Koordinatenfarben (Standard; Weiss, Blau, Grau)

GLfloat A_GridNIGHT[4] = A_T_WHITE

GLfloat A_GridDARK[4] = A_T_WHITE

GLfloat A_GridBOOK[4] = A_T_BLACK

Gitterfarben der Koordinatenflächen für die Modelle

int A_0=A_1=A_2=A_3=A_4=A_5=A_6=A_7=A_8=A_9=1 Ganzzahlige Variablen !_i für Benutzersteuerung mit Tasten ‚i‘ | ‚Strg/i‘

float A_distance = 1.f Distanz der Kamera zum Ursprung (Standard: 1)

bool A_extmode = false Extended Mode der Benutzeranwendung [Taste ‚E‘: E(true)/A(false) ]

bool A_Foggy = true Nebel E(true)/A(false) (Standard: true)

bool A_HelpLines=false Hilfslinien (nur für ALGEO-Vektoren) : E(true)/A(false) (Standard:false)

float A_sx = A_sy = A_sz = 0.f Kameraverschiebung in Achsenrichtung (Standard: alle 0)

float A_phi=0.f; Kamera-Rotation um die y-Achse (5° entspricht der Angabe 5./180.*M_PI)

float A_theta=0.f; Kamera-Rotation um die x-Achse (5° entspricht der Angabe 5./180.*M_PI)

bool A_Gatt=true Koordinatenflächen-Gitterlinien E(true)/A(false) (Standard:true)

bool A_Positiv=false Nur Positiven Quadranten zeigen E(true)/A(false) (Standard:false)

float A_turn[3]={0.f,1.f,0.f} Vektor zur Rotation mit der Fkt. A_Turn() der Achsen in Uhrzeigerrichtung

float A_x=1.f Relle Benutzervariable [Steuerung mit Tasten ‚K‘ (kleiner) und ‚G‘ (größer)]

bool A_xPlane=A_yPlane=A_zPlane=false A_iPlane – Fläche, die durch die i-Achse durchstoßen wird E(true)/A(false)

ALGEO - vordefinierte Farben und Positionen

#define ZERO 0.f, 0.f, 0.f

#define UNIT_X 1.f, 0.f, 0.f

#define UNIT_Y 0.f, 1.f, 0.f

#define UNIT_Z 0.f, 0.f, 1.f

#define UNIT_XY 1.f, 1.f, 0.f

#define UNIT_XZ 1.f, 0.f, 1.f

#define UNIT_YZ 0.f, 1.f, 1.f

#define UNIT_XYZ 1.f, 1.f, 1.f

#define UNIT_X_M -1.f, 0.f, 0.f

#define UNIT_Y_M 0.f,-1.f, 0.f

#define UNIT_Z_M 0.f, 0.f,-1.f

#define UNIT_XY_M -1.f,-1.f, 0.f

#define UNIT_XZ_M -1.f, 0.f,-1.f

#define UNIT_YZ_M 0.f,-1.f,-1.f

#define UNIT_XYZ_M -1.f,-1.f,-1.f

#define TRANSP 0.f,0.f,0.f,.0f

#define URSPRUNG 0.f,0.f,0.f,.0f

#define WEISS 1.f, 1.f, 1.f, 1.f

#define BLAU 0.f, 0.f, 1.f, 1.f

#define ROT 1.f, 0.f, 0.f, 1.f

#define GRUEN 0.f, 1.f, 0.f, 1.f

#define GELB 1.f, 1.f, 0.f, 1.f

#define CYAN 0.f, 1.f, 1.f, 1.f

#define MAGENTA 1.f, 0.f, 1.f, 1.f

#define SCHWARZ 0.f, 0.f, 0.f, 1.f

#define GRAU .5f, .5f, .5f, 1.f

#define HELLGRAU .6f, .6f, .6f, 1.f

#define HELLBLAU .3f, .3f, 1.f, 1.f

#define HELLROT 1.f, .3f, .3f, 1.f

#define ROSA 1.f, .3f, .3f, 1.f

#define HELLGRUEN .3f, 1.0f,.3f, 1.f

#define HELLGELB 1.f, 1.f, .3f, 1.f

#define HELLCYAN .3f, 1.f, 1.f, 1.f

#define HELLMAGENTA 1.f,.3f, 1.f, 1.f

#define DUNKELGRAU .3f, .3f, .3f, 1.f

#define DUNKELBLAU 0.f, 0.f, .5f, 1.f

#define DUNKELROT .5f, 0.f, 0.f, 1.f

#define DUNKELGRUEN 0.f,.5f, 0.f, 1.f

#define DUNKELGELB .5f, .5f, 0.f, 1.f

#define DUNKELCYAN 0.f, .5f, .5f, 1.f

#define DUNKELMAGENTA .5f,0.f,.5f,1.f

#define T_GLASS 1.f, 1.f, 1.f, .33f

#define T_WEISS 1.f, 1.f, 1.f, .33f

#define T_BLAU 0.f, 0.f, 1.f, .33f

#define T_ROT 1.f, 0.f, 0.f, .33f

#define T_GRUEN 0.f, 1.f, 0.f, .33f

#define T_GELB 1.f, 1.f, 0.f, .33f

#define T_CYAN 0.f, 1.f, 1.f, .33f

#define T_MAGENTA 1.f, 0.f, 1.f, .33f

#define T_SCHWARZ 0.f, 0.f, 0.f, .33f

#define T_GRAU .5f, .5f, .5f, .33f

#define T_HELLGRAU .6f, .6f, .6f, .5f

#define T_HELLBLAU .3f, .3f, 1.f, .5f

#define T_HELLROT 1.f, .3f, .3f, .5f #define T_ROSA 1.f, .3f, .3f, .5f

#define T_HELLGRUEN .3f,1.0f,.3f, .5f

#define T_HELLGELB 1.f, 1.f, .3f, .5f

#define T_HELLCYAN .3f, 1.f, 1.f, .5f

#define T_HELLMAGENTA 1.f,.3f,1.f,.5f

#define T_DUNKELGRAU .3f,.3f,.3f,.33f

#define T_DUNKELBLAU 0.f,0.f,.5f,.33f

#define T_DUNKELROT .5f,0.f,0.f,.33f

#define T_DUNKELGRUEN 0.f,.5f,0.,.33f

#define T_DUNKELGELB .5f,.5f,0.f,.33f

#define T_DUNKELCYAN 0.f,.5f,.5f,.33f

#define T_DUNKELMAGENTA .5,0.,.5,.33f

Page 14: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

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 Betriebs-systems zugänglich macht.

Backface Culling: Es werden nur die Flächen gezeichnet, deren Normalenvektoren zum Betrachter hin weisen. Durch diese Tech-nik 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) be-schrä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

Page 15: OpenGl mit C++ - cassebaum.bplaced.netcassebaum.bplaced.net/schutz/ALGEO.pdf · Thomas Cassebaum OpenGL mit C++ Seite 4 1.4 Das Frustum Frustum (dt. Stumpf) oder häufig auch als

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 ISBN 3-8266-1534-4

[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 Internet 2000

[5] W. P. Kowlak, Spieleentwicklung mit OpenGL uns Java oder „JOGLn in Java“ Universität Oldenburg, 2005