Open Source im professionellen Einsatz
Linux-Magazin 10/2006
© photocase.com

© photocase.com

Ob Bühnenbild oder 3D-Modell, erst Anstrich und Licht sorgen für die perfekte Illusion

Im Rampenlicht

Ein überzeugendes Bühnenbild sorgt für die passende Atmosphäre im Theater. Auch am Computer machen Anstrich und Beleuchtung die Illusion von 3D-Modellen perfekt. Selbst einfache Skripte zaubern dank OpenGL mit Hilfe von Bitmaps und Beleuchtung Überraschendes auf den Schirm.

973

Wie ein geometrisches 3D-Modell mit ein paar Farben auf den Schirm kommt, hat kürzlich ein Artikel [1] zu Tcl3D [2] beschrieben. Doch OpenGL kann bedeutend mehr. Um bei Flugzeugen oder Menschen alle Details wie Augen, Bekleidung oder Beschriftung nachzubilden, wären Millionen von Dreiecken notwendig. Viel einfacher ist es, auf eine grobe Form ansprechende Bitmaps wie ein Abziehbild zu kleben. Bei 3D-Modellen heißt dieses Verfahren Textur. Aktuelle Grafikkarten unterstützen es durch riesige Speicher für Texturen.

Fürs letzte Finish des virtuellen Bühnenbilds sorgt die Beleuchtung. Das Standardlicht aus OpenGL hat den abstoßenden Charme von Neonlicht - doch es gibt angenehmere Lichtquellen, deren Verhalten der Bühnenbauer bis ins Feinste beschreiben darf.

Die hier gezeigten Beispiele setzen auf denen im ersten Artikel auf [1], daher sind die Geometrien und Ansichten bereits definiert. Die gedruckten Listings enthalten den jeweils relevanten Ausschnitt; der komplette Code steht wie immer auf dem FTP-Server des Linux-Magazins [3]. Die Skripte sind wieder für Paul Obermeiers Tcl-Erweiterung Tcl3D [2] geschrieben. Die Beispiele lassen sich aber auch gut auf OpenGL unter C oder Java anwenden, da die Befehle überall den gleichen Namen tragen.

Abziehbild

3D-Modelle bestehen meist aus Dreiecken, die sind simpel und schnell zu erzeugen. Selbst einfache Modelle mit wenigen Dreiecken können realistisch aussehen, wenn sie eine passende Textur erhalten (Abbildungen 1a bis 1c). Damit OpenGL die Bitmaps passend auf die Geometrie montiert, benötigt es jedoch genaue Anweisungen, wohin welche Stelle des Abziehbildes gehört.

Abbildung 1a: Am Anfang steht ein Netz aus Dreiecken, die ein kugelförmiges Modell bilden.

Abbildung 1b: Eine Hülle lässt Objekte wie eine Kugel erscheinen und verdeckt die unsichtbaren Kanten.

Abbildung 1c: Eine passende Textur gibt dem Oberflächennetz das Aussehen eines Steins.

Dabei treffen zwei Welten aufeinander: das dreidimensionale X-Y-Z-Koordinatensystem des Dreiecks und das zweidimensionale S-T-Koordinatensystem der Textur. Der Befehl »glTexCoord2f« sagt OpenGL, welche Stelle der Textur (S, T) auf den nächsten definierten Geometriepunkt (X, Y, Z) kommt. Abbildung 2 zeigt das Verfahren mit drei Dreiecken und einer kleinen Bitmap.

Abbildung 2: Die OpenGL-Funktion »glTexCoord2f« bildet die Bitmap auf die Geometrie ab. Dabei legt der Programmierer fest, welcher Punkt des Bildes wo auf der Oberfläche landet.

Das abgedruckte Listing 1 zeigt die wesentlichen Ausschnitte des kompletten Quelltextes [3]. Das Hauptprogramm setzt die Funktion »tclCreateFunc« als »-createproc« ins OpenGL-Widget ein. Damit ruft die Library diese Funktion auf, um den Inhalt des Widget zu erzeugen. Die Funktion lädt die Texturen und erzeugt die Geometrie.

Listing 1: Texturen

01 # Wird ein Mal aufgerufen
02 proc tclCreateFunc {toglwin} {
03   # ein paar Einstellungen
04   glEnable GL_TEXTURE_2D
05   glEnable GL_DEPTH_TEST
06   glPolygonMode GL_FRONT_AND_BACK GL_FILL
07 
08   # Bild in Tcl laden
09   if [catch {image create photo -file "worked_stone_8180226.JPG"} phImg] {
10     error "Fehler beim Laden: $phImg"
11   }
12 
13   # OpenGL-Vektor mit Bitmap aus Tcl-Image erzeugen
14   set w [image width     $phImg]
15   set h [image height    $phImg]
16   set n [tcl3dPhotoChans $phImg]
17   set pTextureImage [tcl3dVector GLubyte [expr {$w * $h * $n}]]
18   tcl3dPhoto2Vector $phImg $pTextureImage
19   image delete $phImg ;# Bild aus Tcl löschen
20 
21   # Interpolation angeben
22   glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER $::GL_LINEAR
23   glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER $::GL_LINEAR
24 
25   # Textur aus OpenGL-Vektor mit Bitmap erzeugen
26   set ::g_textureID [tcl3dVector GLuint 1]
27   glGenTextures 1 $::g_textureID
28   glBindTexture GL_TEXTURE_2D [$::g_textureID get 0]
29 
30   if {$n == 3} {set type $::GL_RGB
31   } else {      set type $::GL_RGBA}
32   glTexImage2D GL_TEXTURE_2D 0 $n $w $h 0 $type GL_UNSIGNED_BYTE $pTextureImage
33 
34   # OpenGL-Vektor mit Bitmap löschen
35   $pTextureImage delete
36 
37   # Display-Liste erzeugen...
38   set ::g_sphereDList [glGenLists 1]
39   glNewList $::g_sphereDList GL_COMPILE
40   # ...und mit Geometrie und Textur füllen
41   renderSphere 0.0 0.0 0.0 1.5 $::aufloesung
42   glEndList
43 }
44 
45 # Kugel aus Dreiecken mit Textur erzeugen
46 proc renderSphere {r p} {
47   [...]
48   # Normalenvektor berechnen
49   set normalX [expr {cos($theta2) * cos($theta3)}]
50   set normalY [expr {sin($theta2)}]
51   set normalZ [expr {cos($theta2) * sin($theta3)}]
52   glNormal3f $normalX $normalY $normalZ
53 
54   # Einfache Zylinderprojektion der Textur
55   glTexCoord2f [expr {-1.0 * ($j/double($p))}] 
56                [expr { 2.0 * ($i+1)/double($p)}]
57 
58   # Position der Knotenpunkte berechnen
59   set posX [expr {$r * $normalX}]
60   set posY [expr {$r * $normalY}]
61   set posZ [expr {$r * $normalZ}]
62   glVertex3f $posX $posY $posZ
63   [...]
64 }

