Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie...

44
Seminararbeit im Rahmen des Studiengangs Scientific Programming Fachhochschule Aachen, Campus J¨ ulich Fachbereich 9 - Medizintechnik und Technomathematik Integration OpenGL-basierter Visualisierungs-Techniken in 2D-Grafiksystemen ulich, 15. Dezember 2011 Florian Rhiem Diese Arbeit wurde betreut von: Prof. Dr. Karl Ziemons Josef Heinen

Transcript of Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie...

Page 1: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

Seminararbeit im Rahmen des Studiengangs

Scientific Programming

Fachhochschule Aachen, Campus Julich

Fachbereich 9 - Medizintechnik und Technomathematik

Integration OpenGL-basierterVisualisierungs-Techniken in 2D-Grafiksystemen

Julich, 15. Dezember 2011

Florian Rhiem

Diese Arbeit wurde betreut von:Prof. Dr. Karl Ziemons

Josef Heinen

Page 2: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre
Page 3: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

Erklarung

Diese Arbeit wurde im Peter Grunberg Institut/Julich Centre for Neutron Science –Technische und Administrative Infrastruktur – Wissenschaftliche IT-Systeme der For-schungszentrum Julich GmbH konzipiert.

Sie ist von mir selbststandig angefertigt und verfasst. Es sind keine anderen als dieangegebenen Quellen und Hilfsmittel benutzt worden.

Unterschrift

Diese Arbeit wurde betreut von:Prof. Dr. Karl ZiemonsJosef Heinen

Page 4: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre
Page 5: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

Wissenschaftler am Peter Grunberg Institut/Julich Centre for Neutron Science unter-suchen in Experimenten und Simulationen Form und Dynamik von Materialen wie Po-lymeren, Zusammenlagerungen großer Molekule und biologischen Zellen sowie die elek-tronischen Eigenschaften von Festkorpern. Fur die Prasentation der in diesem Zusam-menhang anfallenden Forschungsergebnisse in Vortragen und Veroffentlichungen werdenhaufig Darstellungen von Kristall- und Molekulstrukturen in hochster Qualitat benotigt.

Den Schwerpunkt dieser Seminararbeit bildet die Untersuchung verschiedener Techni-ken sowie die Auswahl eines geeigneten Verfahrens, um solche Darstellungen in hochsterQualitat fur andere Applikationen nutzbar zu machen. Insbesondere soll eine einfacheIntegration OpenGL-basierter 3D-Grafiken in vorhandene 2D-Grafikwerkzeuge und An-wendungsschnittstellen ermoglicht werden. Zu diesem Zweck soll eine Programmbiblio-thek entwickelt werden, mit deren Hilfe es moglich ist 2D-Grafiken von dreidimensionalenObjekten zu erzeugen, so dass diese dann in Anwendungen genutzt werden konnen.

Moderne Programmierschnittstellen fur 3D-Grafik, wie z.B. OpenGL, sind oft sehrkomplex und erfordern viel Einarbeitungszeit. Die im Rahmen dieser Seminararbeit zuentwickelnde Bibliothek soll den Entwicklern eine einfache, konsistente Schnittstelle be-reitstellen, die plattformunabhangig und aus verschiedenen Programmiersprachen herausnutzbar ist.

Insbesondere soll eine Moglichkeit gefunden werden, bei der Erstellung der oben ge-nannten Grafiken system-spezifische Darstellungen zu vermeiden, um ohne ein Anzeige-fenster Grafiken zu erzeugen (offscreen rendering). Plattformabhangige Techniken sollenin der Bibliothek genutzt, aber fur den Anwendungsprogrammierer entsprechend abstra-hiert werden.

Im Rahmen einer Bachelorarbeit kann die Aufgabenstellung um die Erstellung einesgemeinsamen Frameworks erweitert werden, welches die Moglichkeiten konventioneller2D-Grafik und interaktiver 3D-Systeme vereint. Eine besondere Herausforderung stellthierbei die Plattformunabhangigkeit sowie die einfache und transparente Benutzung ausSicht der Entwickler und Anwender dar.

Page 6: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre
Page 7: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

Inhaltsverzeichnis

Inhaltsverzeichnis

1 Motivation 1

2 Grundlagen 22.1 Konzept der Bibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22.2 OpenGL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

2.2.1 Legacy OpenGL . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42.2.2 Core Profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2.3 Plattformabhangige Schnittstellen zu OpenGL . . . . . . . . . . . . . . . 62.3.1 OpenGL Extension to the X Window System (GLX) . . . . . . . 62.3.2 Core OpenGL (CGL) . . . . . . . . . . . . . . . . . . . . . . . . . 62.3.3 Windows Extensions to OpenGL (WGL) . . . . . . . . . . . . . . 8

3 Realisierung 93.1 Offscreen Rendering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.1.1 Erstellung eines Offscreen OpenGL Context . . . . . . . . . . . . 103.1.2 Framebuffer Objekte . . . . . . . . . . . . . . . . . . . . . . . . . 16

3.2 Retained Mode Rendering . . . . . . . . . . . . . . . . . . . . . . . . . . 183.2.1 OpenGL Display Lists . . . . . . . . . . . . . . . . . . . . . . . . 183.2.2 OpenGL Vertex Buffer Objekte . . . . . . . . . . . . . . . . . . . 193.2.3 Vorstellung des implementierten Systems . . . . . . . . . . . . . . 20

3.3 Erstellung von Grafiken in hoher Auflosung . . . . . . . . . . . . . . . . . 21

4 Ergebnisse 244.1 Benutzung der API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

5 Ausblick 31

Listings 33

Abbildungsverzeichnis 33

Literatur 34

i

Page 8: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre
Page 9: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

1 Motivation

Seit den ersten dreidimensionalen Computeranimationen 1976 an der University of Utahbis heute, hat sich die 3D-Grafik weit entwickelt und wird mittlerweile in den verschie-densten Bereichen eingesetzt. Von der dreidimensionalen Landkarte auf einem Smart-phone bis zu Computer-Aided Design auf einer Workstation – wenn Mess-, Simulations-und mehrdimensionale Daten visualisiert werden, sind sie fur Menschen meist schnellverstandlich. Besonders bei Vortragen, Postern oder Veroffentlichungen ist der Einsatzvon Visualisierungen sehr wichtig, um die oft enormen Datenmengen so zu prasentieren,dass der Betrachter sie verstehen und wichtige Aussagen nachvollziehen kann. Fur solcheEinsatzwecke ist eine hohe Qualitat der Grafiken wichtig; einfache

”Bildschirmfotos“ von

Visualisierungsanwendungen reichen haufig nicht aus.Die zur Erstellung solcher Grafiken benotigte Programmierung mit 3D-Grafikschnitt-

stellen ist sehr aufwendig und komplex, denn der Programmierer hat tiefgreifende Kon-troll- und Optimierungsmoglichkeiten, wie sie hauptsachlich fur moderne Echtzeit-An-wendungen wie Computerspiele benotigt werden. Oft will man allerdings nur einzelneGrafiken erzeugen, die teilweise relativ simpel aufgebaut sind; beispielsweise konnenMolekule allein mit Kugeln und Zylindern fur die Atome und Atombindungen gut vi-sualisiert werden (ball-and-stick Modelle).

Daher habe ich im Rahmen dieser Seminararbeit die Bibliothek OpenGL offscreenrenderer (GLor) entwickelt, mit der man bei geringem Zeitaufwand hochauflosende 3D-Grafiken erzeugen kann. Die Erstellung der Grafiken lauft dabei plattformunabhangigund ohne sich offnende Fenster ab, so dass die Bibliothek auch in andere Programme inte-griert werden kann, ohne deren Benutzbarkeit negativ zu beeintrachtigen. Beispielsweisekonnen so in einer Simulation Bilder erzeugt werden, die zum Verstandnis beitragenkonnen.

In dieser Arbeit mochte ich die verwendeten Techniken vorstellen und die Proble-me, die bei Entwurf und Implementierung der Bibliothek aufgetreten sind, und derenLosungen erlautern. Im Anschluss folgt eine kurze Einfuhrung in die Benutzung derBibliothek.

1

Page 10: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

2 Grundlagen

2 Grundlagen

2.1 Konzept der Bibliothek

Beim Entwurf und der Entwicklung der Bibliothek wurden folgende Ziele verfolgt:

1. Hohe Qualitat der erzeugten Grafiken

2. Plattformunabhangigkeit

3. Geringe Einarbeitungszeit und einfache Benutzbarkeit durch den Anwender

4. Erzeugung der Grafiken ohne zusatzliche Anzeigefenster

5. Moglichkeit der Benutzung mit verschiedenen Sprachen, z. B. Python oder Java

Um Grafiken in hoher Qualitat zu erzeugen, mussen weit hohere Auflosungen als diebei Bildschirmen ublichen Auflosungen moglich sein. Speziell bei Printmedien sind hoheAuflosungen moglich und sollten daher auch genutzt werden. Verwendet man Grafi-ken mit einer geringeren Auflosung, als die fur das Ausgabemedium passende, tretenQuantisierungseffekte auf. Neben Einsatzzwecken wie dem Posterdruck hat die Nutzunghochauflosender Grafiken auch Vorteile fur Prasentationen, die an Bildschirmen oder miteinem Beamer angezeigt werden sollen, denn das Umrechnen auf kleinere Auflosungen(downsampling) fuhrt in diesem Fall zur Kantenglattung per Supersample Antialiasing(SSAA).

Zur Erzeugung der Grafiken wird OpenGL genutzt, da es sich dabei um eine plattfor-munabhangige und sehr verbreitete Schnittstelle handelt.

