Práce s grafikou 640x480@16bit v Pascalu. (1/4)
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu
Reklama
Reklama

Práce s grafikou 640x480@16bit v Pascalu. (1/4)Práce s grafikou 640x480@16bit v Pascalu. (1/4)

 

Práce s grafikou 640x480@16bit v Pascalu. (1/4)

Google       Google       31. 1. 2006       17 294×

Popis grafické unity pro práci v grafickém módu 111h, (640x480x16bit) využívající virtuální obrazovku v XMS paměti. Obsahuje procedury pro práci s XMS, kreslení základních geometrických tvarů, grafický OutText a načítání obrázků ze souborů PCX (256barev).
Část 1. Základní procedury a funkce pro práci v grafickém módu 111h. (init grafiky, umístění pixelu, kreslení čar a kruhu)

Reklama
Reklama

Autor tohoto článku nenese žádnou odpovědnost za škody způsobené používáním těchto procedur, funkcí a programů. Článek je určen spíše pokročilejším programátorům se znalostí Pascalu a assembleru. To ovšem nevylučuje, že hotovou unitu může využívat začátečník. Seznam zdrojů a příklady ke stažení jsou umístěny na konci posledního dílu série.

Článků na toto téma již bylo na internetu napsáno mnoho. Jak však ukazují dotazy ve fórech (a spolužáků ve třídě), rozebraných příkladů není nikdy dost. Tato unita začala vznikat asi před rokem z touhy po poznání, dnes je v takovém stavu, že se dá bez problémů využít při vytváření programu pracujícím ve 2D grafice.

Grafický mód 111h jsem zvolil proto, že v rozlišení 640x480 při 16bitových barvách (65,5 tisíc barev) se již dá vytvořit relativně dobře vyhlížející grafika, pro barvu pixelu postačuje pouze 1 word a také, a nejspíš právě proto, že při psaní první verze této unity jsem měl na internátě pouze 486ku s 2MB grafikou, na které vyšší režimy nešly. (Dnes se tomu, že jsem v roce 2004 programoval na 486ce směju.)


Dopodrobna tady celou problematiku rozebírat nebudu, adresování video paměti při vyšších SVGA módech je přehledně popsáno v článku Zobrazování 24 bit. BMP od Petra Kučery na serveru pcsvet.cz

Init grafiky:


asm
   mov ah, 4fh
   mov al, 02h
   mov BX, 111h
   int 10h
   mov podpora,al
   mov vystup,ah
 end;

 if podpora<>$4f then Begin
     writeln('funkce nastaveni grafickeho modu neni podporovana..');
     exit;
 end;
 if vystup<>00 then Begin
     writeln('nepovedlo se inicializovat grafiku..');
     exit;
 end;

návrat do textového módu:


 asm
   mov ah,0h
   mov al,3
   int 10h
 end;

vykreslení pixelu:


procedure putPixel(x,y,barva:word);
{Tato procedura pise pixely primo do VRAM (nepouziva virtualni obrazovku)}
{Je pouzivana pro vykreslovani ukazatele mysi.}
var Bank,off:word;
    long:Longint;
Begin
{Pri pouziti vetsich rozlisenich a vetsim poctu barev nez v rezimu
 13h (320x200x256) nelze pristupovat k videopameti jako k celku. Standardne je totiz mozno zapisovat pouze do 65536 bytu pameti.
 Proto se pouziva tzv. Banku, ktere se prepinaji... Jeden bank
 ma standardne velikost 65536 bytu. }

  if (x>=Xmax) or (y>=Ymax) then exit;
  x:=x shl 1;
  long:=y;
  long:=(long*radek+x) shr 16;
  Bank:=long;
  {ekvivalent Bank:=(y*640+x) div 65536  }

  long:=y*radek;
  long:=long+x;
  long:=long-(Bank shl 16);
  off:=long;
  {ekvivalent Off:=(y*480+x) - Bank * 65536   }

  {Ted vime, v jakem banku a na jeke jeho pozici se zadany pixel nachazi. }
  {Pokud je tento Bank jiny nez ten, do ktereho jsme zapisovali posledne,
  musime jej zmenit. (Pokud nastavujeme bank pro kazdy pixel, priserne to
  zdrzuje..)}

  if predchozi<>Bank then Begin
    {nastavovani banku zdrzuje, proto jej nastavujeme
    jen tehdy, pokud se zmenil}
    asm
       xor bx, bx
       mov dx, BANK  { Nastav Bank }
       mov ax, 4f05h { Vesa funkce pro praci s okny }
       int 10h
    end;
  end;

  {     1         2}
  {     RRRR RGGG GGGB BBBB }
  { jsme v rezimu 16b, takze zelena ma 6 bitu a R a B 5bitu...}
  memW[SegA000:off]  :=barva;{2}
  predchozi:=Bank;
