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