GetPixel()
-
Irgentwie verstehe ich das immer noch net^^
Also, ich versuche mal zu erklären was mein programm eigentlich macht.
1. Ich lade ein bitmap
2. speichere alle pixel des bitmaps in einer arrayvariable vom typ colorref
3. Nun zeige ich jeden pixel an, das sieht bei mir momentan so aus:for (int i = 0; i < 800; i++) { for (int j = 0; j < 600; j++) { SetPixel (hdc, i, j, buffer[i][j]) ; } }Dies passiert nun 100 mal die sekunde, man kann sich vorstellen, das das gewisse problematiken bereitet.
Also, ich will kein bild laden oda so, ich hantiere auch nichmehr mit dem bild herum, sondern ich handtiere nurnoch mit dem coloref herum, mit einer variable halt.
Nur das anzeigen macht problehme, das anzeigen der einzelnen pixel

Ich suche ganz einfach in schnellere funktion als diese hier:
SetPixel (hdc, i, j, buffer[i][j]) ;mit bitbtl oda so habe ich in der anwendung nix am hut, zeichne bloß pixel.
oda habe ich da jetzt irgentwas falsch verstanden?
-
Bitte helft mir, ich finde bei google einfach nix da zeigen die komplette bitmaps immer nur an, ich will einfach nur pixl anzeigen, keine bitmaps

-
SetPixel() ist nunmal lahmarschig (dafür wird die Änderung aber auch nach jedem SetPixel sofort sichtbar)

Der Weg über eine Bitmap ist nunmal deutlich schneller.
Du setzt die Pixel direkt im Speicher ohne Umwege und kannst die ganzen gesetzten Pixel dann in einem Rutsch dank BitBlt() anzeigen.Es gibt nichts wirklich anderes in der WinAPI.
-
Jetzt nehmen wir mal an ich will daraus mal ein mini 2d game machen, ist das möglich, also das das bild nicht mehr flackert etc?
Langsamm fange ich an zu verstehen, aber noch nicht ganz

Ist di anzeige geschwindigkeit dann genauso schnell als ob ich ein normales bitmap normal anzeige oder schneller?
Ich frage das nur ungerne, aber könntest du ein codebeispiel senden?
Ich komme da einfach nicht weiter
-
Es flackert auf jedenfall deutlich weniger als bei SetPixel() (es sei denn du nutzt BackBuffer, dann tut sich in beiden Fällen da nichts)
Pixel-setzen bei ner DIB-Section und BitBlt zusammen dauert sehr sehr sehr viel weniger als SetPixel. Bei sagen wir 800x600 ist SetPixel() schon derbst bescheiden.
Wenn du ein Spiel machst: Wozu musst du da einzelne Pixel setzen?! Wenn du da ne Figur oder so über den Bildschirm wandern lassen willst, würde ich eher die Person in ne Bitmap klatschen und Hintergrund etc. jeweils ne Bitmap und das ganze jeweils direkt via BitBlt(), TransparentBlt(), AlphaBlend() oder so auf den Bildschirm pappen.
Bei BitBlt() muss 'quasi' nur kopiert werden, das geht selbst bei größeren Bildern noch ratz-fatz.Aber für Spiele lohnt sich wohl eher SDL oder speziell bei 2D-Spielen das gute alte DirectDraw