end;

Podobně je napsána i funkce pro zjištění barvy určitého pixelu:


function getPixel(x,y:word):word;
{ Cte hodnotu pixelu primo z VRAM a vraci jeho barvu }
var Bank,off:word;
    long:Longint;
Begin
  if (x>=Xmax) or (y>=Ymax) then exit;
  x:=x shl 1;
  long:=y;
  long:=(long*radek+x) shr 16;
  Bank:=long;
  {ekvivalent Bank:=(y*640+x) div 65536  }

  long:=y*radek;
  long:=long+x;
  long:=long-(Bank shl 16);
  off:=long;
  {ekvivalent Off:=(y*480+x) - Bank * 65536   }

  if predchozi<>Bank then Begin
    {nastavovani banku zdrzuje, proto jej nastavujeme
    jen tehdy, pokud se zmenil}
    asm
       xor bx, bx
       mov dx, BANK  { Nastav Bank }
       mov ax, 4f05h { Vesa funkce pro praci s okny }
       int 10h
    end;
  end;

  getPixel:=memW[SegA000:off];
  predchozi:=Bank;
end;

V grafickém módu 111h je pro barvu každého pixelu potřeba pouze 16bitů (1 word). Horních 5 bitů obsahuje hodnotu červené, dalších 6 zelené a dolních 5 bitů modré barvy. Pro převod barvy do 16bitového formátu ze tří barevných složek lze využít následující funkci:


function getColor(r,g,b:word):word;
{R G B jsou v rozsahu 0-255}
{vraci hodnotu barvy pouzitelne v 16bitove grafice}
Begin
  r := r shr 2;
  g := g shr 2;
  b := b shr 2;
  {rozsah 0-255 jsme si prevedli na 0-63}
  r:=(r shr 1) shl 11;        { 0000 0000 00II IIIX -> IIII I000 0000 0000}
  g:=(g shl 10)shr 5;         { 0000 0000 00II IIII -> 0000 0III III0 0000}
  b:=((b shr 1)shl 11)shr 11; { 0000 0000 00II IIIX -> 0000 0000 000I IIII}
  getColor := r or g or b;
end;

Čára

Pro vykreslení čáry se dá využít známého Bresenhamova algoritmu.


procedure Line(a,b,c,d:integer;barva:word);
{udela caru}
  function sgn(a:real):integer;
  begin
    if a>0 then sgn:=1
    else
      if a<0 then sgn:=-1
      else sgn:=0;
  end;

var
  i,s,d1x,d1y,d2x,d2y,u,v,m,n:integer;

begin
  u:= c-a;
  v:= d-b;
  d1x:= sgn(u);
  d1y:= sgn(v);
  m:= abs(u);
  n:= abs(v);
  if not(m>n) then
    begin
      d2x:= 0;
      d2y:= d1y;
      i:=m;
      m:=n;
      n:=i;
    end
  else
    begin
      d2x:= d1x;
      d2y:= 0;
    end;
  s:= m shr 1;
  for i:=0 to m do
    begin
      Pixel( a ,b,barva);
      s:= s+n;
      if not(s<m) then
        begin
          s:= s-m;
          a:= a+d1x;
          b:= b+d1y;
        end
      else
        begin
          a:= a+d2x;
          b:= b+d2y;
        end;
    end;
end;

Kruh

Pro vykreslení kruhu se dá použít Pithágorova věta. V cyklu for inkrementujeme y do doby než y = r. Při každém cyklu si podle vzorce x*x = r*r - y*y vypočítáme souřadnici x a do bodu [x,y] (posunutým o souřadnice středu) umístíme pixel zadané barvy. Aby jednotlivé body kružnice byly spojené, musíme vždy udělat vodorovnou čáru mezi posledními body. Tímto způsobem lze relativně rychle vykreslit čtvrtinu kružnice. Aby byla kružnice kompletní, musíme každý bod vykreslovat vždy 4x. (Jednou do každého kvadrantu.)