Bitmaps für Texturen liegen üblicherweise auf der Festplatte, insbesondere für realistische Darstellungen sind es meist Fotos der gewünschten Oberflächen. Solche Texturen finden sich zum Beispiel bei Mayang [4] oder speziell für Holz bei [5]. Als Textur eignet sich eine beliebige Bitmap, allerdings sollte die Kantenlänge eine Potenz von 2 sein, zum Beispiel 256 mal 512. Damit es an den Kanten zu keinen sichtbaren Stößen kommt, kann ein Gimp-Filter die Bilder in nahtlose Muster verwandeln (»Filter | Abbilden | Nahtlos machen«).

Auf Umwegen

Es gibt leider keine Funktion, die Bitmaps direkt von der Festplatte in OpenGL lädt. Daher sind drei Schritte nötig. Zuerst holt das Skript, wie bei Tk üblich, die Bitmaps mit »image create photo -file Dateiname«. Gewöhnlich laden Tk-Programme damit Bitmaps für Buttons. Die If-catch-Konstruktion in den Zeilen 9 bis 11 sorgt für eine Fehlermeldung, falls das Skript die Datei nicht laden kann.

Danach wandert die Bitmap aus Tk zu OpenGL. Hierfür hat Tcl3D bequemerweise eine Funktion, die Tk-Images in einen OpenGL-Vektor lädt. Zuerst erzeugt in Zeile 17 »tcl3dVector« einen Vektor, seine Größe bestimmt sich aus Länge und Breite des Image multipliziert mit der Anzahl der Kanäle. Normale Bilder haben je einen Kanal für Rot, Grün und Blau, einige noch einen weiteren für die Transparenz. Die Funktion »tcl3dPhoto2Vector« kopiert in Zeile 18 den Bildinhalt in den Vektor. Nun liegt das Bild doppelt vor, als OpenGL-Vektor und als Tk-Bild. Letzteres löscht Zeile 19, um Speicher zu sparen.

Klar ist, dass OpenGL die Bitmap in den meisten Fällen verzerrt, um sie auf die Geometrie zu legen. Dazu interpoliert es die Zwischenpunkte, der Befehl »glTexParameteri« sorgt in den Zeilen 22 und 23 für eine einfache lineare Interpolation. Als Nächstes erzeugt »glBindTexture« aus dem vorhandenen Vektor ein Texturobjekt (Zeile 28).

Diesen Artikel als PDF kaufen

Express-Kauf als PDF

Umfang: 4,5 Heftseiten

Preis € 0,99
(inkl. 19% MwSt.)

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Virtueller Bühnenbildner

    Ob Bildschirmschoner, CAD-System oder Flugsimulator - Programme mit dreidimensionalen Effekten sind auf den meisten Computern zu finden, aber schwer zu schreiben. Ein neues Projekt macht Letzteres leichter und öffnet Skript-Programmierern den Vorhang für 3D-Effekte in ihrer Software.

  • Glänzende Effekte

    Für die gängigen Computerspiele führen moderne Grafikkarten viele Berechnungen selbstständig aus und rendern 3D-Szenen in akzeptabler Qualität. Eine realistischere Darstellung schaffen Shader-Programme, die auf dem Grafikchip laufen und unter Linux in der Hochsprache Cg programmiert wurden.

  • Schattenspiele

    Programmierbare Grafikchips sind nichts Neues, doch inzwischen berechnen sie mit Shadern auch Lichteffekte. Mit der OpenGL Shading Language erledigt das nach Cg und HLSL nun auch eine freie Hochsprache.

  • Bewegte Objekte

    Auch hochfliegende Ideen lassen sich mit Coin und wenigen Zeilen C++ schnell umsetzen: Aus einfachen Objekten mit Texturen und komplexen VRML-Modellen entsteht eine animierte 3D-Welt.

  • SDL 2.0

    Nach mehreren Jahren Entwicklungsarbeit ist im August die modernisierte Version 2.0 der Bibliothek SDL erschienen. Trotz der zahlreichen Neuerungen fällt der Um- und Einstieg erstaunlich leicht.

comments powered by Disqus

Ausgabe 01/2017

Digitale Ausgabe: Preis € 6,40
(inkl. 19% MwSt.)

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.