Damit die Bibliothek leichter zu benutzen ist als OpenGL, beschrankt sie sich auf dieDarstellung von Dreiecksgittern und ein einfaches Beleuchtungsmodell mit einer einzel-nen Lichtquelle im Raum oder

”auf der Kamera“. Außerdem werden die von OpenGL ge-

botenen Moglichkeiten der Performance-Optimierung vor dem Benutzer versteckt, denndie Zeit zur Erzeugung eines Bildes ist fur die geplanten Einsatzzwecke nebensachlich.Um fur haufige Anwendungen die Benutzung zu erleichtern, wurden Hilfsfunktionenimplementiert, mit denen einfache Korper wie Kugeln, Zylinder oder Kegel gezeichnetwerden konnen, ohne das fur sie erst eine Dreiecksgitter erstellt werden muss.

OpenGL wird ublicherweise interaktiv genutzt, also in einem Fenster mit der Moglich-keit das Angezeigte durch Mausbewegung, Klicks oder mit der Tastatur zu beeinflussen.Die im Rahmen dieser Seminararbeit erstellte Bibliothek soll jedoch keine Interakti-on bieten und die angestrebten Auflosungen sind auch in modernen Systemen nichtvollstandig in einem Fenster darstellbar. Das Erzeugen der Grafiken soll daher komplettohne Anzeigefenster erfolgen. Dies kann zwar nur plattformabhangig ermoglicht wer-den, aber der plattformabhangige Teil des Programms soll vollstandig vor dem Nutzerverborgen bleiben.

Die Bibliothek ist in der Programmiersprache C geschrieben, da diese eine Program-mierung nah am jeweiligen Betriebssystem ermoglicht. Unter Linux, Apple Mac OS Xund Microsoft Windows sind die fur OpenGL zustandigen Schnittstellen aus C verfugbar.

2

Page 11: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

2.2 OpenGL

OpenGL ist ebenfalls direkt aus C benutzbar, wahrend andere Sprachen, wie z. B. Py-thon, zur Benutzung von OpenGL eine Schnittstelle zu C (ctypes) nutzen und damitwiederum auf die Funktionen von OpenGL zugreifen. Ein weiterer Vorteil von C ist,dass es sich in viele andere Programmiersprache integrieren lasst. Damit ist die Moglich-keit gegeben, dass die Bibliothek auch aus anderen Sprachen benutzt werden kann. Umdies weiter zu unterstutzen wurde darauf geachtet, die Schnittstelle ohne Einsatz vonStructs, Unions, etc., benutzen zu konnen. Eine Anbindung an die Bibliothek fur Pythonwurde wahrend der Entwicklung geschrieben, so dass sichergestellt werden konnte, dassdie im Entwurf geplante Sprachunabhangigkeit auch gegeben war.

2.2 OpenGL

Die zur Erzeugung der Grafiken genutzte Schnittstelle, die Open Graphics Library(OpenGL), ist eine Software-Schnittstelle zur Grafikhardware[1]. Es handelt sich dabeinicht um eine Bibliothek, wie der Name vermuten lasst, sondern um eine Spezifikationfur eine Schnittstelle, die eine Bibliothek implementieren kann. Eine solche OpenGL-Implementierung ist auf den meisten modernen Arbeitsplatzrechnern vorhanden, dennsie ist fester Bestandteil von Microsoft Windows (allerdings nur in Version 1.1), App-le Mac OS X (denn dort wird die gesamte grafische Benutzeroberflache mit OpenGLerzeugt), und vieler Linux-Distributionen. Neben den im Betriebssystem mitgeliefertenImplementierungen, gibt es auch Implementierungen, die in Verbindung mit speziellenGrafikkartentreiber bereitgestellt werden. OpenGL ist so konzipiert, dass die Erzeugungder Grafiken auf eine GPU ausgelagert werden kann, um die CPU zu entlasten. In diesemFall bezeichnet man das Rendering, also die Erzeugung der Grafiken, als hardwarebe-schleunigt.

Die Spezifikation von OpenGL ist vollkommen plattformunabhangig und beschreibtdie Erzeugung von Grafiken in einer sogenannten Pipeline, ausgehend von dreidimensio-naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und derenEigenschaften, wie z. B. ihre Farbe, beschrieben und zusammen mit Pixeldaten (Textu-ren) wird in mehreren Schritten ein Bild erzeugt. Dabei werden die Vertices zuerst auseinem abstrakten, vom Anwender zu bestimmendem Koordinatensystem in sogenanntenormalisierte Geratekoordinaten[12] ubertragen, zu grafischen Primitiven (Punkten, Li-nien und Dreieecken) zusammengesetzt und dann in eine Rastergrafik umgewandelt. Furden Ablauf dieser Schritte gibt es zwei Modelle: Die klassische Fixed-Function-Pipeline1,in der man Transformationen, Beleuchtung, etc. durch Parameter beeinflusst, und diemoderne Shader-basierte Pipeline2 [1] (siehe Abbildung 1 und Abbildung 2). Shader-Programme sind kleine, vom Anwendungsentwickler in der OpenGL Shading Language(GLSL) geschriebene Programme, welche bestimmte Abschnitte der OpenGL Pipeline,wie die Vertex-Transformationen oder die Beleuchtung, realisieren. Sie werden, wennmoglich, auf der Grafikkarte parallel ausgefuhrt.

1vor OpenGL 3.1; oft”Legacy OpenGL“ genannt

2ab OpenGL 3.1; oft”Core Profile“ genannt, zur Abgrenzung vom abwarts- aber nicht vorwartskom-

patiblem”Compatibility Profile“, welches Legacy OpenGL auch in Version 3.1 aufwarts unterstutzt

3

Page 12: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

2 Grundlagen

2.2.1 Legacy OpenGL

OpenGL Implementierungen, welche die Fixed-Function-Pipeline unterstutzen, sind weitverbreitet, da auch die meisten aktuellen Implementierungen durch das

”Compatibility

Profile“ die veralteten Funktionen unterstutzen3. Sie bieten vier Moglichkeiten die Ver-texdaten anzugeben:

• Immediate Mode Rendering

• Retained Mode Rendering mit

– Display Listen

– Vertexdaten im Hauptspeicher

– Vertex Buffer Objekten (seit OpenGL 1.5 in der Spezifikation, fruher alsErweiterung[6][9])

Im sogenannten Immediate Mode Rendering sorgt jeder Aufruf einer glVertex*()4 Funk-tion dafur, dass der dadurch spezifizierte Vertex sofort verarbeitet wird. Sobald genugVertices fur eine Primitive vorhanden sind, durchlauft diese den Rest der Pipeline undwird angezeigt.

Aufrufe von Immediate Mode Funktionen konnen in Display Lists gespeichert und be-liebig oft ausgefuhrt werden (siehe Abbildung 1 auf der nachsten Seite). Dieses Vorgehendes einmaligen Spezifizierens der darzustellenden Objekte und getrennten, wiederholba-ren Ausfuhrens der Anweisungen charakterisiert das Retained Mode Rendering. Einezweite Moglichkeit hierzu bildet das Array-basierte Rendern, in dem Speicherbereichemit den Vertexdaten gefullt werden. Solche Vertex Arrays werden zum Rendern an diePipeline ubergeben und dort dann abgearbeitet. Diese Speicherbereiche liegen entwederim Hauptspeicher oder als Vertex Buffer Objekt im schnelleren Grafikkartenspeicher.

Im Legacy OpenGL werden fur jeden Vertex die Farbwerte berechnet und fur die beider Rasterisierung erzeugten Fragmente5 werden diese Farbwerte interpoliert (Per-vertexlighting).

2.2.2 Core Profile

Vertex Buffer Objekte und Shader-Programme stehen als Erweiterung der Spezifikationbereits seit OpenGL 1.4 zur Verfugung[8][9], jedoch blieb die Fixed-Function-Pipelineerhalten. Dies anderte sich im Rahmen der OpenGL Version 3.1, denn es wurden einigeFunktionen, die im Legacy OpenGL zur Verfugung stehen, aus dem Kern der Spezifika-tion entfernt. Die Angabe der Vertexdaten erfolgt nun ausschließlich uber Vertex BufferObjekte (VBOs) und in der Pipeline wurden mehrere Schritte durch Shader-Programme

3Eine Ausnahme bildet hier die OpenGL 3.2 Implementierung von Apple Inc., die mit Mac OS X Lionausgeliefert wird und entweder OpenGL 2.1 oder OpenGL 3.2

”Core Profile“ anbietet, aber kein

”Compatibility Profile“

4Mit den Funktionen nach dem Namensschema glVertex[234][sifd](), bzw. glVertex[234][sifd]v() wirddie Position eines Vertex angegeben.

5Fragmente entsprechen vereinfacht gesagt den Pixeln, die man in der erzeugten Grafik sieht.

4

Page 13: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

2.2 OpenGL

Abbildung 1: Die Legacy OpenGL Pipeline[3]

5

Page 14: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

2 Grundlagen

ersetzt (siehe Abbildung 2 auf der nachsten Seite). Diese Einschrankungen erlauben denImplementierungen Altlasten loszuwerden und ermoglichen den Nutzern der Schnittstel-le die Verwendung von speziell an die Anwendung angepassten Shader-Programmen.Beispielsweise Per-pixel lighting oder das sogenannte Deferred Rendering, bei dem ineinem Zwischenschritt der Framebuffer mit Geometriedaten gefullt wird, ist erst durchdie Einfuhrung der Shader-Programme moglich geworden.

Um zu zukunftigen OpenGL Implementierungen kompatibel zu sein, sollten neu ge-schriebene Programme mit dem Core Profile funktionieren; beispielsweise indem es zweiRenderpfade gibt, einen fur Legacy OpenGL und einen fur Core Profile OpenGL.

2.3 Plattformabhangige Schnittstellen zu OpenGL

