Graj±c w Jazz Jack Rabbit nie mo¿na nie ulec
ciekawym efektom graficznym. Bo nie w ka¿dej grze z okresu <
1998 widaæ takie rzeczy. Szczególnie zainspirowa³a mnie transparencja...
Transparencja to po prostu przezroczysto¶æ. Chodzi mi o wy¶wietlanie
jakiego¶ obrazka na tle innego, z tym, ¿e wy¶wietlany obrazek bêdzie
nieco prze¶witywa³.
Okazuje siê, ¿e tak¿e i my mo¿emy zrobiæ taki efekt, co wiêcej to
wcale nie jest trudne.
Paleta
Tutaj bêd± nam potrzebne wszystkie odcienie jakiego¶ koloru, np.
czerwonego. Naj³atwiej by³oby zrobiæ tak:
For i := 0 To 255 Do SetCol(i, i Div 4, 0, 0);
Ale taka paleta to marnotrawstwo! Pamiêtajmy bowiem, ¿e karta VGA
pozwala na wy¶wietlenie do 64 odcieni danego koloru, a nie 256.
Dlatego te¿ do stworzenia tego i wielu innych efektów (np. bump
mapping) wystarczy taka paleta:
For i := 0 To 63 Do SetCol(i, i, 0, 0);
Tym sposobem mamy jeszcze 192 kolory do dyspozycji. Mo¿emy je po¶wiêciæ
na np. napisy, czy te¿ na t³o, które nie musi byæ wype³nione odcieniami
tylko jednego koloru.
Zmienne, sta³e, typy
Najwa¿niejszy jest w tym efekcie bufor ramki. Co to oznacza? Wiele
gier wykorzystuje tê technikê. A wszystko po to, aby do minimum
ograniczyæ bezpo¶rednie zapisywanie do pamiêci karty. Dziêki temu
unikniemy migotania obrazu, a sam program bêdzie znacznie szybszy.
Type
ScreenArray = ^ScreenType;
ScreenType = Array[0..63999] Of Byte;
Var
Screen : ScreenArray;
Potrzebne s± jeszcze dwie dodatkowe tablice. W pierwszej bêdzie
t³o, w drugiej za¶ przezroczysty obrazek. Pierwsza tablica bêdzie
tego samego typu, co bufor ramki, tak wiêc piszemy:
Var
Image1 : ScreenArray;
Druga tablica bêdzie wymaga³a odrêbnego typu. Bêdzie on podobny
do bufora ramki, z tym, ¿e bêdzie mia³ rozmiar szeroko¶ci nak³adanego
obrazka pomno¿onej przez jego wysoko¶æ i ca³a ta liczba musi byæ
zmniejszona o jeden. Przyk³adowo obrazek bêdzie mia³ rozmiar 128x128:
Type
Image2Array = ^Image2Type;
Image2Type = Array[0..16383] Of Byte; { 16383 = 128 x 128 - 1 }
Var
Image2 : Image2Array;
Potrzebne bêd± jeszcze liczniki:
Var
i, x, y : Word;
oraz parê tymczasowych zmiennych:
Var
TempCol : Byte;
LX, LY : Word;
Inicjalizacja
Najpierw tworzymy w pamiêci konwencjonalnej wszystkie tablice, pisz±c:
New(Screen);
New(Image1);
New(Image2);
S± one po³o¿one poza standardowym segmentem danych programu, tak
wiêc bez tych trzech instrukcji komputer siê zawiesi.
Teraz trzeba wyzerowaæ wszystkie tablice, aby unikn±æ "zaszumionego"
ekranu:
FillChar(Screen^[0], 64000, 0);
FillChar(Image1^[0], 64000, 0);
FillChar(Image2^[0], SizeOf(Image2^), 0);
Nastêpnie musimy zapisaæ w Image1 t³o, za¶ w Image2 nak³adany obrazek.
Nie bêdê bawi³ siê w prezentowanie sposobów na za³adowanie pliku
BMP, PCX, czy GIF, ale wygenerujê obrazki w programie.
For x := 0 To 319 Do
For y := 0 To 199 Do Image1^[320 * y + x] := x Xor y;
For i := 0 To 16383 Do Image2^[i] := Random(10) + 40;
Tak by³oby najpro¶ciej i chyba najlepiej.
Oczywi¶cie przed u¿yciem instrukcji Random trzeba j± zainicjalizowaæ
poprzez instrukcjê Randomize i sprawdziæ, czy program u¿ywa modu³u
CRT.
G³ówna pêtla
Teraz najlepsze! Musimy stworzyæ pêtlê Repeat..Until, a w niej umie¶ciæ,
co nastêpuje:
1. Wyczy¶ciæ bufor ramki
2. Umie¶ciæ w buforze ramki t³o
3. Nanie¶æ przezroczysty obrazek:
a) wpisaæ do zmiennej TempCol kolor piksela z t³a, na który ma byæ
naniesiony piksel z drugiego obrazka
b) obliczyæ nowy kolor metod±:
- pomno¿yæ warto¶æ zawart± w TempCol przez kolor aktualnie nak³adanego
piksela
- podzieliæ wynik przez 63
- je¿eli wykorzystuje siê tylko pierwsze 64 kolory, to podzieliæ wynik
przez 4
- finalny punkt - do bufora ramki
4. Przenie¶æ zawarto¶æ bufora ramki na ekran
Uff. Nie wiem, czy zrozumiale t³umaczê, ale na pewno da siê co¶
z tego wyci±gn±æ.
Efekt latarki
W tytule wspomnia³em o latarce. No wiêc, sposób tworzenia takiego
efektu jest bardzo podobny do przedstawionego wy¿ej algorytmu. Wystarczy
tylko:
1 .W tablicy Image2 umie¶ciæ obrazek przypominaj±cy ciemniej±c± po
brzegach kulê
2. Nie przenosiæ t³a do bufora ramki
To wystarczy, aby uzyskaæ zupe³nie inny efekt!
Nak³adany obrazek mo¿na odczytaæ z pliku, mo¿na go tak¿e wygenerowaæ
w programie metod± cieniowania Phonga (Phong shading). Procedura
jest zawarta w kodzie ¼ród³owym.
Kod ¼ród³owy do artyku³u:
Transparencja (7,30 KB)