
1. Na pewno, bêd±c gdzie¶ w ciemnym miejscu,
i maj±c przy sobie latarkê ¶wiecili¶cie ni± aby rozja¶niæ sobie
widok. Je¿eli ¶wiecili¶cie na ¶cianê, na której by³y jakie¶ napisy
³atwiej by³o je odczytaæ. Fajne cieniowane kó³eczko pozwala³o nam
dostrzec to czego normalnie z ciemno¶ci nie widzimy. Rysunek pokazuje
jak to ma wygl±daæ. Bump jest to uzyskiwanie na p³askim ekranie
obrazu 3D. Lecz przyk³ad opisany w tym artykule dotyczy tylko i
wy³±cznie obrazu 2D. Efekt i tak jest wspania³y. Stworzyli¶cie rysunek
320x200x255 i chcecie by by³ o¶wietlany. Jest to bardzo proste lecz
oprócz jakiego¶ t³a potrzebne nam bêdzie jakie¶ ¶wiat³o, które te¿
trzeba narysowaæ. ¦wiat³o najlepiej jakby by³o cieniowane, bo wtedy
wychodzi najlepszy efekt. W tym przyk³adzie mamy oszczêdzon± robotê
je¶li chodzi o narysowanie t³a i ¶wiat³a (pliki: tlo.gfx i latarka.gfx).
Lecz same grafiki nic nam nie daj± trzeba tak¿e umieæ stworzyæ algorytm
ukazuj±cy t³o, ciemno¶æ i ¶wiat³o. Program dzia³a w bardzo prosty
sposób. Na ekranie jest rysowane ¶wiat³o o kolorach pobieranych
z tablicy ekran. Mo¿e jest to trochê nie zrozumia³e, ale je¶li przeczytasz
poni¿szy tekst to na pewno wiêcej zrozumiesz.
2. Najpierw trzeba otworzyæ t³o, czyli obrazek, który bêdzie o¶wietlany.
Trzeba tak¿e pamiêtaæ aby zawarto¶æ obrazka umie¶ciæ w tablicy 64000
KB.
type
ekran = array[0..319, 0..199] of byte;
Tablica potrzebna do umieszczenia w niej obrazka jest gotowa wiêc
teraz trzeba otworzyæ obrazek, a robi siê to tak.
procedure opentlo(plik : string; tlo : byte);
var
f : file;
b : array[0..319] of byte;
x, y : integer;
begin
assign(f,plik);
reset(f,1);
for x:=0 to 199 do
begin
blockread(f,b,320);
{przelewanie obrazka do tablicy}
for y:=0 to 319 do if b[y]<>tlo then begin putpixel(y,x,b[y]);
ekr^[y,x]:=b[y]; end;
end;
close(f);
end;
Wiemy ju¿ jak otworzyæ t³o, ale pozosta³o nam jeszcze ¶wiat³o.
procedure openpfile(x1, y1 : integer; plik : string; tlo : byte);
var f : file;
b, rx, ry : byte;
xx, yy : integer;
buf : array[1..321] of byte;
w, d : Word;
begin
assign(f,plik);
reset(f,1);
blockread(f,buf,2,w);
rx:=buf[1];
ry:=buf[2];
for yy:=1 to ry do
begin
blockread(f,buf,rx,w);
for xx:=1 to rx do if (buf[xx]<>tlo) then
{procedura rysuje rysunek poza kolorem tlo, pobieraj±c jednocze¶nie,
nr koloru odpowiadaj±cych punktów z tablicy ekran}
putpixel(xx+x1,yy+y1,(ekr^[xx+x1,yy+y1] div 50-(buf[xx])-3));
end;
close(f);
end;
3. Mamy ju¿ najwa¿niejsze procedury, dziêki którym stworzymy ¶wiec±c±
¶wiat³em latarkê. Pora zaj±æ siê stworzeniem ca³ego programu. Do
jego wykonania potrzebne nam bêd± zmienne:
var
ekr : ^ekran;
{zmienna typu ekran}
mx, my, k : integer;
{zmienne do myszki}
ax, ay : integer;
{zmienne pomocnicze}
i : integer;
{zmienna pomocnicza}
Ju¿ mamy wszystko, wiêc pora napisaæ program.
(!!!UWAGA!!! PROGRAM WYKORZYSTUJE UNIT HELPMOUS.TPU)
uses crt, helpmous;
type
ekran = array[0..319, 0..199] of byte;
var
ekr : ^ekran;
mx, my, k : integer;
ax, ay : integer;
i : integer;
procedure initvga; assembler;
asm
mov ax, 13h
int $10
end;
procedure closevga; assembler;
asm
mov ax, 03h
int $10
end;
procedure putpixel(x, y : integer; c : byte);
begin
mem[$a000:y*320+x]:=c;
end;
function getpixel(x, y : integer) : byte;
begin
getpixel:=mem[$a000:y*320+x];
end;
procedure bar(x, y, d, s : word; kolor : byte);
var
xx, yy : word;
begin
for xx:= x to d do
for yy:= y to s do
begin
putpixel(xx,yy,kolor);
end;
end;
procedure setcol(col : byte; r, g, b : byte);
begin
port[$3C8] := col;
port[$3C9] := r;
port[$3C9] := g;
port[$3C9] := b;
end;
procedure opentlo(plik : string; tlo : byte);
var f : file;
b : array[0..319] of byte;
x, y : integer;
begin
assign(f,plik);
reset(f,1);
for x:=0 to 199 do
begin
blockread(f,b,320);
for y:=0 to 319 do if b[y]<>tlo then begin putpixel(y,x,b[y]);
ekr^[y,x]:=b[y]; end;
end;
close(f);
end;
procedure openpfile(x1, y1 : integer; plik : string; tlo : byte);
var f : file;
b, rx, ry : byte;
xx, yy : integer;
buf : array[1..321] of byte;
w, d : Word;
begin
assign(f,plik);
reset(f,1);
blockread(f,buf,2,w);
rx:=buf[1];ry:=buf[2];
for yy:=1 to ry do
begin
blockread(f,buf,rx,w);
for xx:=1 to rx do if (buf[xx]<>tlo) then
putpixel(xx+x1,yy+y1,(ekr^[xx+x1,yy+y1] div 50-(buf[xx])-3));
end;
close(f);
end;
begin
new(ekr);
initvga;
opentlo('tlo.gfx',255);
for i:=0 to 255 do setcol(i,i,i,i);
bar(0,0,320,200,0);
bar(0,0,320,200,0);
mousewindow(5,5,210,90);
setmousepos(110,50);
mx:=5;
my:=5;
repeat
getmousepos(mx,my,k);
openpfile(mx,my,'latarka.gfx',255);
if (ax<>mx) or (ay<>my) then
begin
ax:=mx;
ay:=my;
bar(0,0,320,200,0);
end;
until keypressed;
closevga;
dispose(ekr);
end.
4. Program jest ³atwy w obs³udze i ma wiele zastosowaæ, lecz to
od ciebie zale¿y co to bêdzie...
Kod ¼ród³owy do artyku³u:
Bump Mapping (30 KB)