Die Spezifikation von OpenGL ist zwar vollkommen plattformunabhangig, doch um ei-ne OpenGL Implementierung benutzen zu konnen, benotigt man eine Anbindung anden Teil des Betriebssystems, der die Grafik verwaltet. Dies ist ublicherweise das Fens-tersystem. Uber eine solche Anbindung muss ein sogenannter OpenGL Context erstelltwerden, durch den festgelegt ist, womit gerendert wird, welche OpenGL Version benutztwerden soll, wo der Framebuffer liegt, etc. [1, S. 7] Diese Schnittstellen werden oft durchplattformunabhangige Schnittstellen und Bibliotheken weiter abstrahiert, z. B. durch dasOpenGL Utility Toolkit (GLUT) [19]. Um spezielle Anwendungen wie Offscreen Rende-ring zu realisieren, muss man dennoch auf plattformabhangige Schnittstellen zuruckgrei-fen.

2.3.1 OpenGL Extension to the X Window System (GLX)

Die meisten unixartigen Betriebssysteme, beispielsweise Linux-Distributionen, benutzendas X Window System als Fenstersystem. Um OpenGL unter diesem System nutzen zukonnen, wurde eine Erweiterung fur X spezifiziert, welche die Erstellung eines OpenGLContext im X Server ermoglicht. Um einen Context erstellen zu konnen, benotigt maneinen GLX Zeichenbereich, ein GLX Drawable. Solch einen Zeichenbereich kann manbeispielsweise fur ein X Fenster erzeugen, um in dieses Fenster zu rendern. [13, S. 2]

Mit Mesa3D steht unter Linux eine quelloffene Implementierung der OpenGL API zurVerfugung, die je nach Hardware OpenGL bis zu Version 2.1 mit vielen Erweiterungenanbietet [20]. Außerdem konnen fur die Grafikkarte passende Treiber installiert werden,mit denen auch aktuelle OpenGL Versionen, z. B. Version 4.2, unterstutzt werden.

2.3.2 Core OpenGL (CGL)

Mac OS X nutzt OpenGL zur Darstellung der Benutzeroberflache. Die zugehorige API,Core OpenGL (CGL), ist die Basis des Fenstersystems. Um einen OpenGL Context zuerzeugen, mussen einige grundlegende Eigenschaften, wie Farbtiefe und Art des Zeichen-bereiches, in einem Pixel Format festgelegt werden. Dabei ist es nicht zwingend, dassein Zeichenbereich fur diesen Context existiert.[14][4, Kapitel 14]

6

Page 15: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

2.3 Plattformabhangige Schnittstellen zu OpenGL

Abbildung 2: Die OpenGL Core Profile Pipeline[3][5]

7

Page 16: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

2 Grundlagen

Aktuelle Implementierungen fur Apple Gerate werden mit Mac OS X mitgeliefert undbieten OpenGL 2.1 oder, seit Mac OS X 10.7

”Lion“, als Alternative eine Core Pro-

file Implementierung von OpenGL 3.2. Auch ein Software-Renderer6, der die gleichenFunktionen bietet, ist enthalten.[16]

2.3.3 Windows Extensions to OpenGL (WGL)

In Microsoft Windows ist OpenGL seit Windows NT 3.5 verfugbar[4, S. 542], doch durchMicrosoft DirectX, einem Framework, das unter anderem eine 3D-Grafik API enthalt(Direct3D), ist die Unterstutzung durch Microsoft eher eingeschrankt. Zwar wird mitdem Betriebssystem eine Implementierung ausgeliefert, diese ist allerdings veraltet (Ver-sion 1.1). Eine aktuelle Implementierung erhalt man nur durch Installation eines Her-stellerspezifischen Grafikkartentreibers.

Um in Microsoft Windows einen OpenGL Context erstellen zu konnen, muss mit denWindows Extensions to OpenGL (WGL) fur einen GDI7 Device Context ein OpenGL-fahiges Pixel Format gewahlt werden. Dieser Device Context muss zu einem erstelltenFenster oder einer gerateunabhangigen Bitmap gehoren.[17]

Eine Besonderheit stellt die Art und Weise dar, wie Funktionen, die zu Erweiterungender unterstutzten OpenGL Version gehoren, benutzt werden. Nach der Erstellung desOpenGL Context konnen Funktionszeiger zu diesen Funktionen abgefragt werden, durchwelche die Erweiterungen nutzbar werden. Unter Linux und Mac OS X reicht dazu dasEinbinden einer Header-Datei.[4, Kapitel 13]

Abbildung 3: Die Bibliothek bildet eine Schicht zwischen der Anwendung auf der einenund OpenGL und CGL, GLX oder WGL auf der anderen Seite.

6eine Implementierung, die nur die CPU nutzt7Graphics Device Interface, die unter Windows fur die Abstraktion von Grafikgeraten zustandige API

8

Page 17: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3 Realisierung

Die Erstellung von Grafiken soll moglichst einfach in bestehende Programme integriertwerden konnen, die bisher keine 3D-Funktionalitat unterstutzen. Daher fiel die Ent-scheidung kein eigenstandiges Programm, sondern eine Programmierschnittstelle undeine dynamische Bibliothek zu entwickeln. Beim Entwurf der Bibliothek wurden dreiProblemstellen deutlich, die in den folgenden Abschnitten diskutiert werden:

• Offscreen Rendering Es mussen Moglichkeiten gefunden werden, OpenGL oh-ne ein sichtbares Anzeigefenster zu nutzen und derenImplementierungen mussen durch eine plattformunab-hangige Schnittstelle abstrahiert werden.

• Retained Mode Rendering Das Rendering darf nicht im Immediate Mode erfol-gen, da dies die Benutzung, beispielsweise das Erstellenvon Bildern aus verschiedenen Perspektiven, erschwerenwurde. Der Losungsansatz muss dabei unabhangig vonder vorhanden OpenGL Version sein.

• Erstellung von Grafikenin hoher Auflosung

Um Grafiken in hoher Qualitat zu erzeugen muss eineMoglichkeit gefunden werden, mit OpenGL Grafiken inhoheren Auflosungen zu erstellen, als die ublichen Bild-schirmauflosungen.

Abbildung 4: Ein Entwurf des Nutzungsschemas der Bibliothek

9

Page 18: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3 Realisierung

Wie in Abbildung 4 auf der vorherigen Seite zu sehen, ergibt sich durch die Aufspaltungdes Gesamtproblems in diese drei Teilprobleme eine unkomplizierte Handhabung derProgrammierschnittstelle. Die Bibliothek wird zu Beginn der Nutzung initialisiert, dabeiwird implizit ein OpenGL Context fur das Offscreen Rendering erstellt. Anschließendwird die Szene, also die darzustellenden Objekte, definiert. Die Art, wie diese Definitionerfolgt, ist der erste Teil des Retained Mode Rendering Systems. Von dieser Szene konnennun beliebig Grafiken erzeugt werden, wobei logischerweise die Szene gerendert wird. DasRendern bildet den zweiten Teil des Retained Mode Rendering Systems. Diese beidenSchritte konnen mehrfach wiederholt werden, bis alle gewunschten Grafiken erzeugt sind,danach mussen der OpenGL Context und die Bibliothek freigegeben werden. Außerhalbder Initialisierungs- und Freigabemethoden wird das Offscreen Rendering System aufGrund der Plattformunabhangigkeit von OpenGL nicht genutzt, die Bibliothek ließesich also auch mit einem OpenGL Context in einem Fenster benutzen.

3.1 Offscreen Rendering

Das Problem des Offscreen Rendering lasst sich wiederum in zwei Teile unterteilen.OpenGL selbst enthalt ein Werkzeug um abseits des Standard-Framebuffers zu ren-dern, die sogenannten Framebuffer Objekte (FBOs). Diese lassen sich mit OpenGL-Funktionen erstellen und konnen als gleichwertiger Ersatz zum vom Fenstersystem er-zeugten Standard-Framebuffer verwendet werden. Um Funktionen von OpenGL nutzenzu konnen, muss jedoch bereits ein OpenGL Context existieren. In den ublichen Anwen-dungen stellt dies keinerlei Problem dar, weil ein FBO dort als Hilfsmittel fur Effekte wieSpiegelungen oder Schatten und nicht als dauerhafter Ersatz des Standard-Framebuffersgenutzt wird. Fur diese Bibliothek, bedeutet dies aber, dass erst ein Offscreen OpenGLContext (mit oder ohne Standard-Framebuffer) und anschließend ein Framebuffer Objekterstellt werden muss.

3.1.1 Erstellung eines Offscreen OpenGL Context

Wie in Abschnitt 2.3 beschrieben, ist die Erzeugung eines OpenGL Context plattfor-mabhangig. Die zu Grunde liegenden Konzepte konnen allerdings abstrahiert werden.In den drei plattformabhangigen Programmierschnittstellen wird zur Erstellung einesOpenGL Context immer zumindest die Information daruber benotigt, von welcher Artder Zeichenbereich sein muss. Dabei gibt es drei unterschiedliche Arten:

• Fenster

• Pixmaps/Bitmaps

• Pixel Buffer

Zwischen den letzten beiden besteht der Hauptunterschied darin, dass Pixel Buffer imSpeicher der Grafikkarte liegen, falls dedizierter Grafikspeicher vorhanden ist, wahrendBitmaps normale Speicherbereiche der Anwendungen im Hauptspeicher sind. Fur den

10

Page 19: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3.1 Offscreen Rendering

Zweck des Offscreen Rendering sind nur vollkommen”unsichtbare“ Fenster eine Losung,

