Doublebuffer: Finde den Fehler nicht!



  • Moin, moin,

    folgender Code liefert mir nur einen schwarzen Bildschirm:

    static void drawpoints(struct state *st) {
    	HDC hdc = GetDC(st->window);
    	HDC hdcMem = CreateCompatibleDC(hdc);
    
    	// in den Buffer (hdcMem) zeichnen
    
    	// erstmal alles schwarz machen
    	FillRect(hdcMem, &myScreenSize, (HBRUSH)GetStockObject(BLACK_BRUSH));
    
    	// und Punkte in den Buffer zeichnen
    	for (int i = 0; i < st->npoints; i++) {
    		SetPixel(hdcMem, st->pointbuf[i].x, st->pointbuf[i].y, st->colours[st->ccolour]);
    	}
    
    	// und wusch und swap
    	BitBlt(hdc, 0, 0, myScreenSize.right, myScreenSize.bottom, hdcMem, 0, 0, SRCCOPY);
    
    	ReleaseDC(st->window, hdcMem);
    	ReleaseDC(st->window, hdc);
    
    	DeleteDC(hdcMem);
    	DeleteDC(hdc);
    
    	st->ccolour++;		// nächster Farbdurchlauf
    	st->npoints = 0;	// Pointbuffer zurücksetzen
    }
    

    Das setzen der Pixel direkt in den DC (also hdc anstatt hdcMem) funktioniert übigens hervorragend - flackert natürlich wie Wild!

    Jemand spontan ein Idee?

    --
    Beste Grüße
    Timmix



  • Hoi,

    Also erstmal bringst du die Aufrufe von ReleaseDC und DeleteDC drucheinander ⚠ :

    -> GetDC/ReleaseDC
    -> CreateCompatibleDC/DeleteDC

    Zweitens musst du in hdcMem ne Bitmap einsetzen in die gezeichnet wird 💡
    Hier bitte auch beachten:

    MSDN zu SelectObject(...) schrieb:

    This function returns the previously selected object of the specified type. An application should always replace a new object with the original, default object after it has finished drawing with the new object.

    und drittens -falls das immer noch nix bringt- prüf mal den Return-Wert (vllt auch mit GetLastError) von GetDC ( ➡ Stimmen die Werte von st->window und myScreenSize ?).



  • CodeFinder schrieb:

    ( ... )
    Zweitens musst du in hdcMem ne Bitmap einsetzen in die gezeichnet wird 💡
    ( ... )

    Heyho,

    super scheint jetzt zu funktionieren! Danke.

    Allerdings flackert folgendes immer noch wie wild:

    static void drawpoints(struct state *st) {
    	HDC                hdc        = GetDC(st->window);
    	static HBITMAP     hBitmap    = CreateCompatibleBitmap(hdc, myScreenSize.right, myScreenSize.bottom);
    	static HDC         hdcMem     = CreateCompatibleDC(hdc);
    
    	ReleaseDC(st->window, hdc);
    
    	SelectObject(hdcMem, hBitmap);
    
    	// erstmal alles schwarz machen
    	FillRect(hdcMem, &myScreenSize, (HBRUSH)GetStockObject(BLACK_BRUSH));
    
    	// und Punkte im Buffer zeichnen
    	for (int i = 0; i < st->npoints; i++) {
    		SetPixel(hdcMem, st->pointbuf[i].x, st->pointbuf[i].y, st->colours[st->ccolour]);
    	}
    
    	// Swap Buffer
    	BitBlt(hdc, 0, 0, myScreenSize.right, myScreenSize.bottom, hdcMem, 0, 0, SRCCOPY);
    
    	st->ccolour = 16;	// Todo: Farbdurchlauf (ccolour++)
    	st->npoints = 0;	// Pointbuffer zurücksetzen
    }
    

    ... verstehe ich nicht, ich zeichne doch im Speicher? Könnte das flackern daran liegen, dass ich derzeit (noch) den gesamten Bildschirm "blitte"?



  • timmix schrieb:

    ... verstehe ich nicht, ich zeichne doch im Speicher? Könnte das flackern daran liegen, dass ich derzeit (noch) den gesamten Bildschirm "blitte"?

    Hm jo daran kann das liegen^^...den ganzen Bildschirm uji^^....

    Naja hier vllt noch n paar Tipps:
    1. Probier mal das:

    // in der WndProc:
    case WM_ERASEBKGND:
       return (1L);
    

    2. Setze die beiden Style CS_HREDRAW und CS_VREDRAW nicht in deiner WNDCLASSEX-Strukur, falls du überhaupt mit Std-Fenstern arbeitest.

    Dann vllt. nochwas:
    Wenn du die Funktionen sehr oft hintereinander aufruft, ist der Double-Buffer-Effekt natürlich weg 😉 , ist klar.


Anmelden zum Antworten