ubuntuusers.de

X-Server, C++, Farbtiefe wird nicht richtig bestimmt

Status: Ungelöst | Ubuntu-Version: Ubuntu 12.04 (Precise Pangolin)
Antworten |

j0nas

Anmeldungsdatum:
19. Juli 2009

Beiträge: 6

Hallo Liebe Community,

ich habe mir ein Buch zur Grafikprogrammierung mit dem X-Server gekauft. Dort gibt es natürlich jeder Menge Quellcode. Dabei bin ich auf ein Programm gestoßen, dass bei mir einen Fehler verursachte. Dabei konnte das Fenster nicht erzeugt werden und die Funktion XCreateWindow hat nicht richtig gearbeit(genauen Wortlaut weiß ich nicht mehr).

Der Code der den Fehler ausmacht:

1
2
3
4
5
6
7
8
pixmap_formats = XListPixmapFormats(dpy, &count);
  for(i=0, depth=0; i<count; i++) {
    if(pixmap_formats[i].depth > depth) {
      depth        = pixmap_formats[i].depth;
      bytespp      = pixmap_formats[i].bits_per_pixel / bits_per_byte;
      scanline_pad = pixmap_formats[i].scanline_pad;
    }
  }

Dabei wird die maximale Tiefe bestimmt. Nach diesem Code kommt für depth hier 32 raus. Wenn ich diese Schleife übergehe und für depth 24 einsetze, läuft das Programm Fehlerfrei.

Daraus habe ich gefolgert das die Farbtiefe hier nicht richtig bestimmt wird. Standardmäßig nutzt doch der X-Server die 24Bit?!

Meine Frage ist nun in diesem Zusammenhang, wie kann ich das Verhalten hier anpassen, dass ich nicht die 24 bit als Wert einschreiben muss. Es kann ja vllt. auch mal passieren, dass ich den X-Server mit 32 Bit laufen lasse, dann würde dieses Programm ja nicht alles mögliche ausnutzen. Was ist meine möglichkeit hier den korrekten Wert zu ermitteln?

Vielen Dank schon einmal im voraus ☺

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11260

Wohnort: München

24-Bit bei Linux entspricht der 32-Bit Anzeige unter Windows - die 8 alpha-Bits werden in der Angabe einfach nicht mitgezählt... Du hast jeweils ein Byte - also je 256 mögliche Werte für alpha, rot, grün, blau. Vermutlich muss man den Alpha-Wert mit berücksichtigen.

j0nas

(Themenstarter)

Anmeldungsdatum:
19. Juli 2009

Beiträge: 6

Danke für die Antwort, aber inwiefern mach ich dass in C++/diesem speziellen Fall?

Prinzipiell scheint mein X-Server die 32bit ja zu unterstützen und als maximale Farbtiefe anzugeben. Würde sich das problem lösen, wenn ich den X-Server prinzipiell mit diesen 32bit nutze?

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11260

Wohnort: München

Was liefert denn das Struct an Werten? Laut http://linux.die.net/man/3/xlistpixmapformats

The XPixmapFormatValues structure provides an interface to the pixmap format information that is returned at the time of a connection setup. It contains:

typedef struct {
 int depth;
 int bits_per_pixel;
 int scanline_pad;
 } XPixmapFormatValues;

Ich kenne den Rest des Codes nicht (und kann C++ bestenfalls ein Bisschen lesen ohne alle Feinheiten der Sprache zu kennen), daher weiß ich nicht was da schief geht. j0nas schrieb:

Würde sich das problem lösen, wenn ich den X-Server prinzipiell mit diesen 32bit nutze?