dagegen sind Pixmaps und Pixel Buffer fur die Benutzung zum Offscreen Renderingausgelegt. Pixmaps haben den Nachteil, dass sie nur fur Software-Renderer benutzt wer-den konnen, da der Framebuffer im Hauptspeicher liegt. Dies ist allerdings nur unterWindows relevant, da unter Mac OS X und Linux moderne Software-Renderer vorhan-den sind, welche die fur die Bibliothek benotigten OpenGL Features (vor allem FBOs)unterstutzen. Pixel Buffer sind hingegen speziell fur hardwarebeschleunigtes OffscreenRendering konzipiert.[15]

Art des OpenGL Hardwarebeschleunigung Verfugbar unter

Zeichenbereiches moglich Linux Mac OS X Windows

Fenster 3 3 3 3

Pixmap 7 3 7 3

Pixel Buffer 3 3 3 7

Tabelle 1: Ubersicht uber Zeichenbereichsarten

Mac OS X

Unter Mac OS X ist zur Erstellung eines OpenGL Context im Gegensatz zu Linux undWindows nur die Information uber die Art des Zeichenbereiches notig, ein solcher Zei-chenbereich muss nicht existieren. Daher kann mit CGL ein Pixel Format ausgewahltwerden, welches fur einen Pixel Buffer gedacht ist, und mit diesem – ohne Erstellungeines tatsachlichen Pixel Buffers – ein OpenGL Context erstellt werden.

Listing 1: Erstellung eines OpenGL Context mit CGL

CGLContextObj context;

CGLPixelFormatObj pix;

GLint npix;

const CGLPixelFormatAttribute pf_attributes [] = {

kCGLPFAColorSize , 24, /* 32bit RGBA Color Buffer */

kCGLPFAAlphaSize , 8,

kCGLPFADepthSize , 24, /* 24bit Depth Buffer */

kCGLPFAPBuffer , /* Format fuer einen Pixel Buffer */

0, 0

};

/* Auswahl von Pixel Formaten */

CGLChoosePixelFormat(pf_attributes , &pix , &npix);

/* Erstellung des OpenGL Context mit dem ersten Format */

CGLCreateContext(pix ,NULL ,& context);

/* Freigabe der Pixel Formate */

CGLReleasePixelFormat(pix);

/* Den Context fuer OpenGL Funktionen benutzen */

11

Page 20: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3 Realisierung

CGLSetCurrentContext(context);

Nun konnen OpenGL-Funktionen benutzt werden. Bei der Freigabe der Bibliothek mussauch der OpenGL Context freigegeben werden.

Listing 2: Freigabe eines OpenGL Context mit CGL

/* Den Context freigeben */

CGLReleaseContext(context);

Linux

Unter Linux stehen Pixel Buffer erst ab GLX 1.3 zur Verfugung. Um einen Context miteinem Pixel Buffer zu erstellen, muss eine fur einen Pixel Buffer geeignete FramebufferKonfiguration (analog zu den Pixel Formaten unter Mac OS X und Windows) ausgewahltwerden. Mit dieser kann ein Pixel Buffer fur das aktuelle X Display erstellet werden:

Listing 3: Erstellung eines Pixel Buffers mit GLX

Display *display;

int fbcount;

GLXFBConfig *fbc;

GLXFBConfig fbconfig;

GLXPbuffer pbuffer;

int fb_attribs [] = {

GLX_DRAWABLE_TYPE , GLX_PBUFFER_BIT , /* Config fuer einen

Pixel Buffer */

GLX_RENDER_TYPE , GLX_RGBA_TYPE , /* RGBA als Farbsystem */

None

};

int pbuffer_attribs [] = {

GLX_PBUFFER_WIDTH , 1,

GLX_PBUFFER_HEIGHT , 1,

None

};

/* Standard X Display benutzen */

display = XOpenDisplay (0);

/* Auswahl von Framebuffer Konfigurationen */

fbc = glXChooseFBConfig(display , DefaultScreen(display),

fb_attribs , &fbcount);

fbconfig = fbc [0];

XFree(fbc);

/* Pixel Buffer erstellen */

pbuffer = glXCreatePbuffer(display , fbconfig , pbuffer_attribs);

Falls nur GLX 1.2 unterstutzt wird, weicht die Bibliothek auf die Erstellung einer Pix-map aus. Die fehlende Hardwarebeschleunigung sorgt zwar fur eine Verlangsamung desRendern-Prozesses, doch der Mesa3D Software-Renderer besitzt alle fur die Bibliothek

12

Page 21: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3.1 Offscreen Rendering

benotigten Eigenschaften. Um eine X Pixmap zu erzeugen wird wie in Listing 3 eineFramebuffer Konfiguration ausgewahlt. Aus dieser werden die fur das X Window Systemnotigen Informationen ausgelesen und zur Erstellung einer X Pixmap auf dem X Serververwendet.

Listing 4: Erstellung einer X Pixmap mit GLX

Display *display;

Pixmap pixmap;

int fbcount;

GLXFBConfig *fbc;

GLXFBConfig fbconfig;

XVisualInfo *visual;

int fb_attribs [] = {

GLX_DRAWABLE_TYPE , GLX_PIXMAP_BIT , /* Config fuer eine

Pixmap */

GLX_RENDER_TYPE , GLX_RGBA_TYPE , /* RGBA als Farbsystem */

None

};

/* Standard X Display benutzen */

display = XOpenDisplay (0);

/* Auswahl von Framebuffer Konfigurationen */

fbc = glXChooseFBConfig(display , DefaultScreen(display),

fb_attribs , &fbcount);

fbconfig = fbc [0];

XFree(fbc);

/* XVisualInfo aus der Framebuffer Konfiguration auslesen */

visual = glXGetVisualFromFBConfig(display ,fbconfig);

/* X Pixmap erstellen */

pixmap = XCreatePixmap(display , XRootWindow(display ,

DefaultScreen(display)), 1, 1, visual ->depth);

Nachdem man sich ein solches Drawable, also ein Pixel Buffer oder eine Pixmap erstellthat, kann man diese verwenden um einen mit der Framebuffer Konfiguration erstelltenOpenGL Context zu benutzen.

Listing 5: Erstellung eines OpenGL Context mit GLX

GLXContext context;

/* Den Context erstellen ... */

context = glXCreateNewContext(display , fbconfig , GLX_RGBA_TYPE ,

None , True);

/* ... und mit dem Drawable benutzen */

glXMakeContextCurrent(display , drawable , drawable , context);

Wahrend der Freigabe der Bibliothek mussen auch der OpenGL Context und das Dra-wable freigegeben und die Verbindung zum Display geschlossen werden.

13

Page 22: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3 Realisierung

Listing 6: Freigabe eines OpenGL Context mit GLX

/* Den Context selbst freigeben */

glXDestroyContext(display , context);

/* Die genutzte Drawable freigegeben */

if (used_pbuffer) {

glXDestroyPbuffer(display , pbuffer);

} else {

XFreePixmap(display , pixmap);

}

/* Die Verbindung zum Display schliessen */

XCloseDisplay(display);

Windows

Unter Windows stehen keine Pixel Buffer zur Verfugung und es wird ein Drawable –in der Windows API HWND genannt – benotigt. Die Moglichkeit, wie in Linux aufeine Pixmap auszuweichen, besteht nicht, denn der Software-Renderer ist unter Win-dows, wie in Abschnitt 2.3.3 erwahnt, veraltet. Es besteht allerdings die Moglichkeitunsichtbare Fenster anzuzeigen und dies wird in der Initialisierung der Bibliothek auchgetan. Um so ein Fenster zu erstellen, wird zuerst eine Fensterklasse definiert, und furdie Bibliothek registriert (die hInstance wird beim Laden der Bibliothek durch Windowsubergeben). Das Fenster soll unsichtbar sein, entsprechend ist das Aussehen des Fenstersnicht relevant und die Standardwerte sind in Ordnung.[18]

Listing 7: Registrierung einer Fensterklasse in der Windows API

WNDCLASS wndclass;

/* Die Fensterklasse definieren */

wndclass.style = 0;

wndclass.lpfnWndProc = DefWindowProc; /* Standard

Event -Behandlung */

wndclass.cbClsExtra = 0;

wndclass.cbWndExtra = 0;

wndclass.hInstance = hInstance;

wndclass.hIcon = NULL;

wndclass.hCursor = LoadCursor (NULL ,IDC_ARROW);

wndclass.hbrBackground = NULL;

wndclass.lpszMenuName = "OpenGLWindow";

wndclass.lpszClassName = "OpenGLWindow";

/* Die Fensterklasse registrieren */

RegisterClass (& wndclass);

Anschließend kann ein Fenster mit dieser Klasse erstellt und fur dieses Fenster ein PixelFormat gewahlt werden.

14

Page 23: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3.1 Offscreen Rendering

Listing 8: Erstellung eines Fensters in der Windows API

HWND hWnd;

PIXELFORMATDESCRIPTOR pfd;

int iPixelFormat;

HDC dc;

/* Das Fenster erstellen */

hWnd = CreateWindow ("OpenGLWindow", "OpenGL Fenster", 0, 0, 0,

1, 1, NULL , NULL , hInstance , NULL);

/* Den Device Context des Fensters abfragen */

dc = GetDC(hWnd);

/* Ein Pixel Format beschreiben */

memset (&pfd ,0,sizeof(pfd));

pfd.nSize = sizeof(pfd);

pfd.nVersion = 1;

pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; /*

Format fuer ein Fenster */

pfd.iPixelType = PFD_TYPE_RGBA; /* RGBA als Farbsystem */

pfd.cColorBits = 24; /* 32bit Color Buffer */

pfd.cAlphaBits = 8;

pfd.cDepthBits = 24; /* 24bit Depth Buffer */

pfd.iLayerType = PFD_MAIN_PLANE;

/* Das Pixel Format fuer den Device Context auswaehlen und

setzen */

