|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Fruchteis Mini JLI'ler
Anmeldedatum: 15.09.2007 Beiträge: 27 Wohnort: Heidelberg Medaillen: Keine
|
Verfasst am: 28.01.2008, 20:48 Titel: Verständnisprobleme bezüglich D3DLOCKED_RECT |
|
|
Nun, die Schwierigkeit den Sachverhalt, bezogen der Lock_Rect-Struktur, zu verstehen, liegt darin, dass ich nicht verstehe aus welchem Grund ich den Pitch, der die eigentliche Breite der Oberfläche angibt, in Byte bzw. entsprechend der Farbtiefe umrechnen muss. Auch komplett entzogen, die Vorstellung das ich *pBits in Abhängigkeit von der Farbtiefe casten muss, möchte mir nicht so wirklich sinnig vorkommen.
Beispiel:
DWORD* Pixel = reinterpret_cast<DWORD*>(LockRect.pBits)
->Weshalb caste ich in einem 4Byte long typ? Verständlich ist dies, da ich einen TrueColor-Modus mit Alphawert benutze. Aber weshalb caste ich in einem 4Byte Integer-Typ? Eventuel interne Verarbeitung?
Um gezielt auf ein Pixel, sagen wir an der Stelle (x,y), zugreifen zu können,
ist ja folgender Schritt notwendig:
Code: | int Pitch = LockRect.Pitch/4;
D3DCOLOR* Pixel = reinterpret_cast<D3DCOLOR*>(LockRect.pBits);
/*Lese_Zugriff*/
D3DCOLOR Pixelxy = Pixel[y * Pitch + x];
/*Schreib_Zugriff*/
Pixel[y * Pitch +x] = D3DCOLOR_ARGB(....); |
Zu meinen Fragen: Weshalb, wie oben bereits angesprochen, teile ich Pitch durch vier? Weshalb caste ich pBits und warum multipliziere ich, um auf ein Pixel zuzugreifen, y mit Pitch und addiere dann das Produkt mit x?
Auf welches Pixel greife ich eigentlich zu, da ich ja keine x , y Koordinate angebe? Müsste ich nicht ein mehrdimensionales Array benutzen um auf ein Pixel, das verständlicherweise einen Punkt auf der Surface kennzeichnet und daraus folgend ein geordnetes Koordinatenpaar besitzt, in der Ebene - die Surface - zugreifen zu können?
Ich weiß sehr wohl das dies sehr viele Fragen sind, doch hoffe ich ihr mir weiterhelfen _________________ Ein Beweis für Programmierer:
Jedes Programm läßt sich um mindestens eine Anweisung kürzen.
Jedes Programm hat mindestens einen Fehler.
Durch Induktion können wir schließen:
Jedes Programm ist reduzierbar auf eine Anweisung, die nicht funktioniert... |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 29.01.2008, 09:36 Titel: |
|
|
Zitat: | Warum multipliziere ich, um auf ein Pixel zuzugreifen, y mit Pitch und addiere dann das Produkt mit x? | Eine Textur ist nur ein lineares Array und kein 2-dimensionales. d.h. es liegt im speicher mit der breite b und dem pitch p und der höhe h direkt hintereinander. Stell dir eine 4x8-Textur mit dem pitch 6 vor: Code: | T T T T S S
T T T T S S
T T T T S S
T T T T S S
T T T T S S
T T T T S S
T T T T S S
T T T T S S | T ist hier ein Pixel auf der Textur (Texel) und S der überflüssige Speicher, der wegen der GraKa immer mit reserviert wird. In dem Array liegen diese Werte zeilen weise hinter einander, also so: Code: | T T T T S S T T T T S S T T T T S S T T T T S S T T T T S S T T T T S S T T T T S S T T T T S S | bits[0], deine 0. Zeile(ich fange bewusst mit 0 an), ist also T, bis bits[5]. Deine 1. Zeile beginnt ab bits[6], deine 2. ab bits[12] usw. d.h. Jede Zeile ist um <pitch> voneinander entfernt. Du addressierst sie also: [0 * pitch] = [0], [1 * pitch] = 6 usw. Dann musst du nur noch die Spalte auswählen (von 0 bis 3, da b = 4). Die addierst du dann dazu, also: [0 * pitch + 0] = erster Texel, [1 * pitch + 2] = 1 zeile 2. spalte usw.
Zitat: | Weshalb caste ich pBits? | pBits ist von Natur aus BYTE* (= unsigned char; char ist im Grunde auch nur ein 8-bit-Integertyp). D3DLOCKED_RECT kann aber alle möglichen Farbtiefen beinhalten, sowohl 8-bit als auch 32-bit usw. Du musst wissen welche Tiefe pBits hier hat. Daher musst du dann casten, um auch richtig drauf zuzugreifen. Stell dir das so vor(das unsigned lasse ich der EInfachheit halber mal weg): CPP: | __int8* pBits; // das sei jezt dein BYTE*
__int32* pixels = reinterpret_cast<__int32*>( pBits ); // jetzt werden die bits als 32-bit werte interpretiert
// pixels[ 2 ] entspricht nun pBits[ 8 ] und
// pixels[ 2 ] kannst du problemlos einen 32-bit wert zuweisen | Das sind alles Integers, weil es im Grunde Zahlen sind man Integers am leichtesten ansprechen kann. floats z.b. wären etwas schwieriger ;)
Zitat: | Weshalb, wie oben bereits angesprochen, teile ich Pitch durch vier? |
Mit dem pitch ist das ähnlich, der pitch bezieht sich von Haus aus auch auf die Breite in Bytes und du musst ihn erst umrechnen. Da du pBits in 32-bit gecastet hast addressierst du pBits[8] ja mit [pixels[2]. Nehmen wir an, der pitch ist 64, dann ist pBits[ 64 ] die 2. Zeile in deiner Textur (== [1 * 64 + 0]). über pixels ist die 2. zeile aber pixels[ 16 ] und nicht 64, da 16 als "16 schritte von 32-bit" interpretiert wird. daher musst du den pitch durch 4 Teilen damit das wieder stimmt.
So, war ganz schön viel in einem Post, aber man muss sich da auch echt erstmal einarbeiten um das alles zu verstehen, also frag ruhig wenn was unklar ist.
Gruß DXer |
|
Nach oben |
|
|
Fruchteis Mini JLI'ler
Anmeldedatum: 15.09.2007 Beiträge: 27 Wohnort: Heidelberg Medaillen: Keine
|
Verfasst am: 29.01.2008, 15:55 Titel: |
|
|
Erstaunt einerseits über deine aufschlussreiche Antwort, andererseits verblüfft über die Fülle an Information, die mir so nicht bewusst war.
Herzlichen Dank _________________ Ein Beweis für Programmierer:
Jedes Programm läßt sich um mindestens eine Anweisung kürzen.
Jedes Programm hat mindestens einen Fehler.
Durch Induktion können wir schließen:
Jedes Programm ist reduzierbar auf eine Anweisung, die nicht funktioniert... |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|