Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[Allegro] Podwójne buforowanie - obraz wciąż migocze

Ostatnio zmodyfikowano 2013-01-05 20:49
Autor Wiadomość
kilroy
Temat założony przez niniejszego użytkownika
[Allegro] Podwójne buforowanie - obraz wciąż migocze
» 2012-12-31 14:49:17
Zrobiłem program z ćwiczenia i migotanie nie ustępuje. Problem już miałem z wcześniejszym zadaniem. Jeśli nie czyściłem ekranu to ludek mi się ruszył tylko raz - i to skokowo (prawdopodobnie tylko do zakończenia pierwszej pętli, bo przestał się ruszać, gdy kolor tła się minimalnie zmienił), potem już wciskanie kursorów nie działało (ale ESC - działa).

W tym zadaniu miałem czyścić tylko bufor, ale to nie działa, bo ludek co prawda nie miga, ale też się nie porusza (to znaczy porusza się tylko raz - zanim przejdzie pierwsza pętla).

Więc postanowiłem też czyścić ekran i wtedy ludek się rusza, ale wraca problem migotania. Ktoś ma poradę? Trochę pomogło gdy dodałem do pętli zmienną liczbową, która dzięki funkcji "if" wywołuje czyszczenie ekranu co którąś pętlę. Jednak wydaje mi się, że są lepsze i skuteczniejsze metody uniknięcia migania.
P-72519
Admixior
» 2013-01-01 01:48:40
Jednak wydaje mi się, że są lepsze i skuteczniejsze metody uniknięcia migania.
Owszem są nazywa się to "podwójne buforowanie". A jeżeli takowe się zacina już po pierwszym to... sprawdź czy z dobrego bufora korzystasz, i czy wyświetlasz na ekran. Ewentualnie wstaw wadliwy kawałek kodu.
P-72580
kilroy
Temat założony przez niniejszego użytkownika
» 2013-01-01 15:53:54
Przede wszystkim dziękuję za odpowiedź

Tu jest program:

C/C++
#include <allegro.h>

volatile long speed = 0;
void increment_speed()
{
    speed++;
}
END_OF_FUNCTION( increment_speed );

LOCK_VARIABLE( speed );
LOCK_FUNCTION( increment_speed );

int main()
{
    int licz = 0;
    allegro_init();
    install_keyboard();
    set_color_depth( 16 );
    set_gfx_mode( GFX_AUTODETECT, 640, 480, 0, 0 );
    clear_to_color( screen, makecol( 0, 0, 0 ) );
    install_timer();
    install_int_ex( increment_speed, BPS_TO_TIMER( 400 ) );
   
   
    BITMAP * bufor = NULL;
    BITMAP * ludek = NULL;
    BITMAP * tlo_gry = NULL;
   
    bufor = create_bitmap( 640, 480 );
    clear_bitmap( bufor );
    if( !bufor )
    {
        set_gfx_mode( GFX_TEXT, 0, 0, 0, 0 );
        allegro_message( "Nie mogê utworzyæ bufora !" );
        allegro_exit();
        return 0;
    }
   
    ludek = load_bmp( "D:\\Programy\\Programowanie\\CodeBlocks/Moje\\Dodatki/Obrazki/ludek.bmp", default_palette );
    if( !ludek )
    {
       
        set_gfx_mode( GFX_TEXT, 0, 0, 0, 0 );
        allegro_message( "nie mogê za³adowaæ obrazka Ludek !" );
        allegro_exit();
        return 0;
    }
   
    tlo_gry = load_bmp( "D:\\Programy\\Programowanie\\CodeBlocks/Moje\\Dodatki/Obrazki/tlo.bmp", default_palette );
    if( !tlo_gry )
    {
       
        set_gfx_mode( GFX_TEXT, 0, 0, 0, 0 );
        allegro_message( "nie mogê za³adowaæ obrazka tlo !" );
        allegro_exit();
        return 0;
    }
   
    int ludek_x = 100, ludek_y = 100;
   
   
    while( !key[ KEY_ESC ] )
    {
        while( speed > 0 )
        {
            if( key[ KEY_LEFT ] ) ludek_x--;
           
            if( key[ KEY_RIGHT ] ) ludek_x++;
           
            if( key[ KEY_UP ] ) ludek_y--;
           
            if( key[ KEY_DOWN ] ) ludek_y++;
           
            speed--;
        }
       
        /*if (licz%1060==0)
            clear_to_color(screen, makecol(0,0,0));
        licz++;*/
        //rest(1);
       
        masked_blit( tlo_gry, bufor, 0, 0, 0, 0, 640, 480 );
       
       
        masked_blit( ludek, bufor, 0, 0, ludek_x, ludek_y, ludek->w, ludek->h );
       
        blit( bufor, screen, 0, 0, 0, 0, 640, 480 );
       
       
    }
    remove_int( increment_speed );
    destroy_bitmap( ludek );
    destroy_bitmap( bufor );
    destroy_bitmap( tlo_gry );
    allegro_exit();
    return 0;
}
END_OF_MAIN();