iPixelFormat = ChoosePixelFormat(dc ,&pfd);

SetPixelFormat(dc ,iPixelFormat , &pfd);

Wie unter Mac OS X und Linux ist es moglich nun einen Context zu erstellen und zubenutzen.

Listing 9: Erstellung eines OpenGL Context mit WGL

HGLRC context;

/* Den Context erstellen ... */

context = wglCreateContext(dc);

/* ... und mit dem Device Context des Fensters benutzen */

wglMakeCurrent(dc ,context);

Bevor alle OpenGL Funktionen zur Verfugung stehen, mussen jedoch Funktionszeiger zuden Funktionen aus Erweiterungen abgefragt werden. Dies kann auch mit Bibliothekenwie der OpenGL Extension Wrangler Library (GLEW) oder der OpenGL Easy Exten-sion Library (GLee) erledigt werden; um frei von einer solchen Abhangigkeit zu bleibenwerden diese Zeiger in der Bibliothek jedoch selbst abgefragt. Nach diesem Schritt kanndie Funktion ganz normal benutzt werden.[4, Kapitel 13]

15

Page 24: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3 Realisierung

Listing 10: Abfragen eines Funktionszeigers mit WGL

/* Auf globaler Ebene */

/* Die Typen folgen dem Schema "PFN"+ Funktionsname +"PROC" und

sind in der Header -Datei glext.h definiert */

static PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;

[...]

/* In der Initialisierung */

glGenFramebuffersEXT = (PFNGLGENFRAMEBUFFERSEXTPROC)

wglGetProcAddress("glGenFramebuffersEXT");

Zur Freigabe der Bibliothek mussen der OpenGL Context, der Device Context und dasFenster freigegeben und die Fensterklasse abgemeldet werden.

Listing 11: Freigabe eines OpenGL Context mit WGL

wglDeleteContext(context);

ReleaseDC(hWnd ,dc);

DestroyWindow(hWnd);

UnregisterClass("OpenGLWindow", hInstance);

3.1.2 Framebuffer Objekte

Wie einleitend erwahnt, gibt es in OpenGL die Moglichkeit, Framebuffer Objekte alsAlternative zum Standard-Framebuffer zu erstellen. Diese Objekte wurden in der Er-weiterung GL EXT framebuffer object[10] eingefuhrt und in Version 3.0 in den Kern derSpezifikation aufgenommen [7]. Wie der Standard-Framebuffer kann ein Framebuffer-Objekt aus mehreren Speicherbereichen bestehen. Es existieren mehrere sogenannte At-tachment Points, an die eine Textur oder ein Renderbuffer8 angefugt werden kann:

Color Buffer: In diesen Buffer wird die in den Fragment-Shadern berechnete Farbe ge-schrieben. Es konnen auch mehrere benutzt werden, diese Technik nennt sich Mul-tiple Render Targets.

Depth Buffer: Im Tiefenpuffer wird fur jedes Pixel der berechnete Tiefenwert gespei-chert und im Tiefentest benutzt, um verdeckte Oberflachen unabhangig von derZeichenfolge durch im Vordergrund liegende Oberflachen zu verdecken (im Gegen-satz zum Maleralgorithmus[4, S. 104]).

Stencil Buffer: Der Stencilbuffer enthalt fur jeden Pixel einen Integer-Wert und wird inverschiedenen Techniken unterschiedlich verwendet, beispielsweise um im Schattenliegende Bereiche (Shadow Volumes) zu markieren.

8Ein Renderbuffer ist ein Speicherbereich in den zweidimensionale Farb-, Tiefen- oder Stencildatengeschrieben werden konnen. Im Gegensatz zu Texturen konnen Werte in Renderbuffern nicht vonShader-Programmen gelesen werden.

16

Page 25: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3.1 Offscreen Rendering

Depth und Stencil Buffer konnen auch in einem gemeinsamen Speicherbereich angelegtwerden, z. B. als 24 bit Tiefen- und 8 bit Stencilbuffer. Um ein Framebuffer Objekt zubenutzen, mussen die gewunschten Buffer erstellt und angefugt werden. Anschließendlegt man das Framebuffer Objekt mit dessen Color Buffer als aktuellen Schreib- und/oder Lese-Framebuffer fest. [2, S. 278-296]

Listing 12: Erstellung und Benutzung eines Framebuffer Objekts

GLuint framebuffer;

GLuint color_renderbuffer;

GLuint depth_renderbuffer;

GLenum draw_buffers [] = {GL_COLOR_ATTACHMENT0 };

/* Das Framebuffer Objekt wird erstellt und als aktueller

Framebuffer gesetzt. */

glGenFramebuffers (1, &framebuffer);

glBindFramebuffer(GL_FRAMEBUFFER , framebuffer);

/* Der 32bit RGBA Color Buffer wird erstellt. */

glGenRenderbuffers (1, &color_renderbuffer);

glBindRenderbuffer(GL_RENDERBUFFER , color_renderbuffer);

glRenderbufferStorage(GL_RENDERBUFFER , GL_RGBA8 , width , height);

glFramebufferRenderbuffer(GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 ,

GL_RENDERBUFFER , color_renderbuffer);

/* Der 24bit Depth Buffer wird erstellt. */

glGenRenderbuffers (2, &depth_renderbuffer);

glBindRenderbuffer(GL_RENDERBUFFER , depth_renderbuffer);

glRenderbufferStorage(GL_RENDERBUFFER , GL_DEPTH_COMPONENT24 ,

width , height);

glFramebufferRenderbuffer(GL_FRAMEBUFFER , GL_DEPTH_ATTACHMENT ,

GL_RENDERBUFFER , depth_renderbuffer);

/* Der Color Buffer wird als aktueller Zeichen - und Lesepuffer

festgelegt. */

glDrawBuffers (1, draw_buffers);

glReadBuffer(GL_COLOR_ATTACHMENT0);

Alle folgenden OpenGL Zeichenoperationen erfolgen auf dem neu erstellten FBO undnicht auf dem Standard-Framebuffer. Dies ist wichtig, da der Zustand des Standard-Framebuffers beispielsweise fur unsichtbare Fenster in Windows nicht definiert ist.

Um die Bibliothek freizugeben, mussen die erstellten Buffer geloscht, und der aktuelleFramebuffer wieder auf den Standard-Framebuffer zuruckgesetzt werden.

Listing 13: Loschen eines Framebuffer Objekts und der zugehorigen Renderbuffer

/* Den Standard -Framebuffer (0) aktivieren */

glBindFramebuffer(GL_FRAMEBUFFER , 0);

/* Den Framebuffer und die Renderbuffer loeschen */

glDeleteFramebuffers (1, &framebuffer);

glDeleteRenderbuffers (1, &color_renderbuffer);

glDeleteRenderbuffers (1, &depth_renderbuffer);

17

Page 26: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3 Realisierung

Da sich in der Schnittstelle seit der Erweiterung GL EXT framebuffer object fast nichtsgeandert hat, kann dieser Code so ahnlich auch genutzt werden, falls OpenGL 3.0 oderdie Erweiterung GL ARB framebuffer object nicht zur Verfugung stehen. In dem Fallmuss an Funktionsnamen

”EXT“ und an Macros

”EXT“ angehangt werden.[10][11]

3.2 Retained Mode Rendering

Wie zu Beginn von Abschnitt 3 motiviert, muss ein Retained Mode Rendering Systemimplementiert werden, welches unabhangig von der verwendeten OpenGL Version ist. ImFolgenden werden die zwei gangigen, versionsabhangigen Techniken (OpenGL DisplayLists und Vertex Buffer Objekte) und anschließend das implementierte System, welchesdie beiden Techniken erweitert und abstrahiert, vorgestellt.

3.2.1 OpenGL Display Lists

Eine Display List ist eine Folge von OpenGL Funktionsaufrufen, die einmal definiertund anschließend beliebig oft ausgefuhrt werden kann. Die einfache Handhabung derDisplay List ist zwar ein Vorteil, jedoch haben Display Lists in modernen System ofteine niedrigere Performance als Vertex Buffer Objekte, unter anderem dadurch das siedie Benutzung von Immediate Mode Rendering Funktionen erlauben.

Listing 14: Erstellung und Benutzung einer Display List

GLdouble colors [] = {[...]};

GLdouble normals [] = {[...]};

GLdouble vertices [] = {[...]};

GLuint display_list;

/* Die Display List erstellen */

display_list = glGenLists (1);

/* Definition der Liste beginnen */

glNewList(display_list , GL_COMPILE);

/* Ein Dreiecksgitter mit Immediate Mode Funktionen zeichnen */

glBegin(GL_TRIANGLES);

for (i = 0; i < n; i++) { /* Fuer jeden Vertex */

glColor3dv(colors+i*3); /* die Farbe , */

glNormal3dv(normals+i*3); /* den Normalenvektor */

glVertex3dv(vertices+i*3); /* und die Position angeben */

}

glEnd ();

/* Definition der Liste beenden */

glEndList ();

/* Die Liste aufrufen , um das Dreiecksgitter zu zeichnen */

glCallList(display_list);

18

Page 27: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3.2 Retained Mode Rendering

3.2.2 OpenGL Vertex Buffer Objekte

Vertex Buffer Objekte (VBOs) stellen zusammen mit Shadern die Basis des Rendernsim Core Profile dar. Sie sind Speicherbereiche im Grafikkartenspeicher, die Vertexda-ten enthalten. Diese Daten konnen wie bei der Benutzung von Display Lists mit einervon ihrer Anzahl unabhangigen Menge Funktionsaufrufe gezeichnet werden. Durch ver-schiedene Zeichenfunktionen kann dies fur bestimmte Einsatzzwecke optimiert werden.So konnen beispielsweise berechnete Daten aus der Pipeline zum spateren Zeichnen inVertex Buffer Objekte geschrieben werden (Transform Feedback, siehe [4, S. 509]) odermit einem Aufruf mehrere verschiedene Transformationsmatrizen fur dieselben Datenbenutzt werden, um dasselbe Dreiecksgitter an verschiedenen Positionen zu zeichnen(Instanced Rendering, siehe [4, S. 497]).

