490 likes | 699 Views
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:
E N D
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);
Red Green Blue 255 0 0 180 148 149 132 123 125 202 99 143 198 71 163 88 43 45 8 8 175 105 109 105 124 124 116 179 173 159 214 193 165 231 214 198 247 231 222 198 148 132 65 36 31 206 206 206 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) • ...
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 – ImagemLe, 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 – ImagemLe, escreve • Escrita int save_bitmap(const char *filename, BITMAP *bmp, PALLETE *pal); • Exemplo: save_bitmap("c:\\eu\\mengao.bmp", minha_img, NULL);
Allegro – Imagemcria, 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); img2 img1
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, // ponteiro para a imagem int x, int y // posição do pixel ); • void putpixel( // apenas altera a matriz BITMAP* bmp, // ponteiro para a imagem int x int y, // posição do pixel int cor // 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
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(); };
void inc_frame (void); volatile int frame; 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];