Allegro Doublebuffering Problem -> Geschwindigkeitsverlust



  • So,nach längerer Abstinenz von c++ melde ich mich wieder zurück 🙂
    War deswegen länger nicht mehr in c++ aktiv,weil ich bei einem Contest für ein Minigolfspiel für B2D mitgemacht habe (dl-link: http://home.arcor.de/rambo256/Dateien/BB/BoRa Golf v. 1.0 public.rar ) .Der Contest ist nun zuende und die Jury bewertet nun, drückt mir die Daumen 😉
    Fange nun mit Allegro an,um wieder reinzukommen.

    So,nun aber weg vom Offtopic und nun zu meiner Frage:
    Wieso ruckelt das so stark?! Ich habe mir eine eigene Klasse geschrieben (cGraphics). Dort habe ich dann folgende Funktionen implementiert:

    void cls(BITMAP *buffer)
            {    
                 acquire_bitmap(buffer);             
                 clear(buffer);
    
            }
    
           void flip(BITMAP *buffer)
           {
    
                release_bitmap(buffer);
                blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H);
           }
    

    Diese brauche ich ja für das Double Buffering. Da dürfte rein Theoretisch kein Fehler drin sein.
    Nun zeige ich euch noch die Methode,mit der ich meine Bilder zeichne:

    void drawimage(BITMAP *buffer, BITMAP *Name, int x, int y, int width , int height)
           {
    
                masked_blit(Name, buffer, 0, 0, x, y, width, height);
    
           }
    

    Da dürfte eigentlich auch alles Ok sein. Nun mein Hauptcode:

    #include <allegro.h>
    #include "cInitAllegro.cpp"
    #include "cGraphics.cpp"
    
    cGraphics Graphics;
    cInitAllegro init_Allegro;
    
    int main(void)
    {
    
      init_Allegro.init(800, 600, 32, 0);
    
      BITMAP *buffer = create_bitmap(SCREEN_W,SCREEN_H);
      BITMAP *Ball = Graphics.loadimage("Ball.bmp");
    
      int x = 0;
      int y = 0;
    
      while(!key[KEY_ESC])
      {
    
        if(key[KEY_LEFT])
        {
           x = x-5;
        }
    
        if(key[KEY_RIGHT])
        {
           x = x+5;
        }
    
        if(key[KEY_UP])
        {
           y = y-5;
        }
    
        if(key[KEY_DOWN])
        {
           y = y+5;
        }   
    
        Graphics.cls(buffer);
    
        Graphics.drawimage(buffer,Ball,x,y,10,10);
    
        Graphics.flip(buffer);
    
      }
    
    destroy_bitmap(buffer);
    destroy_bitmap(Ball);  
    
    }
    
    END_OF_MAIN();
    

    So,nun was mir aufgefallen ist:
    Im 8-bit Modus: läuft alles sehr flüssig,genauso wie ich es wollte,nur es gibt keine Tranzparents.

    Ab 16Bit: Es ruckelt nur noch vor sich hin,zwar gibt es nun eine Tranzparents (lila wird nicht angezeigt),aber es ruckelt zu stark.

    Das kann doch nicht sein. Ich habe schon vieles ausprobiert,habe draw_sprite benutzt,etliches umgestellt usw... Auch die Forumssuche hat nichts gebracht.
    Nichts aber auch gar nichts hat geholfen. Ich wäre sehr dankbar für eure Hilfe.
    Mein Freund hat das gleiche Problem,also an meinem Rechner kann es schonmal nicht liegen,der ist mehr als ausreichend.



  • Weil deine HW oder SDL Scheisse ist?

    Bye, TGGC Deine Unterstützung wird gebraucht!



  • TGGC schrieb:

    Weil deine HW oder SDL Scheisse ist?

    Bye, TGGC Deine Unterstützung wird gebraucht!

    Also wenn du mit SDL das meinst, was ich darunter verstehe (simple directmedia layer), dann frag ich mich, wo er die eingebunden haben will. Ist nämlich garnich drin - falls Allegro nicht zufällig auf der SDL basiert, was ich in meiner momentanen Übermüdung nicht wirklcih sagen kann..)

    Dieses double buffering im Code versteh ich allerdings nicht wirklich. Du erstellst regelmäßig ein bitmap, renderst den buffer und löschst das Bitmap wieder?

    Also das klingt mir arg danach, dass dein BUS auf dem Mainboard 256 Bit breite braucht.
    Der Rechner geht da zwangsläufig in die Knie, weil du unkomprimierte Daten von 800 * 600 * 4 Byte = 1.920.000 Byte drei mal durch den Rechner jagst bevor du sie darstellst..

    Gibt es in Allegro keine Möglichkeit, den zweiten Buffer direkt in die Grafikkarte zu schreiben ?



  • Wahh, hast recht! Allegro ist ja wieder was Anderes. Nur die Performance scheint genau so mies zu sein, sonst gelten die "Meine Blit-Aufrufe sind zu langsam" ja immer der SDL.

    Bye, TGGC (Für echte Fans)



  • Also was ich jetzt nicht verstehe, wo erstelle/lösche ich denn andauernd Bitmaps?!
    Ich erstelle sie doch vor/nach der while-Schleife und nicht mittendrin.
    Das möchte ich mal erklärt haben 😉



  • also ich hab mich mit allegro noch nicht so sehr befasst, aber aquire_bitmap() deutet darauf hin, dass Speicher allokiert wird. während release_bitmap() danach klingt, den speicher wieder frei zu geben.

    @ TGGC - sowas kommt vor.. bei mir ständig.

    Die SDL ist übrigens ziemlich schnell, wenn man es richtig macht. Wenn mann allerdings anstelle den DirectX-Modus zu nutzen beim Initialisieren der SDL den Layer für die WinAPI nutzt, ist man selbst schuld..
    Naja, ich nutze die SDL auch nur zum Initialisieren von openGL, etc..



  • Ok,ich gehe heute erst mal in der Schule Karneval feiern und dann versuche ich mal,den Buffer mit draw_sprite direkt zu zeichnen (geht mit "screen").Hab das auch shcon genmacht und es läuft sehr schnell,aber da verfälschen sich die Werte der Farbtiefe,da muss ich nochmal nachhaken und schauen,wie man das bei der Funktion Draw_Sprite einstellt.
    Ich poste dann mal das ergebnis!



  • Joa, mache das. Immerhin soll das Forum nicht nur denen helfen die die Fragen stellen..



  • uhm.... also ich hab schon lang nix mehr mit Allegro gemacht, aber: lass einfach mal die Aufrufe von acquire_bitmap und release_bitmap weg, die brauchst du IIRC nur, wenn du per-pixel Aenderungen am Bitamp vornimmst!



  • Ne das bringt nichts. Das habe ich vorher schon ausprobiert.
    Ich bin gerade dabei die Palette zu setzen. Also damit der Draw_sprite befehl weiß,mit welchen Farbeinstellung er es zu tun hat. Normalerweise mache ich das ja schon bei initialisieren (set_color_depth()) aber das will nicht klappen. Muss dann die set_color() Funktion benutzen. Bin gerade am suchen,wie man sie richtig anwendet (Ja ich habe die Allegro-Hilfe 😉 ).



  • So,nun hab ich es geschafft.
    Habe jetzt eine Mischung aus Buffer und Pageflip gemacht (=Triplebuffer wenn ich mich nicht irre!).
    Falls interresse besteht,poste ich mal den Code für diejenigen die das Problem auch haben/bekommen.



  • ich würds einfach tun - gebrauchen könnens immer einige 😉



  • Einmal die Funktionen:

    void cls(BITMAP *active)
            {    
                 clear_to_color(active, makecol32(0, 0, 0));
    
            }
    
           void flip(BITMAP *active_page, BITMAP *page1, BITMAP *page2, BITMAP *buffer, int flip)
           {
    
                buffer = active_page;
    
                if (flip == 1 )
                {
                     vsync();
                }
    
                blit(buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H);
    
                if (active_page == page1)
                {
                     active_page = page2;
                }
                else
                {
                     active_page = page1;
                }
    
           }
    

    Und die Main.cpp:

    #include <allegro.h>
    #include "cInitAllegro.cpp"
    #include "cGraphics.cpp"
    
    cGraphics Graphics;
    cInitAllegro init_Allegro;
    
    int main(void)
    {
    
      init_Allegro.init(1024, 768, 32, 0);
    
      BITMAP *buffer = create_video_bitmap(SCREEN_W,SCREEN_H);
      BITMAP *Ball = Graphics.loadimage("Ball.bmp");  
    
      BITMAP *page1 = create_video_bitmap(SCREEN_W, SCREEN_H);
      BITMAP *page2 = create_video_bitmap(SCREEN_W, SCREEN_H);
      BITMAP *page3 = create_video_bitmap(SCREEN_W, SCREEN_H);
      BITMAP *active_page;
    
      active_page = page1;
    
      int x = 0;
      int y = 0;
    
      while(!key[KEY_ESC])
      {
    
        if(key[KEY_LEFT])
        {
           x = x-5;
        }
    
        if(key[KEY_RIGHT])
        {
           x = x+5;
        }
    
        if(key[KEY_UP])
        {
           y = y-5;
        }
    
        if(key[KEY_DOWN])
        {
           y = y+5;
        }   
    
        Graphics.cls(active_page);
    
        Graphics.drawimage(active_page,Ball,x,y,10,10);
    
        Graphics.flip(active_page, page1, page2, buffer,0);
    
      }
    
    destroy_bitmap(buffer);
    destroy_bitmap(Ball);
    destroy_bitmap(page1);
    destroy_bitmap(page2);   
    
    }
    
    END_OF_MAIN();
    

    Hoffe das es anderen hilft 🙂


Anmelden zum Antworten