Listing 15: Erstellung und Benutzung eines Vertex Buffer Object (VBO)

GLdouble colors [] = {[...]};

GLdouble normals [] = {[...]};

GLdouble vertices [] = {[...]};

GLuint vbo;

GLint vertex_location , normal_location , color_location;

unsigned int n, i;

void *mem;

/* Ein VBO anlegen */

glGenBuffers (1, &vbo);

glBindBuffer(GL_ARRAY_BUFFER , vbo);

/* Die Vertexdaten in einen gemeinsamen Speicherbereich

kopieren */

mem = malloc(n*3*3* sizeof(GLfloat));

for (i = 0; i < n; i++) {

GLfloat *data = (( GLfloat *)mem)+i*3*3;

data [0] = vertices[i*3+0];

data [1] = vertices[i*3+1];

data [2] = vertices[i*3+2];

data [3] = normals[i*3+0];

data [4] = normals[i*3+1];

data [5] = normals[i*3+2];

data [6] = colors[i*3+0];

data [7] = colors[i*3+1];

data [8] = colors[i*3+2];

}

/* Die Vertexdaten daraus in den VBO kopieren */

glBufferData(GL_ARRAY_BUFFER , n*3*3* sizeof(GLfloat), mem ,

GL_STATIC_DRAW);

free(mem);

/* OpenGL die Position der Vertexdaten mitteilen */

19

Page 28: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3 Realisierung

vertex_location = glGetAttribLocation(context_struct_.program ,

"in_Vertex");

glVertexAttribPointer(vertex_location , 3,GL_FLOAT , GL_FALSE ,

sizeof(GLfloat)*3*3 ,( GLvoid *)(sizeof(GLfloat)*3*0));

glEnableVertexAttribArray(vertex_location);

normal_location = glGetAttribLocation(context_struct_.program ,

"in_Normal");

glVertexAttribPointer(normal_location , 3,GL_FLOAT , GL_FALSE ,

sizeof(GLfloat)*3*3 ,( GLvoid *)(sizeof(GLfloat)*3*1));

glEnableVertexAttribArray(normal_location);

color_location = glGetAttribLocation(context_struct_.program ,

"in_Color");

glVertexAttribPointer(color_location , 3,GL_FLOAT , GL_FALSE ,

sizeof(GLfloat)*3*3 ,( GLvoid *)(sizeof(GLfloat)*3*2));

glEnableVertexAttribArray(color_location);

/* Mit den n Vertices ein Dreiecksgitter zeichnen */

glDrawArrays(GL_TRIANGLES , 0, n);

3.2.3 Vorstellung des implementierten Systems

Bei der Entwicklung der Bibliothek stellten sich im Zusammenhang mit Retained ModeRendering folgende Probleme, die es zu losen galt:

• Die Gitterdaten und die Daten, die bei jedem Aufruf einer Zeichnen-Funktionmitgegeben werden, mussen verwaltet werden.

• Die Aufrufe der Zeichnen-Funktionen mussen gespeichert und mehrmals ausgefuhrtwerden konnen.

• Der Zugriff auf die Dreiecksgitter sollte unabhangig von den internen Datenstruk-turen sein.

• Das Zeichnen selbst muss fur alte und neue OpenGL-Versionen implementiert sein.

Der Nutzer soll Dreiecksgitter definieren und zeichnen lassen konnen. Dabei werden derBibliothek bei der Erstellung eines Dreiecksgitters und bei jedem Aufruf einer Funktionzum Zeichnen Daten ubergeben. Diese Daten mussen so lange vorgehalten werden, bissichergestellt werden kann, dass sie nicht mehr benotigt werden. Bei den Daten, die einenZeichnen-Aufruf charakterisieren ist dies simpel, da diese Daten geloscht werden konnen,sobald die Szene geloscht wird. Die Daten der Dreiecksgitter werden im Gegensatz dazuvon zwei verschiedenen Stellen benotigt: Der Nutzer konnte jederzeit das Gitter zeichnenlassen und auch nachdem er es geloscht hat, konnte es sich noch in einer Szene befinden.Deshalb muss ein Garbage Collection Algorithmus implementiert werden, der die Datenverwaltet.

Als Verfahren bietet sich hier das einfach implementierbare und deterministische Re-ference Counting an, da keine zyklischen Datenstrukturen vorliegen. Dabei werden die

20

Page 29: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3.3 Erstellung von Grafiken in hoher Auflosung

Daten eines Dreiecksgitters in einer Datenstruktur verwaltet, die zusatzlich einen Refe-renzzahler enthalt.

Um das Zeichnen mehrfach ausfuhrbar zu machen, orientiert sich die Bibliothek andem Prinzip der Display Lists, indem die Funktionen zum Zeichnen nicht tatsachlichzeichnen, sondern ihre Aufrufe fur spatere Verwendung speichern. Kopien der Parameterder Funktion zum Zeichnen eines Dreiecksgitters werden in einer zusammengesetztenDatenstruktur gespeichert, die einen Knoten in einer einfach verketteten Liste bildet.Wann immer eine Grafik generiert werden muss, wird diese Liste durchlaufen und furjeden Knoten wird mit den darin gespeicherten Daten eine bibliotheksinterne Funktionaufgerufen, die das tatsachliche, versionsabhangige Zeichnen ubernimmt.

Da die Bibliothek leicht aus anderen Sprachen benutzbar sein soll und um eine im-plementierungsunabhangige Schnittstelle bieten zu konnen, darf der Nutzer nicht direktdie interne Datenstruktur der Dreiecksgitter benutzen, sondern der Zugriff soll ubereinen Identifizierer ablaufen. Als Datentyp dieses Identifizierers wurde aus Erfahrungmit OpenGL, wo dies ublich ist, eine vorzeichenlose Ganzzahl gewahlt.

Das tatsachliche Zeichnen ist zweimal implementiert: Eine Implementierung nutztDisplay Lists und die Fixed-Function Pipeline, die andere nutzt Vertex Buffer Objekteund Shader. Im Verlauf der Initialisierung wird gepruft, ob VBOs und Shader unterstutztwerden und falls dies der Fall ist, werden Shader-Programme kompiliert und aktiviert,die ein Ergebnis wie die Fixed-Function Pipeline erzeugen. Da das Zeichnen wie in denListings 14 und 15 ablauft, bestehen die Daten fur ein Dreiecksgitter entweder aus demIndentifizierer der Display List oder aus dem Identifizierer des Vertex Buffer Objekts undder Anzahl der zu zeichnenden Vertices.

Listing 16: Datenstruktur fur die Gitterdaten

typedef union _GLORMeshData_ {

unsigned int display_list_id;

struct {

unsigned int id;

unsigned int number_of_vertices;

} vertex_buffer_object;

} GLORMeshData_;

3.3 Erstellung von Grafiken in hoher Auflosung

In sehr hohen Auflosungen konnen Grafiken nicht mehr direkt auf der Grafikkarte erzeugtwerden, da die unkomprimierten Bilddaten zu viel Speicher benotigen wurden9. Um dieseLimitierung zu umgehen und Grafiken zu erzeugen, deren Auflosung nur noch durchden verfugbaren Hauptspeicher begrenzt ist, wird das Gesamtbild in Teilbilder zerlegt.Diese werden mit OpenGL im Grafikspeicher erzeugt und anschließend im Hauptspeicherzusammengesetzt.

9Eine Grafik mit 16384x8192 Pixeln wurde mit 32 bit Farbtiefe und einem 24 bit Depth Buffer 896 MiBzusammenhangenden Speichern benotigen.

21

Page 30: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3 Realisierung

Damit die Teilbilder erzeugt werden, wird eine alternative Viewport-Transformation be-nutzt, welche die projizierten Vertex-Koordinaten nicht auf die Große des Framebuffers,sondern auf die Große des Gesamtbildes skaliert und so verschiebt, dass nur ein be-stimmtes Teilbild auf den Framebuffer abgelegt wird.

Abbildung 5: Verschiedenen Koordinatensysteme in der Pipeline (v.l.n.r.): Eye Coordi-nates, Normalized Device Coordinates, Window Coordinates vor und nachdem Clipping [12]

Die Viewport-Transformation ist eine affine Transformation aus dem System der nor-malisierten Geratekoordinaten, in dem alle Komponenten der darzustellenden Verti-ces im Interval [−1; 1] liegen, in das sogenannte Fensterkoordinatensystem (in Abbil-dung 5 bildet sie den 2. Ubergang). In Matrix-Schreibweise (ohne Berucksichtigung derz-Komponente) gilt: xwindow

ywindow

1

=

12widthvp 0 1

2widthvp + xvp

0 12heightvp

12heightvp + yvp

0 0 1

·

xnorm

ynorm

1

Hier werden nun nicht die Framebuffer-Dimensionen benutzt, sondern die Breite undHohe des Gesamtbildes und die Position des Teilbildes. Fur das Teilbild in der i-tenZeile und der j-ten Spalte gilt daher:

xvp

yvp

widthvp

heightvp

=

−j · widthframebuffer

−i · heightframebuffer

widthimage

heightimage

22

Page 31: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

3.3 Erstellung von Grafiken in hoher Auflosung