Jak już wspominałem jest taki sam jak w zadaniu.

Ciekawostka - dodałem tło i się poprawiło. Teraz mogę ruszać ludkiem cały czas, ale pozostaje problem - ludek, a właściwie jego poziome elementy (paski) z początkowego położenia zostawiają ślad na ekranie i przy poruszaniu ludka na wysokości tych pasków nie widać elementów ludka

Gdy dodam do programu czyszczenie ekranu co pewien czas ślady znikają, ale jest mignięcie ekranu, a ludek zostawia ślad w innym miejscu znowu do momentu czyszczenia ekranu.
P-72602
Mrovqa
» 2013-01-01 16:10:01
a właściwie jego poziome elementy (paski) z początkowego położenia zostawiają ślad na ekranie
Wygląda na to, iż nie czyścisz bufora (nie pisałem w Allegro, więc nie powiem co dokładnie jest źle).
P-72608
Gabes
» 2013-01-01 16:12:20
Pętla główna: zasada-czyszczenie bufora co obieg pętli.

C/C++
while( !key[ KEY_ESC ] )
{
   
    //czyszcimy bufor nie screen (nasza bitmapa wielkości ekranu) podanym kolorem (tu kolor czarny)
    clear_to_color( bufor, makecol( 0, 0, 0 ) );
   
    // tu dajemy funkcje sterujące, wyświetlające
   
    if( key[ KEY_RIGHT ] ) ludek_x++;
   
    masked_blit( tlo_gry, bufor, 0, 0, 0, 0, 640, 480 ); // tło
    masked_blit( ludek, bufor, 0, 0, ludek_x, ludek_y, ludek->w, ludek->h );
   
    // a tu wyświetlanie wszystkiego czyli naszego bufora (bitmapy) na screen (na ekran)
   
    blit( bufor, screen, 0, 0, 0, 0, 640, 480 );
   
}
P-72609
kilroy
Temat założony przez niniejszego użytkownika
» 2013-01-01 16:19:28
Ok, czyszczę bufor, ale nic to nie zmienia. Problem ze śladami pozostaje.

C/C++
while( !key[ KEY_ESC ] )
{
    while( speed > 0 )
    {
        if( key[ KEY_LEFT ] ) ludek_x--;
       
        if( key[ KEY_RIGHT ] ) ludek_x++;
       
        if( key[ KEY_UP ] ) ludek_y--;
       
        if( key[ KEY_DOWN ] ) ludek_y++;
       
        speed--;
    }
    /*if (licz%1060==0)
        clear_to_color(screen, makecol(0,0,0));
    licz++;*/
    //rest(1);
    clear_to_color( bufor, makecol( 0, 0, 0 ) );
    masked_blit( tlo_gry, bufor, 0, 0, 0, 0, 640, 480 );
    masked_blit( ludek, bufor, 0, 0, ludek_x, ludek_y, ludek->w, ludek->h );
    blit( bufor, screen, 0, 0, 0, 0, 640, 480 );
}

To możliwe, że problem wynika z tego w jakim systemie operacyjnym pracuję? Mam Win7, mój kompilator to Code::blocks 12.11, Allegro jak w instrukcji kursu - 4.2.2
P-72616
RazzorFlame
» 2013-01-02 07:11:51
Mam kilka pytań. Masz komputer 16 bitowy? O.o
BPS_TO_TIMER ustawileś na 400 co przy moim (słabym) komputerze wynosiło ok 80-100
P-72673
unimator
» 2013-01-02 19:22:17
C/C++
set_color_depth( 16 );
//Spróbuj zamienić na:
set_color_depth( 32 );

A po drugie zobacz czy będzie działać bez timera. Czyli zakomentuj tą wewnętrzną pętle i oraz --speed;
P-72762
« 1 » 2
  Strona 1 z 2 Następna strona