GDI, Bitmap, memDC
-
Hallo,
ich habe mal eine Frage zu dem Win32 GDI.Und zwar würde ich gerne die SetPixel Funktion durch eine Assembler inline Routine ersetzen, dazu bräuchte ich aber ein paar Infos. Aus der MSDN bin ich da nicht so Recht schlau geworden. Zumindest habe ich nicht das gefunden wonach ich gesucht habe.
OK. Also, ich habe mir einen Memory DC über CreateCompatibleDC(..) erschaffen und darin eine Bitmap eingewählt. Nun möchte ich, wie bereits erwähnt, die SetPx Funkt. "nachbauen" und den Speicher direkt selber mit Farbinfos füllen. Ich weiß aber nicht in welcher Form der Speicher vorliegt.
1. Ob die Farbinfos der Zeilen nacheinander im Speicher stehen oder die Spalten?
2. Wieviel ein Pixel an Speicher belegt , 2^32 Farben=Word oder 256 Farben=Byte?
3. Wie bekomme ich 1. und 2. zur Laufzeit heraus?
4. Das Handle der Bitmap ist doch ein Zeiger auf den Anfang des Speicherbereiches in dem die Farbinfos liegen, richtig? Somit müsste ich beginnend ab der referenzierten Adresse, Höhe*Breite*Farbtiefe Bytes mit den gewünschten Farbinfos schreiben.
5. Das Handle auf den memDC aber ist ebenfalls ein Zeiger darauf, wenn ich die Bmp in diesen eingewählt habe, oder?
6. Sollte ich nun lieber erst die Bmp per ASM mit Farbinfos füllen und danach in den memDC einwählen oder erst einwählen und dann den memDC per ASM füllen?Hier der kurze Code zum erzeugen des memDC:
RECT clientArea; GetClientRect(hWnd, &clientArea); HDC hDC = GetDC(hWnd); HBITMAP hMemBmp = CreateCompatibleBitmap(hDC, clientArea.right, clientArea.bottom); // Hier per ASM füllen? HDC hMemDC = CreateCompatibleDC(hDC); SelectObject(hMemDC, hMemBmp); // Oder erst hier den memDC oder die Bmp? ReleaseDC(hWnd, hDC);
-
Ich denke du brauchst GetDiBits...
-
Ich hab mir jetzt noch mal die ganze MSDN Referenz zu Bitmaps angeschaut und weiß genauso viel wie vorher.
Ich will doch nicht die Daten kopieren, sondern einfach nur einen Zeiger auf den Speicherbereich wo die Bitmapdaten liegen. Das scheint wohl nicht so einfach zu gehen wie ich mir das gedacht habe. Bei diesen ganzen Funktionen mit DIBs muss man ja ständig eine BITMAPINFO Struct übergeben. Ich will aber eine Bitmap, welche genauso aufgebaut ist wie mein DC. Deswegen nehme ich ja CreateCompatible... Ich muss dann eigentl. bloß wissen wie dieser aufgebaut ist und einen Zeiger auf den Bereich bekommen. Das kann doch nicht so schwer sein oder? Und die MSDN ist auch nicht wirklich aufschlussreich für mich. Ich bin doch bestimmt nicht der Erste, der so etwas machen möchte.
-
Wenn du direkt in die Bitmap schreiben willst, dann brauchst du CreateDIBSection. Das dadurch erhaltene Handle kannst du wie ein HBITMAP verwenden. Zusätzlich kannst du auch direkt auf den Speicher zugreifen. Das heißt aber nicht, dass jede Speicheränderung sofort am Bildschirm erscheint. Dafür musst du immer noch BitBlt verwenden (wie im anderen Thread schon gesagt, zeilenweise). Also: compatible dc machen, das handle von createdibsection hineinselektieren und dann bitblt.
Oder du machst es mit SetDIBitsToDevice. Dafür musst du nur irgendwo im Speicher eine BITMAPINFO struct ausfüllen und diese der Funktion übergeben. Als Ziel-DC kannst du hier direkt den "echten" DC nehmen.
EDIT: Ich hab vor ein paar Jahren mal genau das gleiche gemacht (Mandelbrotmengenberechnung in Assembler + zeilenweise Anzeige), leider finde ich das Projekt nicht mehr, sonst hätte ich dir den Code auch gleich zeigen können.
-
THX.
Also so funktioniert das Ganze ziemlich gut:BITMAPINFO bmpInfo; ZeroMemory(&bmpInfo.bmiHeader, sizeof(BITMAPINFOHEADER)); bmpInfo.bmiHeader.biWidth = _clientArea.right; bmpInfo.bmiHeader.biHeight = _clientArea.bottom; bmpInfo.bmiHeader.biPlanes = 1; bmpInfo.bmiHeader.biBitCount = 32; bmpInfo.bmiHeader.biSizeImage = BI_RGB; bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biClrUsed = 0; bmpInfo.bmiHeader.biClrImportant = 0; _hMemBmp = CreateDIBSection(_hMemDC, &bmpInfo, DIB_RGB_COLORS, &_pBmpBits, NULL, 0);
Über den _pBmpBits Pointer kann man dann auf den Speicher direkt zugreifen.