procedure kruh(xs,ys,r:longint; Barva:word);
{  Tato procedura vychazi ze vzorce: r*r = x*x + y*y  }
{************************************************************}
   function odmocnina(cislo:longint):longint;
   var vratit,mocnina:longint;
   begin
     vratit:=0;
     mocnina:=0;
     while mocnina < cislo do begin
       inc(vratit);
       mocnina:=vratit*vratit;
     end;
     odmocnina := vratit;
   end;
{************************************************************}
var X,Y,posledniX:longint;
Begin
  r := abs(r);
  Y := 0;
  posledniX := odmocnina( (r*r)-(Y*Y) );
  for Y:=0 to r do Begin
       x:= odmocnina( (r*r)-(Y*Y) );
       repeat
          Pixel( xs+posledniX,ys+Y,barva);
          Pixel( xs-posledniX,ys+Y,barva);
          Pixel( xs-posledniX,ys-Y,barva);
          Pixel( xs+posledniX,ys-Y,barva);
          dec( posledniX );
       until posledniX < x;
       posledniX := X;
  end;
end;

To by pro teď mohlo stačit. S těmito procedurami a funkcemi se již dá vytvořit nějaký graficky nenáročný program. Pokud chcete mít ale ve svém programu nějakou animaci, zjistíte, že ve většině případech není vykreslování objektů příliš rychlé a obraz problikává. Tento problém se řeší tzv. virtuální obrazovkou, kdy je obraz vykreslován nejdříve do RAM paměti a po jeho úplném vykreslení se rychle přenese do paměti grafické karty.

Při rozlišení 640x480 s 16bitovými barvami je pro takovou virtuální obrazovku potřeba 600 kB paměti. Vzhledem k tomu, že v DOSu je přímo adresovatelných pouze 640 kB (a z toho bývá asi jen polovina volná), musíme pro naši virtuální obrazovku využít XMS paměť. Jak to udělat, to si ukážeme v příštím díle.

×Odeslání článku na tvůj Kindle

Zadej svůj Kindle e-mail a my ti pošleme článek na tvůj Kindle.
Musíš mít povolený příjem obsahu do svého Kindle z naší e-mailové adresy kindle@programujte.com.

E-mailová adresa (např. novak@kindle.com):

TIP: Pokud chceš dostávat naše články každé ráno do svého Kindle, koukni do sekce Články do Kindle.

Hlasování bylo ukončeno    
0 hlasů
Google
Autor se zajímá o grafiku v Pascalu, také programuje v Pascalu, Delphi, PHP a Assembleru.

Nové články

Reklama
Reklama
Obrázek ke článku Nový IT hráč na českém trhu

Nový IT hráč na českém trhu

V roce 2015 otevřela v Praze na Pankráci v budově City Tower své kanceláře společnost EPAM Systems (NYSE:EPAM), jejíž centrála se nachází v USA. Společnost byla založená v roce 1993 a od té doby prošla velkým vývojem a stále roste.

Obrázek ke článku České Radiokomunikace opět hledají nejlepší nápady pro internet věcí

České Radiokomunikace opět hledají nejlepší nápady pro internet věcí

České Radiokomunikace (CRA) pořádají druhý ročník CRA IoT Hackathonů. Zájemci z řad vývojářů a fanoušků moderních technologií mohou změřit své síly a během jediného dne sestrojit co nejzajímavější funkční prototyp zařízení, které bude komunikovat prostřednictvím sítě LoRa. CRA IoT Hackathony se letos uskuteční ve dvou fázích, na jaře a na podzim, v různých městech České republiky. Jarní běh se odstartuje 31. března v Brně a 7. dubna v Praze.

Obrázek ke článku Cloud computing je využíván stále intenzivněji

Cloud computing je využíván stále intenzivněji

Využívání cloud computingu nabývá na intenzitě. Jen v letošním roce vzroste podle analytiků trh se službami veřejného cloudu o 18 %, přičemž o téměř 37 % vzrostou služby typu IaaS. Růst o více než pětinu pak čeká služby poskytování softwaru formou služby, tedy SaaS. Aktuálním trendům v oblasti využívání cloudu se bude věnovat konference Cloud computing v praxi, která se koná 23. března. 2017 v pražském Kongresovém centru Vavruška na Karlově náměstí 5.

loadingtransparent (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })();
Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032017 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý