Introdução ao Allegro Rodrigo de Toledo Luiz Fernando Estevão Allegro • Cor • Bitmap – Le, escreve, cria, destrói e limpa • Funções pixel a pixel • Funções de desenho vetorial – Linha, reta, triângulo, círculo • Funções de cópia da imagem • Funções de resize da imagem • Links úteis: – http://www.allegro.cc – http://www.dcc.ufrj.br/~abdalla/tut_arq/imagens.htm – http://www.allegro.cc/manual/ • Inicializações Allegro – Cor • Allegro trata as cores como um inteiro int makecol(int r, int g, int b); p.ex: int color = r*2562 + g*256 + b • Cada canal de cor pode variar de 0 a 255 • Exemplo int green_color = makecol(0, 255, 0); • Canal Alpha (transparência) int makeacol(int r, int g, int b, int a); Allegro – Pallete • O conceito de palheta de cores se aplica a imagens com limitação de cores (ex: 256 cores) • Em allegro existe o tipo pallete PALETTE palette; • Existem comandos específicos para pallete: – set_color (para alterar uma entrada) – get_color (para consultar uma entrada) – ... Red Green Blue 255 180 132 202 198 88 8 105 124 179 214 231 247 198 65 206 0 148 123 99 71 43 8 109 124 173 193 214 231 148 36 206 0 149 125 143 163 45 175 105 116 159 165 198 222 132 31 206 Allegro – Imagem • Em allegro há um tipo específico para imagem: BITMAP • Exemplo: BITMAP *img1, *img2; • Informações sobre a imagem: – Tamanho: img1->w; //width, largura da imagem img1->h; //heigth, altura da imagem – Outras: Em geral para uso interno nas funções de manipulação. (p.ex.: ponteiros para área de memória) Struct BITMAP typedef struct BITMAP { /* a bitmap structure */ int w, h; /* width and height in pixels */ int clip; /* flag if clipping is turned on */ int cl, cr, ct, cb; /* clip left, right, top and bottom values */ GFX_VTABLE *vtable; /* drawing functions */ void *write_bank; /* C func on some machines, asm on i386 */ void *read_bank; /* C func on some machines, asm on i386 */ void *dat; /* the memory we allocated for the bitmap */ unsigned long id; /* for identifying sub-bitmaps */ void *extra; /* points to a structure with more info */ int x_ofs; /* horizontal offset (for sub-bitmaps) */ int y_ofs; /* vertical offset (for sub-bitmaps) */ int seg; /* bitmap segment */ ZERO_SIZE_ARRAY(unsigned char *, line); } BITMAP; Allegro – Imagem Le, escreve • Leitura BITMAP* load_bitmap(const char *filename, PALLETE *pal); – Caso a imagem seja 24/32 bits (ou seja, sem pallete) ou se queira ignorar essa informação, é possivel ignorar o parâmetro. – Tipos aceitos: *.bmp, *.pcx, *.tga, *.lbm – Existem bibliotecas para incluir também: • *.png (loadpng.h) • *.jpeg (jpgalleg.h) – Exemplo: minha_img = load_bitmap(“flamengo.bmp",NULL); Allegro – Imagem Le, escreve • Escrita int save_bitmap(const char *filename, BITMAP *bmp, PALLETE *pal); – Exemplo: save_bitmap("c:\\eu\\mengao.bmp", minha_img, NULL); Allegro – Imagem cria, destrói e limpa • Para criar uma imagem nova: BITMAP* create_bitmap(int width, int height) • Apagando definitivamente uma imagem de memória: destroy_bitmap(BITMAP *bitmap) – Importante para não ocupar memória com lixo • Existem dois comandos para “limpar” a imagem – Com preto: clear(BITMAP *bitmap) – Com uma determinada cor: clear_to_color(BITMAP *bitmap, int color) – Exemplo: clear_to_color(bmp, makecol(255, 0, 0)); Boas práticas! - 1 • Assim como funções tipo malloc(): – Após criar ou carregar um BITMAP* deve-se verificar o sucesso ou fracasso na operação: • BITMAP* img = create_bitmap(100,100); • if(img == NULL){ – printf(“Erro ao criar BITMAP!\n”); – exit(-21); •} Boas práticas! - 2 • Ao destruir um ponteiro: – Após destruir um BITMAP* ele continua apontando lixo: • • • • BITMAP* img = create_bitmap(100,100); ... destroy_bitmap(img); img = NULL; – Importante: Ao sair do escopo, todas as variáveis locais são destruídas! Problemas: • Problemas de alias: – BITMAP* img1 = create_bitmap(100,100); – BITMAP* alias = img1; – destroy_bitmap(alias); – clear(img1); // fault! • Saiba quando é uma cópia e quando é um alias! Funções de desenho vetorial • Linha line(BITMAP *bmp, int x1, int y1, int x2, int y2, int color) • Retângulo – Apenas borda rect(BITMAP *bmp, int x1, int y1, int x2, int y2, int color) – Preenchido rectfill(BITMAP *bmp, int x1, int y1, int x2, int y2, int color) • Triângulo (sempre preenchido) triangle(BITMAP *bmp, int x1, int y1, int x2, int y2, int x3, int y3, int color) • Círculo circle(BITMAP *bmp, int x, int y, int r, int color) circlefill(BITMAP *bmp, int x, int y, int r, int color) • Outros: – Elipse, spline Funções de cópia da imagem • Copiando da origem (source) para destino blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, //coordenadas iniciais na origem int dest_x, int dest_y, //coordenadas iniciais no destino int width, int height) //dimensões do retângulo a ser copiado – Pode-se copiar parcialmente uma imagem – Cuidado com os limites de tamanho • A função blit irá jogar fora (não gera exceção) • Copiando como sprite: draw_sprite(BITMAP *dest, BITMAP *source, int x, int y) Sistema de Coordenadas • Orientação da tela. BLIT – block transfer • blit(img1,img2,x1,y1,x2,y2,larg,alt); img1 img2 Cor Neutra • makecol( 255, 0, 255 ); sprite1 SPRITE • clear_to_color( buffer, makecol(153, 217, 234) ); • draw_sprite( buffer, sprite1, sprite1->w, sprite1->h ); Máscara • blit(img1,saida,0,0,0,0,img1->w,img1->h); • draw_sprite(saida, masc,masc->w,masc->h); img1 masc + saida = BITMAP - Matriz de pixels • int getpixel( // retorna a cor do pixel BITMAP* bmp, int x, int y ); • void putpixel( BITMAP* bmp, int x int y, int cor ); // ponteiro para a imagem // posição do pixel // apenas altera a matriz // ponteiro para a imagem // posição do pixel // valor a ser colocado Animação! • Sequência de sprites Resize • int stretch_blit( – BITMAP* src, BITMAP* dest, – int x1, int y1, // início na fonte – int larg1, int alt1, // dimensões do bloco fonte – int x2, int y2, // início no destino – int larg2, int alt2 // dimensões do bloco dest. ); Visualmente falando: • x dest src Outras Funcionalidades – Rotação; – Inversão; – Floodfill; – Etc.. • www.allegro.cc Manipulação de Imagens Usando Allegro sem criatividade – Inicializações básicas para poder começar a trabalhar Onde baixar e como instalar Cara da aplicação int main (void){ if (!inicia()){ finaliza(); return -1; } anim(); finaliza(); return 0; }; END_OF_MAIN(); • Este é um esqueleto padrão usado. – Pode-se usar de muitas formas, mas esta é bem elegante e organizada. • Joga toda a dificuldade para fora do padrão de inicializações. • Esse esqueleto será disponibilizado. int inicia (void); int inicia (void){ allegro_init(); install_keyboard(); install_mouse(); install_timer(); /* if (install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL) < 0){ return FALSE; } // permite usar sons e musicas */ set_color_depth(CORES); // CORES eh um define // janela if (set_gfx_mode(GFX_AUTODETECT_WINDOWED, RESOL_X, RESOL_Y, 0, 0) < 0){ // tela cheia // if (set_gfx_mode(GFX_AUTODETECT, RESOL_X, RESOL_Y, 0, 0) < 0){ return FALSE; } if (CORES == 32){ set_alpha_blender(); // permite semi-transparencia } return TRUE; }; • CORES é definido fora – Aplicação com maior velocidade • menor nível de cores ( 8 ou 16 ) – Aplicação com maior qualidade • Maior nível de cores ( 24 ou 32 ) • Aplicação pode ser em tela cheia ou em janela • Aplicação pode ter sons e músicas – Usado em animações e jogos void finaliza (void); void finaliza (void){ allegro_exit(); }; • Não tem muito o que inventar aqui. • ... void inc_frame (void); volatile intframe; void inc_frame (void){ frame++; }END_OF_FUNCTION(inc_frame); • Serve apenas para animações. – Se não for para animar, não é necessário • Como o foco está em manipulação de imagem não é necessário aprofundar isso void anim (void); void anim (void){ /* declaracoes da aplicacao */ /**/ while (!key[KEY_ESC]); /* finalizacao da aplicacao */ /**/ }; Abobora • Aqui fica toda a graça! – Comandos e ações são inseridos aqui • O comando no meio está para impedir que o programa rode e feche direto. – Para encerrar o programa basta pressionar ESC – As imagens geradas podem ser visualizadas na própria aplicação. Includes importantes! • Para poder usar o Allegro • include<allegro.h> • Para poder usar strings • include<string.h> Compilando • • • • gcc -o saida.exe main.cpp -Wall -lalleg g++ -o saida.exe main.cpp -Wall -lalleg Importante que o path esteja definido! Colocar as *.dll’s junto da aplicação – alleg42.dll – alld42.dll – allp42.dll – Ou relativo a versão utilizada! Além da manipulação pura • O Allegro permite animações e não apenas manipulação de imagens estáticas. • A cara do anim() muda bastante quando for fazer uma animação. void anim (void); - com animação BITMAP *buffer, *trans_buffer; void anim (void){ /* -consideracoes iniciais- */ srand((time(NULL))); buffer = create_bitmap(screen->w,screen->h); trans_buffer = create_bitmap(screen->w,screen->h); /**/ /* declarando contador de atualizacao */ LOCK_VARIABLE(frame); LOCK_FUNCTION(inc_frame); install_int(inc_frame, FRAME); frame = 1; /**/ while (!key[KEY_ESC]){ if(frame > 0){ /* contadores de animacao */ frame = 0; /**/ /* rotinas de funcionalidade*/ if(k_bt(KEY_A)){ // faca algo } /**/ /* rotinas de limpeza (refresh) */ clear_to_color(buffer,PRET); clear_to_color(trans_buffer,MAGE); /**/ /* desenhando no buffer */ /**/ /* atualizando na tela */ draw_trans_sprite(buffer,trans_buffer,0,0); show_mouse(buffer); blit(buffer,screen,0,0,0,0,buffer->w,buffer->h); show_mouse(NULL); /**/ } } /* finalizando a aplicacao */ remove_int(inc_frame); destroy_bitmap(buffer); destroy_bitmap(trans_buffer); /**/ }; Funções Extras • Informações necessárias para interação – Entrada do mouse – Entrada do teclado • Permitem liberdade e usos pouco comuns • As funções dadas são meio confusas e pouco mnemônicas • Criação de funções mais fáceis de compreender e utilizar Teste de botão de mouse bool m_bt(const int &b){ return (mouse_b & b); }; • m_bt(1) • mouse_b & 1 Teste de botão do teclado bool k_bt(const int &k){ if(key[k]){ while(keypressed()){ clear_keybuf(); } return true; } return false; }; • k_bt(KEY_A); • key[KEY_A];