Farbe "aufsplitten"
-
Hi,
Hm, ok um den Anfängern hier ein kleines Beispiel darzulegen, poste ich hier einen kleinen Teil meiner Engine.Hier werden alle Formate unterstützt was die Funktion GetPixelFormat unterstützt.
Also die Funktion GetPixelFormat liefert die RGBA Bitmasken ( von A/32Bit ist sie zb. 0xff000000, ..usw ).
// get textureinfo from level 0 (*pTexture)->GetLevelDesc( iLevel, &d3ddesc ); PixelFormat = GetPixelFormat( d3ddesc.Format ); // get bits per channel DWORD bits_a = GetBitsFromBitMask( PixelFormat.dwABitMask, PixelFormat.BitsPerPixel ); DWORD bits_r = GetBitsFromBitMask( PixelFormat.dwRBitMask, PixelFormat.BitsPerPixel ); DWORD bits_g = GetBitsFromBitMask( PixelFormat.dwGBitMask, PixelFormat.BitsPerPixel ); DWORD bits_b = GetBitsFromBitMask( PixelFormat.dwBBitMask, PixelFormat.BitsPerPixel ); // set colorkey for( UINT cy=0; cy < d3ddesc.Height; cy++ ) { for( UINT cx=0; cx < d3ddesc.Width; cx++ ) { DWORD dwColor; DWORD dwNewColor; // read color from current pixel if( PixelFormat.BitsPerPixel == 16 ) dwColor = ((WORD*)pBits)[cy*dwLineLength+cx]; if( PixelFormat.BitsPerPixel == 32 ) dwColor = ((DWORD*)pBits)[cy*dwLineLength+cx]; // .. 64 bits // export color UCHAR pix_a = (UCHAR) ( (dwColor & PixelFormat.dwABitMask ) >> (bits_r+bits_g+bits_b) ); UCHAR pix_r = (UCHAR) ( (dwColor & PixelFormat.dwRBitMask ) >> (bits_g+bits_b) ); UCHAR pix_g = (UCHAR) ( (dwColor & PixelFormat.dwGBitMask ) >> (bits_b) ); UCHAR pix_b = (UCHAR) ( (dwColor & PixelFormat.dwBBitMask ) ); // reduce values 0-1 FLOAT fA = ((FLOAT)pix_a)/(pot( 2, bits_a )-1); FLOAT fR = ((FLOAT)pix_r)/(pot( 2, bits_r )-1); FLOAT fG = ((FLOAT)pix_g)/(pot( 2, bits_g )-1); FLOAT fB = ((FLOAT)pix_b)/(pot( 2, bits_b )-1); // compute 32 bit value UCHAR ucA = (UCHAR)(fA * 255); UCHAR ucR = (UCHAR)(fR * 255); UCHAR ucG = (UCHAR)(fG * 255); UCHAR ucB = (UCHAR)(fB * 255); }//for }//for
Bye
-
Hi,
Für die die nicht wissen wie ich auf dwLineLength gekommen bin:
Aber das sollte eig. selbstverständlich sein.// compute line length if( PixelFormat.BitsPerPixel == 16 ) dwLineLength = LockedRect.Pitch >> 1; if( PixelFormat.BitsPerPixel == 32 ) dwLineLength = LockedRect.Pitch >> 2;
Bye
-
danke schonmal, hab aber noch ne wahrscheinlich sehr dumme frage:
wie sehen denn die bitmasken aus?? um speziell auf meine frage zurück zu kommen, wie sieht die bitmask für r5g6b5 aus?
und noch was, diese frage habe ich ähnlich hier schonmal gesachriebem:
was machst du in dieser funktion, wenn deine textur ein 24 bit format hat??
dank
-
Gab's nicht auch in der FAQ schon irgendwo mal eine allgemeine Methode? Was ich hier nicht so toll finde, ist die Verwendung von floats, wenn man erst multipliziert und dann teilt, geht es ohne. Zudem warum ist der Faktor denn 255, müsste doch 2^8 sein!
Wie die Bitmasken für 565 aussieht ist doch klar, die ersten 5 Bits sind für Rot, die nächsten 6 Grün, der Rest Blau. Das ist doch mal logisch!
-
ja, aber wie schreibe ich das? bitmasken sind doch diese 0xff000000 und so, oder? also, wie sähe z.b. eine typische "dsBitMask" aus [Helper]´s PixelFormat Struktur aus?
-
Hi,
@TGGC:
Also die Float's hab ich damal genommen, weil irgent etwas anderes rauskam. Bin mir aber nicht sicher was. Mit den 255 hast du recht. Hab ich gleich geändert, Danke@Tetris Fan:
Die Bitmaske würde in diesem Falle folgende sein:pfmt.dwRBitMask = 0xF800; pfmt.dwGBitMask = 0x07E0; pfmt.dwBBitMask = 0x001F; pfmt.BitsPerPixel = 16;
Aber wie TGGC gesagt hat, im FAQ findest du genauere Informationen.
Bye
-
Danke, aber das hilft mir leider immer noch nicht...
wie kommt man denn auf diese bitmasken? sind die alle irgendwie festgelegt, oder gibt es eine formel oder so, mit der man das berechnen kann?
in den faq zur spiele und grafik programmierung hab ich noch nichts gefunden... suche aber weiter.
-
Tetris Fan schrieb:
Danke, aber das hilft mir leider immer noch nicht...
wie kommt man denn auf diese bitmasken? sind die alle irgendwie festgelegt, oder gibt es eine formel oder so, mit der man das berechnen kann?
in den faq zur spiele und grafik programmierung hab ich noch nichts gefunden... suche aber weiter.Wenn Du mal in meinen Post geguckt hättest, wüsstest Du es:
R5G6B5 sind 5 Bits für Rot, 6 für Grün und 5 für Blau.
Entsprechend, um ROT zu erhalten:
1111100000000000 (erste 5 Bits)
Um GRÜN zu erhalten:
0000011111100000 (zweite 6 Bits)
Für BLAU entsprechend!Und jetzt rate mal, wie das HEXADEZIMAL aussieht:
Richtig:[Helper] schrieb:
@Tetris Fan:
Die Bitmaske würde in diesem Falle folgende sein:pfmt.dwRBitMask = 0xF800; pfmt.dwGBitMask = 0x07E0; pfmt.dwBBitMask = 0x001F; pfmt.BitsPerPixel = 16;
Für ROT:
4 Bits = 1 HexWert
Also die ersten 4 Bits alle auf 1 ergibt F
Die zweiten 4 Bits nur das erste auf 1 (1000) ergibt 8Und wenn Du es jetzt nicht verstanden hast, Schande über Dich, selbst meine Freundin hat das gerade gerallt!
-
AAAAAAAAHHHHHHHHHH
ich habs gerafft (MEINE Freundin leider immer noch net... egal)
nun noch aber eine letzte frage, dann seid ihr mich (vorserst...) los:
ich habe beim weiteren suchen etwas gefunden, zwar nichtt das, was ich gesucht habe, fand es aber dennoch sehr interessant:
um vier farbkomponenten zu einer farbe zusammen zu führen benutze ich D3DCOLOR_ARGB, dieses rechnet das ja so:
(((a) & 0xff) << 24) | (((r) & 0xff) << 16 etc.
auf gamedev.net habe ich aber eine solche rechnung gefunden:
(a << 24) | (r << 16) | (r <<| (b).
ist das das gleiche???
-
Hi,
Hm ich nehme ´jetzt an, dass die der '&' und '|' operator nichts sagt, sonst hättest du es dir denken können.
Wenn ich zwei Fargen(a,b) mit einem '&' operator vergleiche kommen die Bits raus, die in beiden Farben gesetzt sind. Da kommt zb. folgendes raus. ( in Bits)
Bit a b ergebnis
1 1 0 0
2 1 0 0
3 1 1 1
4 0 1 0
.
.Also dieser & operator "entfernt" einfach die Werte die überflüssig sind.
zb. für den Rot-Wert brauch ich nicht die A, G,B Werte. Durch das Bitweise vergleichen mit der Roten-Bitmask bleiben nur die Bits stehen die den Rot anteil der Farbe angeben.
Im Prinzip ist das Verfahren überflüssig. Aber um wirklich 100% sicher zu gehen wird das einfach gemacht
Bye
-
Man, hier wird ja echt beim Urschleim angefangen...
-
Tetris Fan schrieb:
um vier farbkomponenten zu einer farbe zusammen zu führen benutze ich D3DCOLOR_ARGB, dieses rechnet das ja so:
(((a) & 0xff) << 24) | (((r) & 0xff) << 16 etc.
auf gamedev.net habe ich aber eine solche rechnung gefunden:
(a << 24) | (r << 16) | (r <<| (b).
ist das das gleiche???Im ersteren ist ja überhaupt kein g, b drin?
Um in 2. ist r doppelt und g fehlt?!?
Das ist falsch.Im Übrigen stimmt hier Helper's comment
[Helper] schrieb:
Also dieser & operator "entfernt" einfach die Werte die überflüssig sind.
zb. für den Rot-Wert brauch ich nicht die A, G,B Werte. Durch das Bitweise vergleichen mit der Roten-Bitmask bleiben nur die Bits stehen die den Rot anteil der Farbe angeben.
nicht!
Ein "& 0xFF" ist VÖLLIG überflüssig (da alle Bits genommen werden).Aber ich denke Du hast es einfach falsch abgeschrieben...
Helper's anderer
[Helper] schrieb:
Hm ich nehme ´jetzt an, dass die der '&' und '|' operator nichts sagt, sonst hättest du es dir denken können.
stimmt aber umso mehr: Einfach mal in einem CPP-Tut Deiner Wahl bitweise Operatoren nachschlagen. Das dürfte Licht in die Angelegenheit bringen.
Im Übrigen gab's irgendwo hier letztens eine Frage zu "SDL_Init(SDL _AUDIO | SDL_VIDEO)" -> Das ist das gleiche Prinzip...
-
ok, gut, sonst hätte ich alles von meinem color manager, was ich schon habe, umschreiben müssen...
gut, das solls dan wirklich mal gewesen sein.
danke an alle, 1000x danke,
cya
-
Sgt. Nukem:
oh... peinlich. also ddie zweite zeile habe ich tatsächlich falsch abgeschrieben. bei der ersten (übrigens ein auszug aus der dx doku) habe ich ein etc. jinter die ersten beiden teile der rechning gesetzt, da ich keine lust hatte, diese komplett abzuschreiben.
-
Ich werde langsam Wahnsinning...........
folgendes problem: ich setze eine 565 farbe zusammen (16 bit, logisch), und zwar so:unsigned short color = (unsigned short)((255 << 11) | (128 << 5) | (0));
Die resultierende farbe ist gelb, wie das "profi-auge" erkennen sollte... (R:255, G:128, B:0)
nun möchte ich den rot-teil der farbe haben:unsigned char red = (unsigned char) ((color & 0xF800) >> 11);
wenn ich mir red ausgeben lasse, erhalte ich alles andere, als 255 (was ja der rot-teil der erstellten farbe ist),
HELP.......
-
ROTANTEIL =((FARBE >> 11) & 0x0000001F) << 3
GRÜNANTEIL=((FARBE >> 5) & 0x0000003F) << 2
BLAUANTEIL=(FARBE & 0x0000001F) << 3Versuch es mal mit diesen Makros. Hab keine Ahnung ob das stimmt was da steht. Interessiert mich erlich auch nicht. Solange es funktioniert.
-
Tetris Fan schrieb:
Ich werde langsam Wahnsinning...........
folgendes problem: ich setze eine 565 farbe zusammen (16 bit, logisch), und zwar so:unsigned short color = (unsigned short)((255 << 11) | (128 << 5) | (0));
Die resultierende farbe ist gelb, wie das "profi-auge" erkennen sollte... (R:255, G:128, B:0)
nun möchte ich den rot-teil der farbe haben:unsigned char red = (unsigned char) ((color & 0xF800) >> 11);
wenn ich mir red ausgeben lasse, erhalte ich alles andere, als 255 (was ja der rot-teil der erstellten farbe ist),
HELP.......Einfach mal Gehirn einschalten:
Bei 32 Bit = R8G8B8 + entw. A8 oder X8
hat jeder Farbanteil 8 Bit = 256 verschiedene Möglichkeiten ( 2^8 ),
insgesamt also 256 * 256 * 256 = 16.777.216 verschiedene Farben.Bei 16 Bit = R5G6B5 hat rot und blau z.B. nur 5 Bit = 2^5 also 32 verschiendene mögliche Werte!!!
Grün mit 6 Bit = 64 verschiedene Grüntöne.Insgesamt also 32 x 64 x 32 = 65.536 verschiedene Farben.
Wenn Du statt von 0 - 31 den Rotanteil mit 0 - 255 angeben will, mußt Du also skalieren...
-
Hi,
@Sgt. Nukem:
L0LCu
-
-
kann ich nich auch einfach sowas in der art wie...
typedef _foo struct
{
unsigned r : 5;
unsigned g : 6;
unsigned b : 5;
}foo;schreiben? dann kann ich sogar gemütlich über foo.r usw. drauf zugreifen...schließlich sollte der compiler das intern ja dann auch mit shifts machen so das es nich wirklich langsamer is...
tschöö