11 Farbe
11.010 Die Farben meiner Textur (z.B. blau und rot, gelb und cyan) werden vertauscht. Warum ?
Das kann passieren, wenn die Textur die RGB-Werte in umgekehrter Reihenfolge enthält.
Eine Lösung ist, die einzelnen Bytes nach dem Einlesen, also noch vor Übergabe
an die OpenGL, umzutauschen.
Mit OpenGL 1.2 ist es auch möglich, das Parameterformat als GL_BGR oder GL_BGRA
beim Aufruf von glDrawPixels(), glGetTexImage(), glReadPixels(), glTexImage1D(), glTexImage2D()
oder glTexImage3D() anzugeben. In vorhergehenden Versionen ist diese Option eventuell
als Extension (GL_BGR_EXT, GL_BGRA_EXT) verfügbar.
11.020 Wie kann ich ein Bild mit Color-Index in einem RGB-Fenster zeichnen ? Geht es auch umgekehrt ?
Es gibt keinen direkten Weg, um das zu realisieren. Es kann allerdings gehen, dass man
ein RGB-Fenster um eine Color-Index Overlay Plane ergänzt. Ob das möglich ist,
hängt aber vom Programm und dem genutzten System ab.
Falls es um ein Feld von Color-Indizes geht, dass als Textur genutzt werden soll,
kann man eventuell auch die Extension GL_EXT_paletted_texture nutzen, die diese Möglichkeit
vorsieht.
11.030 Die Farben scheinen unter MS Windows fast völlig zu verschwinden. Warum passiert das ?
Die wahrscheinlichste Ursache ist eine (unzureichende) Farbtiefe des Desktops von
256 Farben. Um die Eigenschaften der Anzeige auf 16K oder 32K Farbtiefe zu
ändern, kann man z.B. mit der rechten Maustaste auf den Desktop klicken und dann
Eigenschaften, Einstellungen wählen.
11.040 Wie kann ich eine exakte Farbe für ein Primitive festlegen ?
Dafür muss man wissen, welche Farbtiefe der aktuelle Colorbuffer beinhaltet.
Für einen RGB-Buffer kann man dazu folgenden Code nutzen:
GLint redBits, greenBits, blueBits;
glGetIntegerv (GL_RED_BITS, &redBits);
glGetIntegerv (GL_GREEN_BITS, &greenBits);
glGetIntegerv (GL_BLUE_BITS, &blueBits);
Ist die Farbtiefe jeder Komponente mindestens so gross wie für die gewünschte
Festlegung erforderlich, kann der Farbwert auch genutzt werden.
Die Farbe sollte man nur mit den signifikanten Ziffern der Komponenten als Integer
an glColor3ui() übergeben.
Ist der Color Buffer nicht präzise genug, um den gewünschten Farbwert darzustellen,
muss man eine Ausweichlösung in Betracht ziehen. Der Verzicht auf die am
wenigsten signifikanten Ziffern jeder Komponente ist z.B. akteptabel. Für
Integer-Werte werden diese gestutzten Komponenten an glColor3ui() übergeben.
In jedem Fall muss jede andere Statusvariable deaktiviert werden, die einen
Einfluss auf den berechneten Farbwert haben kann. Der folgende Code zeigt, wie:
glDisable (GL_BLEND);
glDisable (GL_DITHER);
glDisable (GL_FOG);
glDisable (GL_LIGHTING);
glDisable (GL_TEXTURE_1D);
glDisable (GL_TEXTURE_2D);
glDisable (GL_TEXTURE_3D);
glShadeModel (GL_FLAT);
11.050 Wie kann ich jedem Primitive meiner Szene eine jeweils andere Farbe zuordnen ?
Dazu muss man die maximale Farbtiefe jeder Komponente des RGB-Buffers kennen.
Wie das geht, wurde in der vorhergehenden Frage beantwortet.
Aus der Farbtiefe erhält man die Anzahl der überhaupt möglichen Farben.
Hat man die Farbtiefe mit glGetIntegerv() für RGB ermittelt, ergibt sich die
Anzahl der Variationen zu 2(redBits+greenBits+blueBits).
Ist diese Zahl grösser als die Anzahl der vorhandenen Primitive, ist die
Frage prinzipiell beantwortet. Man übergibt den gewählten Farbwert dann
mittels glColor3u*() an die OpenGL.
Der folgende Code zeigt ein Beispiel:
/* numPrims ist die Anzahl der darzustellenden Primitive
void renderPrimitive(unsigned long) zeichnet das Primitive (Index als Parameter)
GLuint makeMask (GLint) gibt eine Bitmaske für die Anzahl der übergebenen Bits zurück
*/
GLuint redMask = makeMask(redBits) << (greenBits + blueBits);
GLuint greenMask = makeMask(greenBits) << blueBits;
GLuint blueMask = makeMask(blueBits);
int redShift = 32 - (redBits+greenBits+blueBits);
int greenShift = 32 - (greenBits+blueBits);
int blueShift = 32 - blueBits;
unsigned long indx;
for (indx=0; indx<numPrims, indx++) {
glColor3ui (indx & redMask << redShift,
indx & greenMask << greenShift,
indx & blueMask << blueShift);
renderPrimitive (indx);
}
Man sollte sichergehen, dass alle Statusvariablen, die den Farbwert noch beeinflussen
können, vorher deaktiviert wurden (siehe vorhergehende Frage).
Auf die Art lassen sich z.B. bestimmte Objekte leicht identifizieren, indem
der Farbwert an der Koordinate XY(Z) als Index auf das Objekt genutzt wird.
So kann die normalerweise dafür genutzte Selection Funktion der OpenGL
umgangen werden.
|