Das machst du ja schon (http://en.wikipedia.org/wiki/Color_depth#True_color_.2824-bit.29), die nächsten üblichen Stufen (wenn das deine Grafikkarte packt und es mit deinem Monitor überhaupt möglich ist) wären ja 30, 36, 42 Bit (http://en.wikipedia.org/wiki/Color_depth#Deep_color_.2830.2F36.2F48-bit.29)

j0nas

(Themenstarter)

Anmeldungsdatum:
19. Juli 2009

Beiträge: 6

Zu der Struktur. Die Werte liefert das ja richtig. Die Idee dahinter ist alle möglichen Farbtiefen abzufragen und die höchste zu nutzen. Das Problem ist, dass diese Schleife auf eine Farbtiefe von 32Bits kommt, meine Anwendung aber nur mit 24Bits läuft. Ich habe das Manuell ausprobiert und dann auf 24 gelassen. Kommt da das Programm/der x-Server mit dem Alphawert durcheinander?

Der Rest des Codes ist in dem Zusammenhang denke ich uninteressant. Dort wird dann mit dieser Farbtiefe das Fenster erzeugt und ein Pixmap reingeschrieben.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11260

Wohnort: München

j0nas schrieb:

Der Rest des Codes ist in dem Zusammenhang denke ich uninteressant. Dort wird dann mit dieser Farbtiefe das Fenster erzeugt und ein Pixmap reingeschrieben.

Es sollte doch von der Klasse und den verwendeten Funktionen, die das Fenster zeichnen abhängig sein welche Angabe für die Farbtiefe erwartet wird - sprich ob die den Alphakanal mitgezählt haben will oder nicht. Ich weiß nicht wie aktuell dein Buch ist und ob sich da evtl. etwas in letzter Zeit an der API der genutzten Klassen geändert hat.

Dee Team-Icon

Avatar von Dee

Anmeldungsdatum:
9. Februar 2006

Beiträge: 20095

Wohnort: Schwabenländle

@j0nas: Kannst Du nicht probehalber fürs Debugging einfach den gesamten Inhalt von pixmap_formats ausgeben?

Die Schleife sieht korrekt aus. Wenn 32 herauskommt, heißt das ja, dass XListPixmapFormats Dir das entsprechend zurückliefert. Das Display dpy, was Du übergibst, scheint also 32 Bit zu unterstützen.

Entweder arbeitet XListPixmapFormats nicht korrekt (was ich nicht denke), oder Dein dpy ist vielleicht nicht das, was Du denkst.

Gruß Dee

j0nas

(Themenstarter)

Anmeldungsdatum:
19. Juli 2009

Beiträge: 6

Also ich habe jetzt bei jedem Schleifendurchlauf einfach die Infos mit ausgegeben.

Resultat:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Tiefe: 1
Bytes pro Pixel: 0
Scanline Pad: 32

Tiefe: 4
Bytes pro Pixel: 1
Scanline Pad: 32

Tiefe: 8
Bytes pro Pixel: 1
Scanline Pad: 32

Tiefe: 15
Bytes pro Pixel: 2
Scanline Pad: 32

Tiefe: 16
Bytes pro Pixel: 2
Scanline Pad: 32

Tiefe: 24
Bytes pro Pixel: 4
Scanline Pad: 32

Tiefe: 32
Bytes pro Pixel: 4
Scanline Pad: 32

Also mein X-Server kann sozusagen bis zu 32Bit hoch. Mein Display ist der Standardmonitor, ein Fenster bekomm ich auch hin. Nur nutze ich bei meinem Fenster anstatt der maximal möglichen 32 Bit die 24 Bit, jedoch per Hand eingetragen.

1
 dpy = XOpenDisplay(NULL);

Gleich danach kommt die oben genannte Schleife.

Weiterhin interessant waren in dem Fall noch die beiden Abschnitte:

1
2
3
4
5
w = XCreateWindow(dpy, DefaultRootWindow(dpy), 100, 100,
                    screen_xsize, screen_ysize,
                    0, // Rahmen
                    24, CopyFromParent, vis, // Tiefe, Klasse, Visual
                    0, NULL); // Wertemaske, Attribute

Und:

1
2
3
4
5
6
7
ximg = XCreateImage(dpy, vis, 24, // 24 = Tiefe
                      ZPixmap,   // Format
                      0,  // Offset vom Anfang der Scanline
                      screen,
                      screen_xsize, screen_ysize,
                      scanline_pad,
                      0); // Bytes_pro_Zeile: 0 = automatisch

In beiden Fällen steht original die Variable depth aus der Schleife an stelle der per Hand geschriebenen 24.

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11260

Wohnort: München

Da du mit wortwörtlichen Fehlermeldungen etwas sparsam bist: Ist das das gleiche Problem?

http://stackoverflow.com/questions/3645632/how-to-create-a-window-with-a-bit-depth-of-32

Antworten |