SetPixelV in Gerätekontext CDC
-
Hallo,
ich bin gerade dabei ein kleines Spielchen mit einer MFC-Anwendung zu schreiben.
Dabei will ich jedes einzelne Pixel vor jeden neuen Bildaufbau festlegen.
Dafür benutze ich die Funktion SetPixelV der Klasse CDC.
Allerdings dauert mir dies zu lange und nun ist meine Frage, ob es einen schnelleren Weg gibt, z.B. den Gerätekontext mit Hilfe eines Zeigers ent-
sprechen zu manipulieren, die Pixel einzufärben.Vielen Dank für Eure Unterstützung!
-
Für so was nimmt man einen Speicher-DC, in den schreibst du erst deine Pixel und zum Schluss wird das ganze auf den DC des Windows geblittet, ist wesentlich schneller. Du musst dazu einen DC und ein Bitmap erstellen, dann das Bitmap im DC selektieren, fertig. In der OnPaint rufst du dann dc.BitBlt(..) auf.
Es gibt aber auch schon fertige Klassen für sowas, such mal nach CMemDC.Gruß,
connan.
-
Hallo,
Das mit dem DC - Speicher habe ich auch schon die ganze Zeit betrieben, nur
dauert dies ebenfalls zu lange, da ich ja jeden einzelnen Pixel des ganzen
Bildschirmes einfärbe.
Vielleicht ist mein Computer auch nur zu langsam, aber, da wundert es mich,
dass bei mir Spiele laufen, bei denen sich alle Pixel verändern.
-
MCGH schrieb:
Vielleicht ist mein Computer auch nur zu langsam, aber, da wundert es mich, dass bei mir Spiele laufen, bei denen sich alle Pixel verändern.
Du meinst sicher 3D-Games und hast eine 3D-Grafikkarte, das ist leider nicht vergleichbar.
Ansonsten schau doch mal ob wirklich SetPixel der Flaschenhals ist. Im Zweifel bleibt dann IMHO nur noch DirectDraw.
-
Ich schick mal nen bisschen Code.
[HDC hdc;
//Initialisierung
...
//hdc = CreateCompatibleDC(NULL);
SelectObject(hdc,hbBitmap);for(y=0; y<500; y++)
for(x=0; x<800; x++)
SetPixelV(hdc,x,y,255);DeleteDC(hdc);
//Ausgabe auf Bildschirm
]Hier steckt noch nicht mal eine variable Beieinflussung der Pixel drin.
Aber trotzdem ist dies ist die Geschwindigkeit der Bildabfolge viel zu
gering. Es muss wohl an SetPixelV liegen.
-
Setz doch die Pixel direkt in das Bitmap.
mit
::GetBitmapBits(...)
bekommst du direkt die Daten und mit
::SetBitmapBits(...)
kannst du dann die veränderten Daten wieder an das Bitmap binden.
So kannst du ohne SetPixel() die dDaten des Bitmaps verändern.
Beispiel:
void CPicture::MakeGrayPicture() { if(!this->m_hObject) { TRACE( "CPicture::MakeGrayPicture Class not Initialised or not Picture Loaded\n"); return; } CPalette pal; UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256); LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300; pLP->palNumEntries = 256; for( int i=0; i < 256; i++) { pLP->palPalEntry[i].peRed = i; pLP->palPalEntry[i].peGreen = i; pLP->palPalEntry[i].peBlue = i; pLP->palPalEntry[i].peFlags = 0; } pal.CreatePalette( pLP ); BITMAP bm; CBitmap::GetObject(sizeof(BITMAP), (LPSTR)&bm); BYTE *bmpBuffer = new BYTE[ bm.bmWidthBytes*bm.bmHeight ];//allocate memory for image //byte buffer ULONG dwValue=CBitmap::GetBitmapBits(bm.bmWidthBytes*bm.bmHeight, bmpBuffer);//Get the bitmap bits //into a structure*/ DWORD* buffer = (DWORD*)bmpBuffer; for(ULONG Count = 0;Count < dwValue/4;Count++) { UINT Index = pal.GetNearestPaletteIndex(buffer[Count]); buffer[Count] = RGB(pLP->palPalEntry[Index].peRed, pLP->palPalEntry[Index].peGreen, pLP->palPalEntry[Index].peBlue); } delete[] pLP; dwValue = CBitmap::SetBitmapBits(bm.bmWidthBytes*bm.bmHeight,bmpBuffer); delete[] bmpBuffer; }
Gruß Matthias