Flimmern



  • Kann mir keiner sagen, wie ich den 2. Punkt umsetzte?



  • Um das löschen des Fensters zu verhindern, wenn man ein Update macht, muß man beim Aufruf der CWnd::RedrawWindow() Methode folgende Flags übergeben:

    RDW_INVALIDATE | RDW_UPDATENOW
    

    z.B. in der CDialog-Klasse:

    this->RedrawWindow(NULL, rgn, RDW_INVALIDATE | RDW_UPDATENOW);
    

    Weitere Infos gibts in der MSDN.

    Ich hab nochmal in ein älteres Projekt von mir rein geschaut, dort hab nämlich in das ganze Fenster gezeichnet und auch einen Backbuffer benutzt und flimmert auch nicht.

    Erstmal einen globalen Backbuffer (kann man auch in eine Klasse kapseln) angelegt:

    CDC *backbuffer = NULL;
    

    Einmalig wird dann der Backbuffer initialisiert, mit einem Dummy-Bitmap das die gewünschte Größe hat (kann man im Resource-Editor erstellen):

    CBitmap bitmap;
    bitmap.LoadBitmap(IDB_BITMAP1);
    BITMAP bm;
    bitmap.GetObject(sizeof(bm), &bm);
    
    CDC *dc = new CClientDC(cDialog);
    backbuffer = new CDC();
    backbuffer->CreateCompatibleDC(dc);
    backbuffer->SelectObject(&bitmap);
    

    In diesen backbuffer blittet man dann immer rein und wenn man fertig ist, kopiert man den Backbuffer in das Fenster:

    CDC *dc = cDialog->GetWindowDC();
    dc->BitBlt(0, 0, 640, 480, backbuffer, 0, 0, SRCCOPY);
    


  • Blitten ist eigentlich auf dem PC falsch. Damals gab es auf dem Amiga, dem Sega Mega Drive und später dem Atari STE (der ST hatte noch keinen) einen Chip, der Speicherbereiche kopieren konnte, ohne Performanceverlust natürlich. Dieser Chip hieß Blitter. Vorzugsweise wurde dieser Blitter dafür benutzt Bitmaps auf den Screen bzw. Backbuffer zu kopieren. Die CPUs hätten das damals in dem Tempo nicht geschafft.

    Der Blitter ist Teil des Agnus-Grafikchips vom Amiga und eine Abkürzung für "Block-Image-Transferer", was soviel heißt wie Grafikblockverschieber. Der Name "Blitter" hat schon eine recht lange Tradition und beruht auf der Prozedur "BitBlt" (bit block transfer), die es auf einem älteren Computer der Firma XEROX gab. Diese Prozedur war für das schnelle Verschieben "rechteckiger" Bereiche in einer Bitmap zuständig. Und da die für den Amiga entwickelte Hardware-Einheit innerhalb von Agnus genau dasselbe tut, lag es nahe, diesen Namen zu verwenden. Jay Miner, der Designer der drei Amiga-Chips, ist in dieser Hinsicht anderer Meinung. Der Blitter des Amiga kann auch wirklich einiges mehr, als nur Daten hin- und herzuschieben. Jay nennt ihn deshalb Bimmer für Bit Image Manipulator.

    Aus historischen Gründen sagt heute jeder Blitten, auch wenn niemand wirklich weiß, wer die Grafiken kopiert (macht unter Windows die CPU, bei OpenGL und DirectGraphics wird der 3D-Chip benutzt, und die haben keinen Blitter).



  • @TheBigW
    Alles mit OpenGL machen??? Warum einfach wenn es auch kompliziert geht. In OpenGL braucht man im 2D-Bereich um einiges mehr Code als wenn man einfach einen MemDC verwendet... Bei komplexen Spielen im 3D-Bereich ist OpenGL sicher ratsam aber für 2D-Spiele würde ich in jedem Fall DirectDraw etc. verwenden. Naja, weniger Code als in OpenGL ist DirectDraw auch nicht. Schon gut, ich hör ja schon auf... Muss jeder selbst entscheiden. Für Brett- oder Kartenspiele die GDI, für Jump&Run Direct Draw und für EgoShooter OpenGL...würde ich sagen. Hab mit OpenGL noch nicht soviel Erfahrung im Spiele-Bereich...noch nicht 😃
    Boah, ich bin ja am senden... SCHRECKLICH 🙄



  • OPenGL ist einfacher als die GDI, einfacher als DirectX, einfacher als alles andere! 😃 Nein, im ernst. OpenGL ist wirklich einfach, da es sehr logisch und sehr "lesbar" ist. Und im 2D-Bereich braucht man nicht mehr Code als für DX oder GDI. Mit ein paar Funkrtionen schaltet man in den 2D-Modus bzw. man schaltet die Perspektive aus. Und schon kann man Vierecke mit Texturen zeichnen, ganz easy. Man kann sogar Layer benutzen, da es weiterhin den Z-Buffer gibt, jedoch ohne das die Perspektive in Kraft tritt. Soll heißen, was man in der Z-Kooridnate 10.0 zeichnet, ist genauso groß wie auf Z-Koordinate 0.0.

    Ich code auch ein Jump&Run komplett in MESA (freier OpenGL-Clone), funzt wunderbar. 🙂



  • CDC *backbuffer = NULL;

    Einmalig wird dann der Backbuffer initialisiert, mit einem Dummy-Bitmap das die gewünschte Größe hat (kann man im Resource-Editor erstellen):
    C/C++ Code:
    CBitmap bitmap;
    bitmap.LoadBitmap(IDB_BITMAP1);
    BITMAP bm;
    bitmap.GetObject(sizeof(bm), &bm);

    CDC *dc = new CClientDC(cDialog);
    backbuffer = new CDC();
    backbuffer->CreateCompatibleDC(dc);
    backbuffer->SelectObject(&bitmap);
    C/C++ Code:
    CBitmap bitmap;
    bitmap.LoadBitmap(IDB_BITMAP1);
    BITMAP bm;
    bitmap.GetObject(sizeof(bm), &bm);

    CDC *dc = new CClientDC(cDialog);
    backbuffer = new CDC();
    backbuffer->CreateCompatibleDC(dc);
    backbuffer->SelectObject(&bitmap);
    C/C++ Code:
    CBitmap bitmap;
    bitmap.LoadBitmap(IDB_BITMAP1);
    BITMAP bm;
    bitmap.GetObject(sizeof(bm), &bm);

    CDC *dc = new CClientDC(cDialog); 
    backbuffer = new CDC(); 
    backbuffer->CreateCompatibleDC(dc); 
    backbuffer->SelectObject(&bitmap);  
    
    In diesen backbuffer blittet man dann immer rein und wenn man fertig ist, kopiert man den Backbuffer in das Fenster: 
    C/C++ Code: 
    CDC *dc = cDialog->GetWindowDC(); 
    dc->BitBlt(0, 0, 640, 480, backbuffer, 0, 0, SRCCOPY);  
    C/C++ Code: 
    CDC *dc = cDialog->GetWindowDC(); 
    dc->BitBlt(0, 0, 640, 480, backbuffer, 0, 0, SRCCOPY);  
    C/C++ Code: 
    CDC *dc = cDialog->GetWindowDC(); 
    dc->BitBlt(0, 0, 640, 480, backbuffer, 0, 0, SRCCOPY);
    

    Was ist hier mit cDialog gemeint? Help danke



  • Ist eine Variable vom Typ CDialog, würde ich mal behaupten.



  • und wie erstellt man diese?



  • Mit dieser Zeile :

    cDialog->GetWindowDC();
    

    Holst du den Device Context des Windows cDialog, welcher nichts anderes ist als z.B. dein MainWindow oder ein SubWindow....

    Cheers



  • Falls es noch nicht klar ist.
    Bsp:

    Du hast eine Klasse A (CA) und eine Klasse B(CB);
    Du erstellst in Klasse B ein Objekt der Klasse A mit

    CA classA;    //classA ist nun das Objekt, genau wie cDialog!!!
    

    Nun kannst du wie oben auch dir das DC holen. 😉


Anmelden zum Antworten