Temat: Bitmapy, wczytywanie plików, double buffer 1 Wstęp

Transkrypt

Temat: Bitmapy, wczytywanie plików, double buffer 1 Wstęp
Grafika komputerowa 2D
Instrukcja
laboratoryjna
6
Temat: Bitmapy, wczytywanie plików, double buffer
Przygotował: dr inż. Grzegorz Łukawski, mgr inż. Maciej Lasota, mgr inż. Tomasz
Michno
1 Wstęp teoretyczny
Biblioteka Allegro wraz z wywołaniem funkcji set_gfx_mode tworzy w pamięci bitmapę
o nazwie screen, reprezentującą obszar ekranu na którym można rysować. Biblioteka dostarcza
również możliwość tworzenia własnych bitmap przez użytkownika. Możemy je podzielić na:
•
Memory Bitmap (standardowa bitmapa przechowywana w pamięci RAM)
•
Sub Bitmap (bitmapa potomna, będąca częścią bitmapy-rodzica)
•
Video Memory Bitmap (specjalny rodzaj bitmap, wykorzystywany np. w grach,
dostosowany do sprzętowego wspomagania niektórych operacji)
•
System Bitmap (specjalny rodzaj bitmap, który zawiera część cech zwykłych bitmap (np.
przechowywanie w pamięci RAM) oraz bitmap typu video)
Więcej o różnicach pomiędzy powyższymi typami bitmap:
http://www.allegro.cc/manual/4/api/bitmap-objects/
Każda bitmapa w Allegro jest reprezentowana przez typ BITMAP, który ma następującą strukturę:
typedef struct BITMAP
int w, h;
int clip;
int cl, cr, ct, cb;
unsigned char *line[];
- size of the bitmap in pixels
- non-zero if clipping is turned on
- clip rectangle left, right, top,
and bottom
- pointers to the start of each line
1.1 Tworzenie bitmap
Bitmapy można tworzyć wywołując funkcję CreateBitmap:
BITMAP *create_bitmap(int width, int height);
gdzie:
width – szerokość
height – wysokość
1/6
Jeśli tworzenie zakończyło się pomyślnie, funkcja zwraca wskaźnik na bitmapę, w przeciwnym
wypadku wartość NULL.
Utworzone bitmapy należy zawsze usuwać z pamięci za pomocą funkcji destroy_bitmap:
void destroy_bitmap(BITMAP *bitmap);
Inne przydatne funkcje:
BITMAP *create_bitmap_ex(int color_depth, int Utworzenie zwykłej bitmapy o podanej
width, int height);
w parametrze color_depth głębi kolorów
BITMAP
*create_sub_bitmap(BITMAP Utworzenie sub-bitmapy, jako parametry
*parent, int x, y, width, height);
należy podać: wskaźnik na bitmapę- rodzica,
oraz prostokąt obcinający - punkt startowy
(x,y) oraz rozmiar (width, height)
BITMAP *create_video_bitmap(int width, int Utworzenie bitmapy typu video-bitmap
height);
BITMAP *create_system_bitmap(int width, int Utworzenie bitmapy systemowej
height);
void set_clip_rect(BITMAP *bitmap, int x1, int Ustawienie prostokąta obcinającego dla
y1, int x2, int y2);
bitmapy
1.2 Obsługa plików graficznych
Biblioteka Allegro posiada zaimplementowane funkcje służące do odczytu i zapisu plików
graficznych. Obsługiwane formaty to: BMP, PCX, TGA i LBM.
Do wczytywania bitmapy służy funkcja load_bitmap:
BITMAP *load_bitmap(const char *filename, RGB *pal);
gdzie:
filename – ścieżka dostępu do pliku
pal – tablica (o rozmiarze 256), która będzie przechowywała paletę obrazu; można użyć zmiennej
typu PALETTE.
Każdą wczytaną bitmapę należy po użyciu usuwać z pamięci za pomocą destroy_bitmap.
2/6
Przykład użycia (zaczerpnięty z dokumentacji: http://www.allegro.cc/manual/4/api/loading-imagefiles/load_bitmap):
BITMAP *bmp;
PALETTE palette;
...
bmp = load_bitmap("image.pcx", palette);
if (!bmp)
abort_on_error("Couldn't load image.pcx!");
...
destroy_bitmap(bmp);
Bitmapy można zapisywać do pliku za pomocą save_bitmap:
int save_bitmap(const char *filename, BITMAP *bmp, const RGB *pal);
gdzie:
filename – ścieżka do pliku do zapisu
bmp – wskaźnik na bitmapę, która ma zostać zapisana
pal – paleta (można ją uzyskać za pomocą funkcji get_palette(PALETTE p)).
1.3 Kopiowanie prostokątnych obszarów pomiędzy bitmapami
W celu skopiowania prostokątnego obszaru jednej bitmapy do drugiej bitmapy, wywołujemy
funkcję blit:
void blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int
width, int height);
gdzie:
source – bitmapa źródłowa
dest – bitmapa docelowa (bitmapa źródłowa i docelowa może też być tą samą bitmapą)
source_x, source_y – lewy górny punkt kopiowanego obszaru
dest_x, dest_y – lewy górny punkt obszaru docelowego
width, height – szerokość i wysokość prostokąta
Funkcja blit jest wykorzystywana w technice Doble Buffering'u (Podwójnego Buforowania). Polega
ona na używaniu do płynnego wyświetlania obrazu na ekranie dwóch buforów o tym samym
rozmiarze. Bufory wyświetlane są na ekranie naprzemiennie, przy czym rysowanie klatki odbywa
się zawsze na niewidocznym buforze. Dzięki temu unika się m. in. migotania obrazu i artefaktów.
W bibliotece Allegro jednym buforem może być bitmapa screen, a drugim dowolna bitmapa
o rozmiarze ekranu. Obraz rysowany jest na drugiej bitmapie, a następnie za pomocą funkcji blit
3/6
jest kopiowany na ekran (pierwszą bitmapę – screen).
1.4 Duszki – Sprite'y
Sprite'y są specjalnymi rodzajami bitmap, które najczęściej służą do tworzenia postaci lub innych
elementów wyświetlanych na ekranie (np. z wykorzystaniem transformacji 2D). W bibliotece
Allegro obsługuje się je identycznie jak zwykłe bitmapy. Dodatkowo udostępnione są następujące
funkcje:
void draw_sprite(BITMAP *bmp, BITMAP Rysuje sprite'a na bitmapie bmp w punkcie
*sprite, int x, int y);
określonym przez x oraz y
void stretch_sprite(BITMAP *bmp, BITMAP Pozwala narysować sprite'a, zmieniając jego
*sprite, int x, int y, int w, int h);
rozmiar. Parametry:
w – nowa szerokość
h – nowa wysokość
void rotate_sprite(BITMAP *bmp, BITMAP Rysuje sprite'a obróconego o kąt angle
*sprite, int x, int y, fixed angle);
void pivot_sprite(BITMAP *bmp, BITMAP Rysuje sprite'a obróconego
*sprite, int x, int y, int cx, int cy, fixed angle);
względem punktu cx, cy
o kąt
void
draw_sprite_v_flip(BITMAP
BITMAP *sprite, int x, int y);
*bmp, Rysuje sprite'a z obróceniem pionowym
void
draw_sprite_h_flip(BITMAP
BITMAP *sprite, int x, int y);
*bmp, Rysuje sprite'a z obróceniem poziomym
void draw_sprite_vh_flip(BITMAP
BITMAP *sprite, int x, int y);
*bmp, Rysuje sprite'a
i poziomym
z obróceniem
angle
pionowym
void rotate_scaled_sprite(BITMAP *bmp, Rysuje sprite'a obróconego o kąt angle oraz
BITMAP *sprite, int x, int y, fixed angle, fixed przeskalowanego przez współczynnik scale
scale);
void pivot_scaled_sprite(BITMAP *bmp, Rysuje sprite'a obróconego o kąt angle
BITMAP *sprite, int x, int y, int cx, int cy, fixed względem punktu cx, cy oraz przeskalowanego
angle, fixed scale);
przez współczynnik scale
void stretch_blit(BITMAP *source, BITMAP Funkcja blit z możliwością zmiany rozmiaru
*dest, int source_x, source_y, source_width, prostokąta na bitmapie docelowej
source_height, int dest_x, dest_y, dest_width,
dest_height);
4/6
Przezroczystość:
Przezroczystość można uzyskać na kilka sposobów, jednak do narysowania sprite'a należy użyć
funkcji:
void draw_trans_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y);
Rysuje ona sprite'a z ustawionym wcześniej kolorem przezroczystości. Przykład (pochodzący
z dokumentacji http://www.allegro.cc/manual/4/api/blitting-and-sprites/draw_trans_sprite):
COLOR_MAP global_trans_table;
create_trans_table(&global_trans_table, my_palette,
128, 128, 128, NULL);
// ustawienie koloru przeroczystości
...
if (get_color_depth() == 8)
color_map = &global_trans_table;
else
set_trans_blender(128, 128, 128, 128);
draw_trans_sprite(buffer, ghost_sprite, x, y);
Można również skorzystać z kanału alfa wczytanej bitmapy (format TGA) poprzez włączenie
odpowiedniego trybu za pomocą funkcji:
void set_alpha_blender();
2 Zadania
1. Napisać program, który narysuje na ekranie monitora jedną z figur geometrycznych (np. trójkąt,
kwadrat, okrąg). Program powinien wykonywać dowolną animację danej figury (np. rotacja,
przesuwanie, skalowanie, odbijanie od brzegów). Wykorzystaj do tego celu double-buffer.
2. Napisać program, który wczytuje dowolną obsługiwaną bitmapę z pliku (samodzielnie
stworzoną). Program powinien wykonywać rotację, skalowanie, odbicie danej bitmapy w zale ności
od wciśniętego klawisza. Proponowana obsługa klawiatury:
• r, R – rotacja;
• s, S – skalowanie;
• p, P – rotacja względem punktu;
• v, V – odbicie pionowe;
• h, H – odbicie poziome;
5/6
• o, O – odbicie pionowe i poziome;
• t, T – rotacja ze skalowaniem;
• k, K – rotacja względem punktu ze skalowaniem;
• x - reset (przywrócenie oryginalnej bitmapy);
• ESC - wyjście.
3. Napisać program, który wczyta dwie dowolne obsługiwane bitmapy z pliku. Przetestuj
i zaprezentuj działanie przezroczystości (alpha – channel).
6/6