In der Rasterisierung werden alle Fragmente, die nicht zu dem gewunschten Teilbildgehoren und fur die daher kein Speicher zur Verfugung steht, verworfen. Nach jedemRendern wird es vom Speicher des Framebuffers (das blaue Rechteck in Abbildung 5 aufder vorherigen Seite) an die passende Stelle im Hauptspeicher kopiert. Beim Kopierenmuss zwischen jeder Zeile des Teilbildes genug Freiraum fur den Rest einer Zeile desGesamtbildes gelassen werden (widthskip = widthimage − widthframebuffer). Nach diesemPrinzip werden der Reihe nach alle Teilbilder gerendert und in das Gesamtbild kopiert.

Abbildung 6: Eine 5x3 Pixel große Grafik als rechteckiges Bild und als Pixel in linearemSpeicher. Ein einzelnes 2x2 Pixel großes Teilbild ist blau und eine Zeilekhaki markiert. (1) widthimage (2) widthframebuffer (3) widthskip

Dieses Vorgehen fuhrt dazu, dass fur jedes Teilbild alle Vertices neu transformiert wer-den mussen. Daher ist die Auflosung der Teilbilder, beziehungsweise des Framebuffers,entscheidend fur die Geschwindigkeit des Renderns. Sie kann beim Initialisieren der Bi-bliothek angegeben werden.

23

Page 32: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

4 Ergebnisse

4 Ergebnisse

Die Bibliothek ist fertiggestellt und erfullt ihren Zweck. Durch die gezielte Kombinationplattformabhangiger Techniken konnte ein plattformunabhangiges, einheitliches Werk-zeug zur fensterlosen Erzeugung von hochauflosenden 3D-Grafiken geschaffen werden.Einfache Grafiken, wie Kristall- oder Molekulstrukturen, konnen durch Hilfsfunktionenschnell und ohne großen Aufwand erzeugt werden. Durch eine wahrend der Implemen-tierung der Bibliothek entwickelte Python-Anbindung wurde verifiziert, dass die Anfor-derung einer moglichst sprachunabhangigen Schnittstelle erfullt sind.

Abbildung 7: Eine mit der Bibliothek erzeugte Grafik (H2O)

4.1 Benutzung der API

Wenn man die Bibliothek in einem Programm nutzen mochte, geht man entsprechenddes Flussdiagrammes in Abbildung 8 vor. Eine sehr simple Anwendung, die nur pruftob die Bibliothek auf dem System lauft, sieht folgendermaßen aus:

Listing 17: Renderpath String ausgeben

#include <stdio.h>

#include "GLor.h"

int main(void) {

GLORInitAttribute init_attrs [] =

{kGLORIAEndOfAttributeList };

/* Initialisierung */

glorInit(init_attrs);

/* Informationen ueber das Rendering ausgeben */

printf("GLor Renderpath String: %s\n",

glorGetRenderpathString ());

/* Freigabe */

glorTerminate ();

return 0;

}

24

Page 33: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

4.1 Benutzung der API

Abbildung 8: Die Nutzung der Bibliothek GLor in einem Programm

25

Page 34: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

4 Ergebnisse

Dieses Programm gibt auf dem Entwicklungssystem z. B. folgenden Text aus:

GLor Renderpath String: GLor - CGL - GL_ARB_framebuffer_object

- Vertex Buffer Objects - 2.1 ATI -7.12.9 - ATI Radeon HD 2400

OpenGL Engine

Schreibt man dieses Programm in Python, darf die leere Attributenliste weggelassenwerden – sie wird von der Anbindung erganzt – der Rest ist identisch.

Listing 18: Das Programm aus Listing 17 in Python

from GLor import *

glorInit ()

print "GLor Renderpath string:", glorGetRenderpathString ()

glorTerminate ()

Das folgende Python-Beispiel zeigt die Verwendung der Hilfsfunktionen zum Zeichnenvon Kugeln und Zylindern, die Kamerafunktionen und die Erstellung von Grafiken.

Listing 19: Ein Wurfel aus Kugeln und Zylindern (Python)

from GLor import *

# Die Bibliothek wird initialisiert.

glorInit ()

# Man kann entweder ein Gitter pro Aufruf zeichnen ...

glorDrawSphereMesh (1, [0,0,0], [1,1,1], [0.11])

glorDrawSphereMesh (1, [0,0,1], [1,1,1], [0.11])

glorDrawSphereMesh (1, [0,1,0], [1,1,1], [0.11])

glorDrawSphereMesh (1, [0,1,1], [1,1,1], [0.11])

glorDrawSphereMesh (1, [1,0,0], [1,1,1], [0.11])

glorDrawSphereMesh (1, [1,0,1], [1,1,1], [0.11])

glorDrawSphereMesh (1, [1,1,0], [1,1,1], [0.11])

glorDrawSphereMesh (1, [1,1,1], [1,1,1], [0.11])

# ... oder die Daten in Listen , bzw. Arrays , sammeln und das

selbe Gitter mehrmals mit verschiedenen Eigenschaften

zeichnen.

cylinder_positions = [[0,0,0], [0,0,0], [0,0,0], [0,0,1],

[0,0,1], [1,1,0], [1,0,0], [1,0,1], [1,0,0], [0,1,0],

[0,1,0], [0,1,1]]

cylinder_directions = [[1,0,0], [0,1,0], [0,0,1], [1,0,0],

[0,1,0], [0,0,1], [0,1,0], [0,1,0], [0,0,1], [0,0,1],

[1,0,0], [1,0,0]]

cylinder_colors = [[1,0,0], [0,1,0], [0,0,1], [1,0,0], [0,1,0],

[0,0,1], [0,1,0], [0,1,0], [0,0,1], [0,0,1], [1,0,0], [1,0,0]]

cylinder_radii = [0.1]*12

cylinder_lengths = [1]*12

26

Page 35: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

4.1 Benutzung der API

glorDrawCylinderMesh (12, cylinder_positions ,

cylinder_directions , cylinder_colors , cylinder_radii ,

cylinder_lengths)

# Die Kamera wird eingestellt indem man den vertikalen

Sichtwinkel und die Distanzen zu naher und ferner

Clipping -Ebene angibt. Ihre Position und Ausrichtung gibt man

in Form von drei Vektoren an: Position , Zentrum des Fokus und

Richtung , welche oben sein soll.

glorCameraProjectionParameters (45 ,1 ,200)

glorCameraLookAt (3, 1.9, 1.9, 0.5, 0.5, 0.5, 0, 0, 1);

# Eine 2048 x2048 Pixel Bitmap wird ausgelesen.

bitmap = glorGetBitmap (2048 ,2048)

# Die Szene wird geloescht.

glorClear ()

# Die Bibliothek wird freigegeben.

glorTerminate ()

# Die Bitmap wird mit der Python Image Library als png -Datei

gespeichert

import Image

img =

Image.frombuffer("RGBA" ,(2048 ,2048),bitmap ,"raw","RGBA" ,0,0)

img.save("example.png","PNG")

Abbildung 9: Der mit dem Programm erzeugte Wurfel

27

Page 36: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

4 Ergebnisse

Der folgende Ausschnitt aus einem Beispielprogramm zeigt, wie man mit den Meshesumgeht.

Listing 20: Umgang mit Meshes

/* GLORMesh ist ein typedef auf unsigned int */

GLORMesh mesh;

/* Mit den Daten des Dreiecksgitters wird das Mesh erstellt. */

glorCreateMesh (&mesh , number_of_vertices , vertices , normals ,

colors)

/* Danach kann man es durch die Funktion glorDrawMesh ()

zeichnen lassen. */

glorDrawMesh(mesh , 1, position , forward , up , color , scales)

/* Auch wenn man das Mesh jetzt schon l"oscht , bleibt es durch

das Reference Counting erhalten , bis die Bibliothek es intern

auch nichtmehr verwendet. */

glorDeleteMesh(mesh)

Das nun folgendende Beispiel ist ein einfaches Anzeigeprogramm fur Molekule im xyz-Dateiformat. Es liest die Atompositionen aus, berechnet Atombindungen und stellt diesemit GLor als ball-and-stick-Modell dar.

Listing 21: Ein XYZ-Anzeigeprogramm (Python)

import sys , numpy , numpy.linalg

from itertools import combinations

import Image

from GLor import *

import atoms # Informationen ueber Elemente

if not len(sys.argv) == 2:

print "Usage: python example16.py <filename >"

sys.exit()

atom_data = []

with open(sys.argv [1]) as xyzfile:

for line in xyzfile.readlines () [3:]:

if len(line.split()) >= 4:

o, x, y, z = line.split()[:4]

atom_data.append ((o.upper (),

numpy.array ((x,y,z),float)))

# Atome als Kugeln ...

sphere_positions = []

sphere_colors = []

28

Page 37: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

4.1 Benutzung der API

sphere_radii = []

for o, pos in atom_data:

sphere_positions.append(pos)

sphere_colors.append(atoms.atom_color_dict[o])

sphere_radii.append (0.2)

# ... und Atombindungen als Zylinder darstellen

cylinder_positions = []

cylinder_directions = []

cylinder_lengths = []

cylinder_colors = []

cylinder_radii = []

for pos1 , pos2 in combinations(sphere_positions ,2):

dist = numpy.linalg.norm(pos2 -pos1)

if dist < 2.2: # delta -Kriterium

cylinder_positions.append(pos1)

cylinder_directions.append(pos2 -pos1)

cylinder_lengths.append(dist /2)

cylinder_colors.append ((0.55 ,0.55 ,0.55))

cylinder_radii.append (0.05)

# GLor mit einem 1024 x1024 Framebuffer initialisieren

glorInit ([ GLORInitAttribute.kGLORIAFramebufferWidth , 1024,

GLORInitAttribute.kGLORIAFramebufferHeight , 1024])

# Atome zeichnen

glorDrawSphereMesh(len(atom_data), sphere_positions ,

sphere_colors , sphere_radii)

# Atombindungen zeichnen