(Quellcode habe ich keinen (mehr) da, bin auf C# umgestiegen)
-
Ich werde es nie kapieren ...
-
So, mal Flugs anhand der msdn gebaut - unkontrolliert und vermutlich fehlerhaft:
HBITMAP aBmp; // Handle der DIB BITMAPINFO bi; // BITMAPINFO-Struktur BITMAPINFOHEADER bmih; // BITMAPINFOHEADER-Struktur char *dibvalues; // Zeiger auf die Pixeldaten // Eigenschaften der zu erzeugenden DIB-Section setzen: ZeroMemory(&bmih,sizeof(BITMAPINFOHEADER)); bmih.biSize=sizeof(BITMAPINFOHEADER); bmih.biHeight=-480; // Höhe der Bitmap 480, negatives Vorzeichen: Oberstes linkes Pixel=erste Pixel in dibvalues bmih.biWidth=640; // Breite der Bitmap 640 Pixel bmih.biPlanes=1; // Ist irgendwie immer 1 ;D bmih.biBitCount=32; // Ein Pixel besteht aus 32 Bits (8 Bit rot, 8 Bit grün, 8 Bit blau, 8 Bit ungenutzt) bmih.biCompression=BI_RGB; // BI_RGB = nicht komprimiert // BITMAPINFO-Struktur (wird von CreateDIBSection() benötigt) // hat 2 Member, einen für die Palette, welche wir nicht benutzen und die BITMAPINFOHEADER-Struktur ist eingebettet: bi.bmiHeader=bmih; // Bei DIB_RGB_COLORS holt sich CreateDIBSection Paletteninfos auf dem hdc das wir übergeben, wir nehmen mal den hdc vom Desktop: HDC hdc=GetDC(NULL); // Das Ding hier erzeugt eine DIB-Section und liefert einen HBITMAP-Handle zurück. // In dibvalues speichert die Funktionen einen Zeiger auf den Speicherbereich wo die Pixel rumliegen aBmp=CreateDIBSection(hdc,&bi,DIB_RGB_COLORS,(void**)&dibvalues,NULL,NULL); // Kurz aufräumen: ReleaseDC(NULL,hdc); // Hat das überhaupt geklappt? if (aBmp==NULL) { OutputDebugString("CreateDIBSection failed! \n"); return 0; } // Jetzt können wir munter Pixel setzen, // das hier entspricht quasi SetPixel()! // hier als Beispiel an der Stelle (x/y) // Ich bin mir nicht sicher aber ich glaube rot,grün,blau,ungenutzt entspricht nicht der hier stehende Reihenfolge // einfach mal rumprobieren. // Mit y*Breite*4+x*4 wird quasi die Position in dibvalues berechnet (hoffe ich) // Warum *4 ? Ein Pixel hatte 32 Bit! dibvalues[y*bmih.biWidth*4+x*4+0] = rotanteil des Pixels an der Stelle (x/y); dibvalues[y*bmih.biWidth*4+x*4+1] = grünanteil des Pixels an der Stelle (x/y); dibvalues[y*bmih.biWidth*4+x*4+2] = blauanteil des Pixels an der Stelle (x/y); dibvalues[y*bmih.biWidth*4+x*4+3] = ungenutzt ?; // ** Ab hier wird aBmp wie eine gewöhnliche Bitmap verwendet ** // Erzeugen wir mal nen temporären DC: hdc=GetDC(NULL); HDC temp_hdc=CreateCompatibleDC(hdc); ReleaseDC(NULL,hdc); // Selektieren da wie bei anderen Bitmaps auch die Bitmap rein: HGDIOBJ OldObj=SelectObject(temp_hdc,aBmp); // ...und blitten die aufs Ziel-DC: BitBlt(ziel_hdc,0,0,640,480,temp_hdc,0,0,SRCCOPY); // ...und natürlich aufräumen: SelectObject(temp_hdc,OldObj); DeleteObject(aBmp); DeleteDC(temp_hdc);Die DIB-Section braucht man dabei im Prinzip eigentlich nur 1x beim programmstart erzeugen und kann dann mit dibvalues die Pixel ändern wie man will, ist man fertig einfach nochmal BitBlt().
-
cool danke, die erklärungen sind sehr gut nun frage ich mich aber, wie kann ich nun die pixel setzen, ich zeige ja kein bitmap an sondern pixel, oder wie kann ich jetzt aus ainem coloref array ein bitmap machen sodass es auch angezeigt wird ?
-
Du hast das in buffer[i][j] liegen? j wäre bei mir y und i bei mir x?
Dann offensichtlich so
for (int j=0; j<480; j++) { for (int i=0; i<640; i++) { dibvalues[j*bmih.biWidth*4+i*4+0] = GetRValue(buffer[i][j]); dibvalues[j*bmih.biWidth*4+i*4+0] = GetGValue(buffer[i][j]); dibvalues[j*bmih.biWidth*4+i*4+0] = GetBValue(buffer[i][j]); } }
-
lol danke

werde ich wenn ich zuhause bin gleich mal testen

nochmals tausenden dank

-
Ok habe es jetzt doch nch auf der firma getestet, es klappt soweit, nur könntest du mir eklären wozu die ziel_hdc dient???
Es kommt auch nur ein fehler, und zwar das die zeal_hdc net deklariert ist, wenn ich die deklariere, so wie temp_hdc, dann wird aber nix angezeigt ??
-
Du wirst die befüllte Bitmap doch irgendwo anzeigen wollen?!
z.B. in deinem Fenster oder so? Das ziel_hdc wäre dann das DC von deinem Fenster.
-
ja habe ch bereits getestet, mein fenster hdc ist hdc ...
aber es wird einfach nix angezeigt ...
Hier mal mein quellcode, es ist ein riesiges durcheinander, da ich noch am experimentieren bin, ordnen mache ich wnns klappt ^^
#define STRICT #include <windows.h> LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); char szKeyStatus[40]; int iKeyLength; static int a; HBITMAP hBitmap[5] ; HDC hdc, hdcMem ; COLORREF rgb[100][100][2]; static int posX[2]; static int posY[2]; PAINTSTRUCT ps ; BITMAP bitmap ; const UINT TimerSec = 1; COLORREF buffer[800][600]; int aX; int aY; static int go; const char szAppName[] = "TestenMachtSpass87"; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hWnd; MSG msg; WNDCLASS wc; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hCursor = LoadCursor(NULL,IDC_ARROW); wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wc.lpszClassName = szAppName; wc.lpszMenuName = NULL; RegisterClass(&wc); hWnd = CreateWindow(szAppName, "Titelleiste", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, /* X-Position auf dem Monitor */ CW_USEDEFAULT, /* Y-Position auf dem Monitor */ 800, /* Fensterbreite */ 600, /* Fensterhoehe */ NULL, NULL, hInstance, NULL); ShowWindow(hWnd, iCmdShow); UpdateWindow(hWnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: { SetTimer(hWnd, TimerSec, 1, NULL); hBitmap[0] = (HBITMAP)LoadImage(NULL, "mel.bmp", IMAGE_BITMAP, 0,0, LR_LOADFROMFILE); hBitmap[1] = (HBITMAP)LoadImage(NULL, "mel.bmp", IMAGE_BITMAP, 0,0, LR_LOADFROMFILE); for (int h = 0; h < 2; h++) { GetObject (hBitmap[h], sizeof (BITMAP), &bitmap) ; hdcMem = CreateCompatibleDC (hdc) ; SelectObject (hdcMem, hBitmap[h]) ; for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { if( RGB( 255, 0, 0) == GetPixel(hdcMem, i, j)) { } else { rgb[i][j][h] = GetPixel (hdcMem, i, j); } } } DeleteDC (hdcMem) ; } iKeyLength = wsprintf(szKeyStatus, "Status Taste %i", a); return 0 ; } case WM_TIMER: { posX[0]++; posY[0]++; for (int x = 0; x < 2; x++) { for (int i = 0; i < 100; i++) { for (int j = 0; j < 100; j++) { aX = posX[x] + i; aY = posY[x] + j; if (aX > 0) { if (aY > 0) { if (aX < 700) { if (aY < 500) { buffer[aX][aY] = rgb[i][j][x]; } } } } } } } InvalidateRect(hWnd, NULL, FALSE); return 0; } case WM_PAINT: { SIZE size; hdc = BeginPaint(hWnd, &ps); HBITMAP aBmp; // Handle der DIB BITMAPINFO bi; // BITMAPINFO-Struktur BITMAPINFOHEADER bmih; // BITMAPINFOHEADER-Struktur char *dibvalues; // Zeiger auf die Pixeldaten // Eigenschaften der zu erzeugenden DIB-Section setzen: ZeroMemory(&bmih,sizeof(BITMAPINFOHEADER)); bmih.biSize=sizeof(BITMAPINFOHEADER); bmih.biHeight=-300; // Höhe der Bitmap 480, negatives Vorzeichen: Oberstes linkes Pixel=erste Pixel in dibvalues bmih.biWidth=300; // Breite der Bitmap 640 Pixel bmih.biPlanes=1; // Ist irgendwie immer 1 ;D bmih.biBitCount=32; // Ein Pixel besteht aus 32 Bits (8 Bit rot, 8 Bit grün, 8 Bit blau, 8 Bit ungenutzt) bmih.biCompression=BI_RGB; // BI_RGB = nicht komprimiert // BITMAPINFO-Struktur (wird von CreateDIBSection() benötigt) // hat 2 Member, einen für die Palette, welche wir nicht benutzen und die BITMAPINFOHEADER-Struktur ist eingebettet: bi.bmiHeader=bmih; // Bei DIB_RGB_COLORS holt sich CreateDIBSection Paletteninfos auf dem hdc das wir übergeben, wir nehmen mal den hdc vom Desktop: HDC hdc=GetDC(NULL); // Das Ding hier erzeugt eine DIB-Section und liefert einen HBITMAP-Handle zurück. // In dibvalues speichert die Funktionen einen Zeiger auf den Speicherbereich wo die Pixel rumliegen aBmp=CreateDIBSection(hdc,&bi,DIB_RGB_COLORS,(void**)&dibvalues,NULL,NULL); // Kurz aufräumen: ReleaseDC(NULL,hdc); // Hat das überhaupt geklappt? if (aBmp==NULL) { OutputDebugString("CreateDIBSection failed! \n"); return 0; } // Jetzt können wir munter Pixel setzen, // das hier entspricht quasi SetPixel()! // hier als Beispiel an der Stelle (x/y) // Ich bin mir nicht sicher aber ich glaube rot,grün,blau,ungenutzt entspricht nicht der hier stehende Reihenfolge // einfach mal rumprobieren. // Mit y*Breite*4+x*4 wird quasi die Position in dibvalues berechnet (hoffe ich) // Warum *4 ? Ein Pixel hatte 32 Bit! for (int j=0; j<300; j++) { for (int i=0; i<300; i++) { dibvalues[j*bmih.biWidth*4+i*4+0] = GetRValue(buffer[i][j]); dibvalues[j*bmih.biWidth*4+i*4+0] = GetGValue(buffer[i][j]); dibvalues[j*bmih.biWidth*4+i*4+0] = GetBValue(buffer[i][j]); } } // ** Ab hier wird aBmp wie eine gewöhnliche Bitmap verwendet ** // Erzeugen wir mal nen temporären DC: hdc=GetDC(NULL); HDC temp_hdc=CreateCompatibleDC(hdc); ReleaseDC(NULL,hdc); // Selektieren da wie bei anderen Bitmaps auch die Bitmap rein: HGDIOBJ OldObj=SelectObject(temp_hdc,aBmp); // ...und blitten die aufs Ziel-DC: BitBlt(hdc,0,0,300,300,temp_hdc,0,0,SRCCOPY); // ...und natürlich aufräumen: SelectObject(temp_hdc,OldObj); DeleteObject(aBmp); DeleteDC(temp_hdc); EndPaint(hWnd, &ps); return 0; } case WM_DESTROY: { MessageBox( NULL, "Beim beenden des Programmes gehen Daten verloren, wollen sie diese zwischenspeichern?", "Warnung!", MB_YESNOCANCEL ); PostQuitMessage(0); return 0; } } return DefWindowProc(hWnd, message, wParam, lParam); }Ich habe jetzt den quellcode auch geschickt, damit man sieht was ich eigentlich mache^^
habe da hdc eingetragen also mein hdc, und es wird nix angezeigt

-
ich vermute ich werde es nie hin bekommen
