Wykorzystanie wskaźników w grafice.




W tym dziale zajmiemy się procedurami graficznymi kopiującymi część ekranu do bufora pamięci. Buforem pamięci będzie zmienna bitmapa typu pointer. Pointer jest predefiniowanym typem wskaźnikowym, którego zmienne nie wskazują danych żadnego określonego typu. Są one jednakże zgodne z dowolnym innym typem wskaźnikowym. Do kopiowania fragmentów ekranu z wykorzystaniem bufora pamięci służą procedury GetImage i PutImage. GetImage umieszcza wybrany prostokątny fragment ekranu określony przez współrzędne lewego górnego narożnika i prawego dolnego narożnika w zarezerwowanym wcześniej obszarze pamięci.

 GetImage(x1,y1,x2,y2,bitmapa^);
X1, y1, x2, y2 są współrzędnymi wybranego do zapamiętania fragmentu ekranu, a bitmapa jest zmienną wskaźnikową oznaczającą adrespoczątku zarezerwowanego obszaru pamięci.
Przed wywołaniem procedury GetImage należy zarezerwować odpowiednio duży obszar pamięci. Do określenia rozmiarów tego obszaru służy funkcja ImageSize, która zwraca wartość typu Word.
Funkcja ta zwraca ilość bajtów potrzebnych do zapamiętania fragmentu ekranu określonego przez współrzędne jego lewego górnego narożnika i prawego dolnego narożnika.

 ImageSize(x1,y1,x2,y2);
Znajdujący się w pamięci obraz można umieścić w wybranym miejscu ekranu, określonym przez współrzędne jego lewego górnego narożnika za pomocą funkcji PutImage.

 PutImage(x1,y1,x2,y2,bitmapa^,opcja);
Argumentami funkcji oprócz parametrów lewego górnego rogu, są: adres obszaru pamięci zawierającego obraz oraz sposób kopiowania. Możliwe są tu następujące opcje określone stałymi:

  CopyPut
  XorPut
  OrPut
  AndPut
  NotPut
Działanie tych opcji ilustruje przykładowy program.

program grafika;
uses crt,graph;
var pic:pointer;
    x,y,x0,y0,r,karta,tryb:integer;
BEGIN
r:=31;
detectgraph(karta,tryb);
initgraph(karta,tryb,' ');
x0:=getmaxx div 2; y0:=50;
x:=x0+(r div 2); y:=y0-r+1;
settextstyle(0,0,1);
setfillstyle(1,15);
circle(x0,y0,r-1);
floodfill(x0,y0,15);
getmem(pic,imagesize(x0-r,y0-r,x0+r,y0+r));
getimage(x0-r,y0-r,x0+r,y0+r,pic^);
putimage(x,y,pic^,copyput);
outtextxy(150,y0,'CopyPut');
readkey;
freemem(pic,imagesize(x0-r,y0-r,x0+r,y0+r));

y0:=y0+95;
circle(x0,y0,r-1);
floodfill(x0,y0,15);
getmem(pic,imagesize(x0-r,y0-r,x0+r,y0+r));
getimage(x0-r,y0-r,x0+r,y0+r,pic^);
y:=y0-r+1;
putimage(x,y,pic^,xorput);
outtextxy(150,y0,'XorPut');
readkey;
freemem(pic,imagesize(x0-r,y0-r,x0+r,y0+r));

y0:=y0+95;
circle(x0,y0,r-1);
floodfill(x0,y0,15);
getmem(pic,imagesize(x0-r,y0-r,x0+r,y0+r));
getimage(x0-r,y0-r,x0+r,y0+r,pic^);
y:=y0-r+1;
putimage(x,y,pic^,andput);
outtextxy(150,y0,'AndPut');
readkey;
freemem(pic,imagesize(x0-r,y0-r,x0+r,y0+r));

y0:=y0+95;
circle(x0,y0,r-1);
floodfill(x0,y0,15);
getmem(pic,imagesize(x0-r,y0-r,x0+r,y0+r));
getimage(x0-r,y0-r,x0+r,y0+r,pic^);
y:=y0-r+1;
putimage(x,y,pic^,orput);
outtextxy(150,y0,'OrPut');
readkey;
freemem(pic,imagesize(x0-r,y0-r,x0+r,y0+r));

y0:=y0+95;
circle(x0,y0,r-1);
floodfill(x0,y0,15);
getmem(pic,imagesize(x0-r,y0-r,x0+r,y0+r));
getimage(x0-r,y0-r,x0+r,y0+r,pic^);
y:=y0-r+1;
putimage(x,y,pic^,notput);
outtextxy(150,y0,'NotPut');
readkey;

cleardevice;
putimage(x,y,pic^,copyput);
outtextxy(150,y0,'Wci˜nij klawisz..');

readkey;

freemem(pic,imagesize(x0-r,y0-r,x0+r,y0+r));
closegraph;
clrscr;
END.







A oto program wykorzystujący powyższe metody do bardziej rozrywkowego celu.