glorDrawCylinderMesh(len(cylinder_positions),

cylinder_positions , cylinder_directions , cylinder_colors ,

cylinder_radii , cylinder_lengths)

# Kamera einstellen

glorCameraProjectionParameters (45, 1, 200)

glorCameraLookAt (0, 10, 1, 0, 0, 0, 0, 0, 1)

# Bild erzeugen

width , height = 2048, 2048

bitmap = glorGetBitmap(width , height)

# GLor beenden

glorTerminate ()

29

Page 38: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

4 Ergebnisse

# Bild speichern

img = Image.frombuffer("RGBA", (width , height), bitmap , "raw",

"RGBA", 0, 0)

img.save("out.png", "PNG")

Abbildung 10: Ein mit GLor visualisiertes Buckminster-Fulleren (C60)

30

Page 39: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

5 Ausblick

Die im Rahmen dieser Seminararbeit entwickelte Bibliothek benutzt ein einfaches Be-leuchtungsmodell, mit einer einzelnen, rein diffusen Lichtquelle. Dies ist fur viele Anwen-dungen ausreichend, Glanzlichter konnen allerdings den optischen Eindruck in manchenSzenen deutlich verbessern. Eine mogliche Erweiterung der Bibliothek konnte, neben demmomentan implementierten Beleuchtungsmodell, Funktionen zur Auswahl und Kontrollealternativer Beleuchtungsmodelle einfuhren.

Momentan beinhaltet die Bibliothek keine Unterstutzung fur Kantenglattung (An-tialiasing), doch diese erhoht die Qualitat der erzeugten Bilder haufig deutlich. Daherist es momentan sinnvoll, Grafiken in einem Vielfachen der benotigten Auflosung, z. B.doppelte Breite und doppelte Hohe, zu erzeugen und sie anschließend von einem anderenProgramm auf die gewunschte Auflosung herunterrechnen zu lassen (Supersampling An-tialiasing). Diese Technik konnte als Funktion glorGetAntialiasedBitmap(width, height,factor) o. a. in die Bibliothek integriert werden.

In vielen Fallen sollen Grafiken beschriftet, Koordinatensysteme gezeichnet oder Ras-tergrafiken eingebunden werden. Die Bibliothek ist so konzipiert, dass sie in 2D-Grafik-systeme integiert werden kann. Die Kombination von 2D- und 3D-Grafiken in einemGrafikframework, beispielsweise als Erweiterung des grafischen Kernsystem (GKS), oderals Erweiterung einer im Hause entwickelten Grafikbibliothek (GR), konnte im Rahmeneiner Bachelorarbeit realisiert werden.

31

Page 40: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre
Page 41: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

Listings

Listings

1 Erstellung eines OpenGL Context mit CGL . . . . . . . . . . . . . . . . . 112 Freigabe eines OpenGL Context mit CGL . . . . . . . . . . . . . . . . . . 123 Erstellung eines Pixel Buffers mit GLX . . . . . . . . . . . . . . . . . . . 124 Erstellung einer X Pixmap mit GLX . . . . . . . . . . . . . . . . . . . . 135 Erstellung eines OpenGL Context mit GLX . . . . . . . . . . . . . . . . . 136 Freigabe eines OpenGL Context mit GLX . . . . . . . . . . . . . . . . . . 147 Registrierung einer Fensterklasse in der Windows API . . . . . . . . . . . 148 Erstellung eines Fensters in der Windows API . . . . . . . . . . . . . . . 159 Erstellung eines OpenGL Context mit WGL . . . . . . . . . . . . . . . . 1510 Abfragen eines Funktionszeigers mit WGL . . . . . . . . . . . . . . . . . 1611 Freigabe eines OpenGL Context mit WGL . . . . . . . . . . . . . . . . . 1612 Erstellung und Benutzung eines Framebuffer Objekts . . . . . . . . . . . 1713 Loschen eines Framebuffer Objekts und der zugehorigen Renderbuffer . . 1714 Erstellung und Benutzung einer Display List . . . . . . . . . . . . . . . . 1815 Erstellung und Benutzung eines Vertex Buffer Object (VBO) . . . . . . . 1916 Datenstruktur fur die Gitterdaten . . . . . . . . . . . . . . . . . . . . . . 2117 Renderpath String ausgeben . . . . . . . . . . . . . . . . . . . . . . . . . 2418 Das Programm aus Listing 17 in Python . . . . . . . . . . . . . . . . . . 2619 Ein Wurfel aus Kugeln und Zylindern (Python) . . . . . . . . . . . . . . 2620 Umgang mit Meshes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2821 Ein XYZ-Anzeigeprogramm (Python) . . . . . . . . . . . . . . . . . . . . 28

Abbildungsverzeichnis

1 Die Legacy OpenGL Pipeline . . . . . . . . . . . . . . . . . . . . . . . . 52 Die OpenGL Core Profile Pipeline . . . . . . . . . . . . . . . . . . . . . . 73 Schichtendiagramm: Anwendung – GLor – OpenGL/CGL/GLX/WGL . . 84 Ein Entwurf des Nutzungsschemas der Bibliothek . . . . . . . . . . . . . 95 Verschiedenen Koordinatensysteme in der Pipeline . . . . . . . . . . . . . 226 Eine Grafik als rechteckiges Bild und als Pixel in linearem Speicher . . . 237 Eine mit der Bibliothek erzeugte Grafik (H2O) . . . . . . . . . . . . . . . 248 Die Nutzung der Bibliothek GLor in einem Programm . . . . . . . . . . . 259 Der mit dem Programm erzeugte Wurfel . . . . . . . . . . . . . . . . . . 2710 Ein mit GLor visualisiertes Buckminster-Fulleren (C60) . . . . . . . . . . 30

33

Page 42: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

Literatur

Literatur

[1] Mark Segal, Kurt Akeley, The OpenGL R©Graphics System: A Specification,Version 3.3 (Core Profile) - March 11, 2010http://www.opengl.org/registry/doc/glspec33.core.20100311.pdf

(Zugriff: 14. November 2011)

[2] Mark Segal, Kurt Akeley, The OpenGL R©Graphics System: A Specification,Version 3.0 - September 23, 2008http://www.opengl.org/registry/doc/glspec30.20080923.pdf

(Zugriff: 18. November 2011)

[3] Dave Shreiner, OpenGL Programming Guide, Seventh EditionAddison-Wesley, 2010, ISBN-13: 978-0-321-55262-8

[4] Richard S. Wright, Jr. et al., OpenGL Superbible, Fifth EditionAddison-Wesley, 2010, ISBN-13: 978-0-321-71261-5

[5] GLSL Core Tutorial – Pipeline (3.3)http://www.lighthouse3d.com/tutorials/glsl-core-tutorial/pipeline33/

(Zugriff: 14. November 2011)

[6] Vertex Buffer Objectshttp://www.opengl.org/wiki_132/index.php?title=Vertex_Buffer_

Object&oldid=4070

(Zugriff: 15. November 2011)

[7] Framebuffer Objectshttp://www.opengl.org/wiki_132/index.php?title=Framebuffer_

Object&oldid=3978

(Zugriff: 18. November 2011)

[8] GL ARB shader objectshttp://www.opengl.org/registry/specs/ARB/shader_objects.txt

(Zugriff 15. November 2011)

[9] GL ARB vertex buffer objecthttp://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt

(Zugriff 15. November 2011)

[10] GL EXT framebuffer objecthttp://www.opengl.org/registry/specs/EXT/framebuffer_object.txt

(Zugriff 18. November 2011)

[11] GL ARB framebuffer objecthttp://www.opengl.org/registry/specs/ARB/framebuffer_object.txt

(Zugriff 18. November 2011)

34

Page 43: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

Literatur

[12] OpenGL FAQ and Troubleshooting Guide - 9 Transformations, v1.2001.11.01http://www.opengl.org/resources/faq/technical/transformations.htm

(Zugriff: 11. November 2011)

[13] OpenGL R©Graphics with the X Window System R©, (Version 1.4)http://www.opengl.org/documentation/specs/glx/glx1.4.pdf

(Zugriff: 15. November 2011)

[14] OpenGL Programming Guide for Mac OS X – Introductionhttp://developer.apple.com/library/mac/#documentation/

graphicsimaging/conceptual/OpenGL-

MacProgGuide/opengl_intro/opengl_intro.html

(Zugriff: 15. November 2011)

[15] OpenGL Programming Guide for Mac OS X – Drawing Offscreenhttp://developer.apple.com/library/mac/#documentation/

graphicsimaging/conceptual/OpenGL-

MacProgGuide/opengl_offscreen/opengl_offscreen.html

(Zugriff: 16. November 2011)

[16] OpenGL Capabilities Tableshttp://developer.apple.com/graphicsimaging/opengl/capabilities/

(Zugriff: 15. November 2011)

[17] MSDN - wglCreateContexthttp://msdn.microsoft.com/en-us/library/dd374379(v=VS.85).aspx

(Zugriff: 15. November 2011)

[18] MSDN - X Program ported to Windowshttp://msdn.microsoft.com/en-us/library/dd369065(v=vs.85).aspx

(Zugriff: 25. November 2011)

[19] Mark J. Kilgard, The OpenGL Utility Toolkit (GLUT) Programming Interface,API Version 3http://www.opengl.org/resources/libraries/glut/glut-3.spec.ps

(Zugriff: 15. November 2011)

[20] Mesa Introductionhttp://www.mesa3d.org/intro.html

(Zugriff: 15. November 2011)

35

Page 44: Integration OpenGL-basierter Visualisierungs-Techniken in ... · naler Geometrie. Die Geometrie wird dabei durch ihre Eckpunkte, die Vertices, und deren Eigenschaften, wie z.B. ihre

Literatur

36