Conheça a iniciativa da Biblioteca dos Desenvolvedores  
Índice da Biblioteca  
Área dos Usuários  
Fórum de Discussão  
Forúm
 
 

25 - Double Buffer - Técnica de desenhar na tela

Quando começamos a desenhar vários objetos primitivos na tela, e movemos ele atraves do teclado ( na execução do jogo ) ou mesmo animamos figuras .bmp, muitas vezes percebemos que a imagem do jogo fica piscando.

O Nome deste efeito é flicker, onde o monitor acaba imprimindo uma tela em preto antes da nova imagem do jogo ser desenhada na variável screen ( variável que representa o monitor no Allegro ). Formando a impressão de que a tela está piscando.

Para resolver este problema, utilizamos a tecnica de Double Buffer, ou seja, criar um buffer ( lugar de armazenamento ) aonde desenhamos tudo o que deve ser desenhado na tela, e só depois que tudo estiver desenhado no buffer, ai sim, imprimimos o buffer na tela ( screen ).

Desta forma, a tela ( screen ) vai ter sempre a ultima imagem gerada para ela. E enquanto tudo não for desenhado no buffer, a tela continua sendo a antiga. Assim a tela não irá piscar mais.

Esse problema geralmente acontece quando o movimento do objeto for muito rápido ou quando a tela é atualizada antes de todos os objetos serem desenhados no screen.

A tecnica de double buffer no allegro é bem simples e também vale para qualquer outra biblioteca gráfica ( aqui estamos dizendo, o exemplo está em allegro, mais você pode usar em DX ou Open GL )

 

Exemplo sem Double Buffer:

Possivelmente o quadrado vermelho e os textos ficarão piscando em sua tela


CÓDIGO...
// Colisão com os cantos da tela
#include <allegro.h>

int main()
{
   allegro_init();
   set_color_depth(16);
   install_keyboard();
   set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0);
   
   
   // inicio da programação atual
   int x = 0;
   int y = 0;
   
   // dimensao do quadrado
   // variáveis constantes nunca mudam durante a execução do programa
   const int tamanho = 100;
   
   
   // Laço principal
   while( !key[KEY_ESC] )
   {
      if ( key[KEY_UP] )
      {
         y--;
      }
      
      if ( key[KEY_DOWN] )
      {
         y++;
      }
      
      if ( key[KEY_LEFT] )
      {
         x--;
      }
      
      if ( key[KEY_RIGHT] )
      {
         x++;
      }
      
      // esta função limpa a tela ou um objeto que tem buffer no allegro
      clear( screen );
      
      // escrevemos um quadrado na tela na posição x e y que podem ter sido modificadas
      rectfill( screen, x, y, x+tamanho, y+tamanho, makecol(255, 0, 0) );
      
      // imprimimos as coordenadas x e y na tela para o usuário ver
      textprintf_ex( screen, font, 10, 10, makecol(255,0,0), -1, "Variavel X: %d", x);
      textprintf_ex( screen, font, 10, 20, makecol(255,0,0), -1, "Variavel Y: %d", y);
      
      // essa função faz o allegro esperar um pouco antes de voltar para o while
      rest(10);
   }
   
   
   allegro_exit();
   return 0;
}
END_OF_MAIN();


FIM DE CÓDIGO...

 

Exemplo com Double Buffer


CÓDIGO...
// Colisão com os cantos da tela
#include <allegro.h>

int main()
{
   allegro_init();
   set_color_depth(16);
   install_keyboard();
   set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0);
   
   
   // inicio da programação atual
   int x = 0;
   int y = 0;
   
   // dimensao do quadrado
   // variáveis constantes nunca mudam durante a execução do programa
   const int tamanho = 100;
   
   
   // Criando BUFFER, ela é um ponteiro para um BITMAP, pode ter qualquer nome
   BITMAP *buffer = NULL;
   buffer = create_bitmap(800,800);
   
   
   // Laço principal
   while( !key[KEY_ESC] )
   {
      if ( key[KEY_UP] )
      {
         y--;
      }
      
      if ( key[KEY_DOWN] )
      {
         y++;
      }
      
      if ( key[KEY_LEFT] )
      {
         x--;
      }
      
      if ( key[KEY_RIGHT] )
      {
         x++;
      }
      
      // limpa o nosso novo buffer
      clear( buffer );
      
      // escreve o quadrado no buffer
      rectfill( buffer, x, y, x+tamanho, y+tamanho, makecol(255, 0, 0) );
      
      // imprimimos as coordenadas x e y na tela para o usuário ver no buffer
      textprintf_ex( buffer, font, 10, 10, makecol(255,0,0), -1, "Variavel X: %d", x);
      textprintf_ex( buffer, font, 10, 20, makecol(255,0,0), -1, "Variavel Y: %d", y);
            
      // imprime o buffer na tela
      blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H);
      
      // essa função faz o allegro esperar um pouco antes de voltar para o while
      rest(10);
   }
   
   
   allegro_exit();
   return 0;
}
END_OF_MAIN();

FIM DE CÓDIGO...

DICA...

Existe uma função da allegro que faz a sincronização vertical, evitando também o efeito de flicker.
O nome da função é vsync();

Utilize ele antes de imprimir o buffer na tela( screen ).

vsync();
blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H);

Download do exemplo 1 - Clique Aqui

Download do exemplo 2 - Clique Aqui




Contribuidor
Adriano Waltrick
10/07/2007


 

« Anterior

 

Próximo »

 
 

01/06/2007 (C) Copyright. Todos os Direitos Reservados. Leia a política de privacidade do portal.
É proibida a cópia de conteúdo deste site de acordo com a Lei Brasileira de Direitos Autorais.