program grafika;
uses crt,graph,bgitoexe;
var pic,pic2:pointer;
    xx,yy,a,b,x,y,x0,y0,r,karta,tryb,d:integer;
BEGIN
dodajbgi;
r:=11;
d:=2*r;
detectgraph(karta,tryb);
initgraph(karta,tryb,' ');
settextstyle(0,0,1);
setfillstyle(1,15);

circle(100,100,r-1);
floodfill(100,100,15);
bar(200,100,205,6*r+100);
getmem(pic,imagesize(100-r,100-r,100+r,100+r));
getmem(pic2,imagesize(200,100,205,6*r+100));
getimage(100-r,100-r,100+r,100+r,pic^);
getimage(200,100,205,6*r+100,pic2^);
putimage(100-r,100-r,pic^,xorput);
putimage(200,100,pic2^,xorput);
b:=0;
yy:=0;
a:=7;
repeat

 for xx:=0 to getmaxx-2*r do begin
   if b<=yy then
           if yy<>getmaxy-2*r then begin
                                  putimage(xx,yy,pic^,xorput);
                                  putimage(0,yy-d,pic2^,xorput);
                                  putimage(getmaxx-r,yy-d,pic2^,xorput);
                                  delay(a);
                                  putimage(xx,yy,pic^,xorput);
                                  putimage(0,yy-d,pic2^,xorput);
                                  putimage(getmaxx-r,yy-d,pic2^,xorput);
                                  b:=yy;
                                  yy:=yy+1;
                                 end
                            else begin
                                  putimage(xx,yy,pic^,xorput);
                                  putimage(0,yy-d,pic2^,xorput);
                                  putimage(getmaxx-r,yy-d,pic2^,xorput);
                                  delay(a);
                                  putimage(xx,yy,pic^,xorput);
                                  putimage(0,yy-d,pic2^,xorput);
                                  putimage(getmaxx-r,yy-d,pic2^,xorput);
                                  b:=yy;
                                  yy:=yy-1;
                                 end
           else
           if yy<>0 then begin
                          putimage(xx,yy,pic^,xorput);
                          putimage(0,yy-d,pic2^,xorput);
                          putimage(getmaxx-r,yy-d,pic2^,xorput);
                          delay(a);
                          putimage(xx,yy,pic^,xorput);
                          putimage(0,yy-d,pic2^,xorput);
                          putimage(getmaxx-r,yy-d,pic2^,xorput);
                          b:=yy;
                          yy:=yy-1;
                         end
                    else begin
                          putimage(xx,yy,pic^,xorput);
                          putimage(0,yy-d,pic2^,xorput);
                          putimage(getmaxx-r,yy-d,pic2^,xorput);
                          delay(a);
                          putimage(xx,yy,pic^,xorput);
                          putimage(0,yy-d,pic2^,xorput);
                          putimage(getmaxx-d,yy-r,pic2^,xorput);
                          b:=yy;
                          yy:=yy+1;
                         end;
          end;

    for xx:=getmaxx-2*r downto 0 do begin
         if b<=yy then
            if yy<>getmaxy-2*r then begin
                          putimage(xx,yy,pic^,xorput);
                          putimage(0,yy-d,pic2^,xorput);
                          putimage(getmaxx-r,yy-d,pic2^,xorput);
                          delay(a);
                          putimage(xx,yy,pic^,xorput);
                          putimage(0,yy-d,pic2^,xorput);
                          putimage(getmaxx-r,yy-d,pic2^,xorput);
                          b:=yy;
                          yy:=yy+1;
                          end
                     else begin
                          putimage(xx,yy,pic^,xorput);
                          putimage(0,yy-d,pic2^,xorput);
                          putimage(getmaxx-r,yy-d,pic2^,xorput);
                          delay(a);
                          putimage(xx,yy,pic^,xorput);
                          putimage(0,yy-d,pic2^,xorput);
                          putimage(getmaxx-r,yy-d,pic2^,xorput);
                          b:=yy;
                          yy:=yy-1;
                          end
                else
                if yy<>1 then begin
                               putimage(xx,yy,pic^,xorput);
                               putimage(0,yy-d,pic2^,xorput);
                               putimage(getmaxx-r,yy-d,pic2^,xorput);
                               delay(a);
                               putimage(xx,yy,pic^,xorput);
                               putimage(0,yy-d,pic2^,xorput);
                               putimage(getmaxx-r,yy-d,pic2^,xorput);
                               b:=yy;
                               yy:=yy-1;
                             end
                        else begin
                              putimage(xx,yy,pic^,xorput);
                              putimage(0,yy-d,pic2^,xorput);
                              putimage(getmaxx-r,yy-d,pic2^,xorput);
                              delay(a);
                              putimage(xx,yy,pic^,xorput);
                              putimage(0,yy-d,pic2^,xorput);
                              putimage(getmaxx-r,yy-d,pic2^,xorput);
                              b:=yy;
                              yy:=yy+1;
                             end;
             end;

until keypressed;
closegraph;
end.