OpenGL.org 3Dsource.de: Infos rund um 3D-Computergrafik, OpenGL und VRML
space Telefon-Tarife space VDI - Arbeitskreis Fahrzeugtechnik space Beschallungsanlagen und Elektroakustik space Heise-News space

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.

Seite durchsuchen nach:

Fragen oder Ideen an:
Thomas.Kern@3Dsource.de
Linux-Counter
(C) Thomas Kern