 SU.GRAPHICS Frequently Asked Questions
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 3.
Date: 07 nov 1998. ("   -   ") :)


p:
-----------

   0. .
   1. .
     1.1.  () .
       1.1.1. Smooth/Blur (,  ).
       1.1.2.  .
       1.1.3. Emboss - ''.
       1.1.4. Motion Blur -    .
     1.2. .
       1.2.1. Median ( ).
       1.2.2. Maximum, minimum.
   2. .
   3. '' ('') .
   4.    /.
     4.1. Z-Buffer.
   5.    .
   6.     ().
     6.1. - .
     6.2.  .
     6.3. 'Magic Eye' -  .
     6.4.  .
   7.   .
     7.1.  .
   8.      (alpha-).
   9. -.
+> 10. Motion blur,   25    
         
+> *.  .
   **. .

:  +>  , *> - 
              FAQ.
------------------------------------------------------------------------------

    FAQ  - p - :

Alexey A. Monastyrenko,

2:5030/168.26@fidonet
2:5030/303.8@fidonet
2:5030/304.8@fidonet
aamonster@yahoo.com
http://monster.da.ru

FAQ    http://monster.da.ru
    SU.GRAPHICS.
===============================================================================


0. .
===============-

  -,   ,     .
 ,       -  RGB,
  ,  - - greyscale.
   RGB :
R[x,y], G[x,y], B[x,y] -   (, , ) 
   (x,y).
         -        
          R[x,y] 
C[x,y] =  G[x,y] 
          B[x,y] 
         L        -

     :
C[x,y] -        (x,y).

   -:
C[x,y]=I[x,y] -     (x,y).

      ,     .

*>   Dmitry Tjurev   faq   
      . C     [source: filename]

------------------------------------------------------------------------------

1. .
===========-

1.1.  () .
==================================-

    RGB  greyscale,    - 
( ,    RGB,    
   ,     ( ,
firelight, rainbow)   ).
    

C'[x,y] = D + Sum A[i,j]*C[i,j]
              i,j

(i,j - .  ,  -2  2.)
,      
   A -      
,     .

1.1.1. Smooth/Blur (,  ).
======================================================-
 p (y  )  p 
py  .  ppy
    +
  + * +
    +
  * y  4,  y p   +   y
  8 -    -py    p,  *.
   ,  p,  greyscale.  truecolor    
   (RGB, YUV  ..,   HSB).  p p
p  truecolor  y,    py.
  y - p p.
   y - averaging NxN - p  py NxN.

 - A[i,j]   
    - 0 1 0 
1/8* 1 4 1 
    L 0 1 0 -
(i,j  -1  1), D=0.


1.1.2.   (Edge Enhancement).
==============================================-
 A:               (D=0)
 -  0 -1  0 
  -1  5 -1 
 L  0 -1  0 -
(  -    1.  /
 ,   )


1.1.3. Emboss - ''.
===========================-
      - ,   ,  
(depth),       .
   PhotoStyler 1.0    .

depth=1:
        -       
A = 1/2* -1  0      D=128.
          0  1 
        L       -

depth=2:
        -          
         -1  0  0 
A = 1/2*  0  0  0      D=128.
          0  0  1 
        L          -

  .    -    -1  1.

, :  ,       -
     C[x,y] C[x-1,y-1]     128.


1.1.4. Motion Blur -    .
=====================================================-
 2 :  (Length)   (Angle),  ,
  .

     Length=3   :

        --             -
         0  0  0  0  0 
         0  0  0  0  0 
A = 1/3  0  0  1  1  1            D=0
         0  0  0  0  0 
         0  0  0  0  0 
        L-             --

1.2.  .
====================-

1.2.1. Median ( ).
=======================================-
  Median.    ( p). p    ,
ppy  , p p  py.
    greyscale.  p p yp py 
p   .  truecolor - y  p  
 p.
  y -   /y. py  py py
p,   p median filter.

1.2.2. Maximum, minimum.
========================-
    p maximum  minimum.  
y /   y /.
     py NxN.

2. .
===========-
 --------------------------------------------------- SU.GRAPHICS -
 From : Lout Roman         2:463/586.20    Sun 23 Nov 97 20:53
 To   : Dmitry Sorvachev                   Tue 25 Nov 97 15:12
 Subj : about morfing
 -----------------------------------------------------------------

 DS>     p 2D p ( p  p
 DS>  p)?  -  p   p  _p_
 DS> ?

    p,     p "p"
 p:
==========cut==========

MORPHING

       , ,  
   ""     
-  " ".    -
  ,      ,  -
   2 -    ,  
 ,       
    .     ?

         -   ""   
  ,       -
 ""    . , 
    ,   -
   .       
     -   
         
     ,   -
.        -  
  , , .     
 : warping, tweening  dissolving.
        Warping (, ) -  -
,          -
 -  -      .  
      
        ,
  .   warping'  
        -
.
        Tweening (  ) - -
       . ,
     ,   -
       -
.
        Dissolving (,   cross-dissolving  -  -
      ) -   -
,         -
        -
    .
             :

[skiped]
                                               . 1.

   warping'       
( , ,    ):

[skiped]
                                                . 2.

Tweening  warping   ,  
    (  
). Dissolving       -
.          -
  ,  ,     ,  
   . Dissolving  ,
       , 
 - .



              ,    
     .  -
    (mesh), :

[skiped]
[p, p    p]

                                . 3.

     ,   -
,   . , -
    ,       
. ,   ,    -
    ,          
( ,      ,    
).
            ,      () 
tweenig'          -
,   tweening  . Warping  
     ,   -
 .     :  ,   
     (x,y)   .   -
  ,     ,  
c.     :   -
   .
          ,    Douglas Smithe  
   "Willow" (1988),    -
  :    -
  x,    y.    :

[ p skiped.  p  p  ,
      -   ]

      :
       ,   
    ,     
-.         
         -   ,  
dissolving',      -
        ..  
        -  morfsrc.zip. 
     PC     -
    /    PC  sun SPARC
workstation,    .


    ?

        "      Heart-Quake/Iguana   (ftp.cdrom.com
pub/demos/demos/1994/heartq.zip)  -     -
 .       -
.     ,     486DX33 ?".
     ,    .  , -
     ,     ,
   Iguana.
          -   .  -
     ,      
       .
 -   256  .     -
    :     
,       . : -
  ,      
,   ,     -
   -      
.  ,      ,
 ,     -
.       .  
      
(,  - s_polybmp),    , -
      (s_poly2d).
         -      
.
          dissolving'  :    
 c=c1+(c2-c1)*t, 0<t<1,  1  c2 -   
  , t -  . ,   -
      RGB.   -
  Heart-Quake,     (  -
) ,   ,    
c=ColTable[c1,c2,t]        t=0..20   
256*256*20=1310720   (!).     -
 ,     
   , , , - 64.      
  81  (      
  ).  ,  
dithering    Heart-Quake ?

           Borland Pascal 7.0 for DPMI.  -
     256x256   9x9. - -
        -  
   .   -
 myvesa      .

[source: morph.pas]

.

1. morphscr.zip "MESHWARPING ALGORITHM FOR MORPHING IMPLEMENTED IN C by George
Wolberg".
2. DEMO.DESIGN.* Frequently Asked Questions, Release 9 () Peter Sobolev,
2:5030/84@fidonet.
3. Demo Heart-Quake/Iguana (ftp.cdrom.com pub/demos/demos/1994/heartq.zip)
4. Demo Stars/Noon (ftp.cdrom.com pub/demos/demos/1995/n/nooon_st.zip).

=========cut=============

3. '' ('') .
==================================-

   ''   .  
,    . ,  
:

[ Lenik Terenin, 2:5061/1 ]

r = pow( R, gammaR ) * 0.30;
g = pow( G, gammaG ) * 0.59;
b = pow( B, gammaB ) * 0.11;

distance = sqrt( r*r + g*g + b*b );

(-      r2-r1, g2-g1, b2-b1 - A.M.)

(  gamma   1.4-1.6,   
 PhotoStyler  1.4 - A.M.)

[Alexey Monastyrenko]
       YUV  


distance = sqrt( sqr(Y2-Y1)*4 + sqr(U2-U1) + sqr(V2-V1) );

Y = R*  0.29900  + G*  0.58700  + B*  0.11400
U = R*(-0.16874) + G*(-0.33126) + B*  0.50000  + 128
V = R*  0.50000  + G*(-0.41869) + B*(-0.08131) + 128
( , U  V  :-) )

[ Serguey Zefirov, 2:5020/620.15 ]
H   p:
   p     p  ,
,    (p  -  )  
.  Colorspace FAQ     p: G  
   p,  R  B p: p p
  ,    p   .
 ppp (p   )   R  B 
 .   ,      .
   pp p, , R - 6 p,
G - 8 p, B -  p. : 240 .  16  
p .

4.    /.
=================================================-

4.1. Z-Buffer.
==============-

  Z-buffer - p (imho)  p p y p
/p.

  p y: p p     y  
, p      (R,G,B   
p).   z-buffer y    py Z
( Z p ' y p).

--[ Dmitry Tjurev, 2:5061/15.49 ]
     ,  y   z,  1/z, .. 
    y    ,    z,
L-     y   y.

   , p.

1.   yp (z-buffer) pp  p -  ppy,
640x480,    (  p   - p  
y). py , ,  32767 (+infinity).

--[ Dmitry Tjurev, 2:5061/15.49 ]
     ,  ,  .  
  16- Z-y      
   .     y 
  yy       yy
   . 32- Z-y -  y,
       .
L-   .. y 1/z,     y.

2.   py ' y', ppy y ,  p
  (X,Y)  Z p  p  yp 
ZBuffer[X,Y],   p    Z<ZBuffer[x,y]. p 
p ZBuffer[x,y]:=z.

3. p y 2   . .

py zbuffer - p p p, p
  (   p y   
  BSP-trees),  p 'p'
. H - y yp (   y  p),
p    py py  p
( pp   ).

   z-buffer - s-buffer. py demo.design FAQ:

--8<--
S-Buffer -   ,   Z-Buffer,   y p
           p   ,  p p (
           p,   y) -. p 
           Span-Buffer (   Segment-Buffer).
--8<--

5.    .
=====================================-

  ULead PhotoStyler:
------------------------------------------
  p  N p:
   I := I+N*128/100;   {     0..255 - yp}
   {I -  R,G,B  }

  p  N p:
   I := (I*(100-N)+128*N)/100

  p  N p:
   I := (I*100-128*N)/(100-N)
L-----------------------------------------

  :
------------------------------------------
   ,  p :  p p  ,  pp
  p/p   p.
    :    pyy p, y  p y
 p  R,G,B ( p  0  255, ).
     pyy p  y y p:
    p   p ()  (! -   , 
  ),    :
 p +50% -   p y
               -50% -   2
 y  ..,    p py 0..255
   p  p p   p.
   :
 I := I+B
 C  0:  I := (I-Avg)*100/(100-C)+Avg
 C  0:  I := (I-Avg)*(100+C)/100+Avg

 I -    (r,g,b) (0..255)
 B -  pyp p (-100..+100)
 C -  pyp p (-100..+100)
 Avg - p  p  I.

   , ,    -   y  p,  p 
 .
    p   ,   Avg  p  p 128.
L-----------------------------------------


6.     ().
===================================================-
      ,    -
..       .


6.1. - .
=======================-

   -       -
      .
      

R[x,y]=Left[x,y] {   }
G[x,y]=0
B[x,y]=Right[x,y] {   }

   256-     
16 .      -
 .

    :   
      .

  -  - (, -).


6.2.  .
======================-

        .
   ,     2  ,  ,
     (, ,   
   :-) ).

   ,     ,  
     .   
    ,     
   ( ,  
  ).   
  ( ,   , 
 ).
        , 
      .

     Bohdan Afanasjev, 2:463/416.13.


6.3. 'Magic Eye' -  .
====================================-

  ,        - ,
     (    ),
   .
   -     .
   -   ,     .


--------+--------
        X - - - -+ z
       / \
      /   \
     /     \
----/-------\----   p
   /         \
  /           \
 /             \
()        ()


+  -  p,  z - ,  x - p
X  -  

p : (-b/2,L) - , (b/2,L) - p.
(L - p     py - ..  z=0)

 p 'y  '  p:
z_l = z_r = h  (h -  p   py)
x_l = x - (x - x_l_eye)*(h-z)/(L-z)          (1)
x_r = x - (x - x_r_eye)*(h-z)/(L-z)          (2)

. , ,    p x_l  x_r 
 - y  ,   y   py
.

p p  py (1),(2) p  p (e.g. 
) p p.

 p yp:
1. y z<<L, z<<h, h=C*L (C<1)
x_l ~= x - (x - x_l_eye)*C + (x - x_l_eye)*(z/h-z/L)
     = x*(1-C) + x_l_eye*C + (x - x_l_eye)*z/H         (1a)

1/H = 1/h - 1/L
H=h*L/(L-h)=h/(1-C); H ~ h

x_r ~= x*(1-C) + x_r_eye*C +(x-x_r_eye)*z/H            (2a)

x_r-x_l = b*C - b*z/H          (3)

(x_r+x_l)/2 = x*(1-C) + x*z/H  (4)

, p p  p

y_r = y_l = y*(1-C)    -   p.

2. p x p x_r (py p,  p
 - ..    p ).

.. z<<H, p  (2a)  . y
x_r = x*(1-C) + x_l_eye*C, y
x*(1-C) = (x_r - x_r_eye*C)   (5)

 x,y,z y p  x*(1-C), y*(1-C).  py
(5)  (3) py  
x = (x_r + b/2*C)
x_r-x_l = b*C - b*z/h.
Hpy ,  b*C - p pp  p p z=0.
  B.
,     y  x_r   py
x := x_r + B/2
z := z(x,y)
x_l := x_r - z*B/h
screen(x_r,y) := screen(x_l,y)

 p p/yp   p   x
  x_l  x_r  py (1a)  (2a) ( p  y
y p ),  p,  p 
y z  p y ( ppy,    'y
p'     0.


6.4.  .
====================-
[Dmitry Tjurev, 2:5061/15.49]
           -  
  ,    ,  .  
      .        
       .          
        
   ,      ,   ,
       . 
      3D-MAX.     ,      
   - ,    ,  
    ,     .
             (
        ,       - ).
   ,        
              .    
    3d-,        ,
,  3d studio. ,     
         
,   (     ;).
   -      . ..  
         . ,
        
  .          
,       -  
   .              
,  ..           
  (  ),    (
  ).

7.    .
==============================================-

7.1.  .
========================-
[Dmitry Tjurev, 2:5061/15.49]
            .   
             .
    ,       ( 
,    ,   )  
         ,  ,  
             .
           
         . ..
      (   )   
  ,           
  (           
).
    ,            
          .     
    ,         
   Ymin  Ymax,      
          (     
    ).
      ,        ,
          
  ?      .    
:    -    (, 10000),  -
  (  -10000).  ,  -  
  .     x-  
      ,    . ,
              x- 
.    ,           
  (    ),        .   
            ,         
  .        
           .
      .
          .  -,  ,  
          ,     
n-.     -    . .
      .     
  ?      ,         
               : x  y.
       :    x-
     y.            
       
                
           .    
                   
         
    .           
       (       
)    Z-.    -    
         -   (   
).           
.
             
   Z-. [source: simple.c]


8.      (alpha-).
=============================================================-
   C1[X,Y] - '' , C2[X,Y] - 
      Alpha[X,Y].
(Alpha=0 -   , Alpha=1 - ).
  
C = C1*Alpha + C2*(1-Alpha)
(  RGB  greyscale)

9. -.
===================-
  -  -    
/      .
   :
  1.       /
     - .
  2.     antialiasing' (,  ,  
      ).
  3.  dithering'     (    6 
          - '' 
       ,  -  ).

    256  -   :

  { }
  Port[$3C8] := ColorNum;
  Port[$3C9] := Round(63*Exp(Ln(R)/Gamma)); {R -  0  1}
  Port[$3C9] := Round(63*Exp(Ln(G)/Gamma)); {G -  0  1}
  Port[$3C9] := Round(63*Exp(Ln(B)/Gamma)); {B -  0  1}

     - py p  50% p  ' '
 p   ,    Gamma  , 
p p    .   
 [source: gamma.pas]
  , py  ,  p p  Corel Draw,  
p,   320x200     800x600.

10. Motion blur,   25    
      .                                  
============================================================-
 KM>>  - p (  Quake2)    p 
 KM>> 25 fps,    60 fps (   p),   
 KM>> ,   ,    p.

 MB>    . p  25  60 -- .

[Dmitry Tjurev, 2:5061/15.49]
    ru.game.design     y y. H  ,
  y,     . .., ,  
fps ,       ,
y    .  3d-y    , y
 y    yy  ,   25  60 fps
y  ,   25 fps     yy 
1 - 2 y ,   60 fps    y  y.
y     motion blur,   25     y .

*.  .
============================-
1. DEMO.DESIGN.* FAQ
   ftp://ftp.enlight.ru/pub/ 
>      .
>  ,    demo - ..  realtime :)
>   .

2. Artificial Intelligence Memo No. 239. February 29, 1972. HAKMEM
   ftp://ftp.netcom.com/pub/hb/hbaker/hakmem/hakmem.html
>    -    . __
>     .   -  ..  .
>   .


**. .
==================-

 ,   //   .
   ;). ,    
  :-).

Dmitry Tjurev               2:5061/15.49
Lout Roman                  2:463/586.20
Serguey Zefirov             2:5020/620.15
Lenik Terenin               2:5061/1
Peter Sobolev               2:5030/84

 FAQ    DEMO.DESIGN FAQ. ,   
      -  .

           
  -   .    -  .


-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
>> source: morph.pas <<
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-


{=========================================
  RealTime Morphing Demo  c Lut Roman 2:463\586.20
==========================================}

uses winapi,crt,myvesa;

type
 TGrate = array [0..8,0..8,1..2] of single;

{p    p}
function timercounter: longint; assembler;
asm
 mov es,seg0040
 mov ax,es:[$6c]
 mov dx,es:[$6c+2]
end;

var
 Image1,Image2       : word;
 Grate1,Grate2       : TGrate;
 x,y                 : integer;
 c                   : char;
 outImage1,outImage2,outImage3 : word;
 cr                  : boolean;
 s                   : string;

 var

{  pp linetextmap_simple_256}
 s_poly2d : array [1..4,1..2] of integer;
 s_polybmp : array [1..4,1..2] of byte;

{ }
 s_leftx : array [1..256] of integer;
 s_rightx : array [1..256] of integer;
 s_left_bmpxy : array [1..256] of integer;
 s_right_bmpxy : array [1..256] of integer;
 csalias      : word;

 s_scrbuf1seg : word; {  }
 s_bmpseg     : word; { }

{-------------- procedures ---------------}
 {$F+}
 {  ,     
 256x256}  procedure texturemap_simple_256; external; {$F-} {$L
 textmaps}

{      p  p    HSI  RAW  }
procedure  LoadImage(var  Image: word; fname: string); f: file;
begin
 assign(f,fname); reset(f,1);
 seek(f,800);
 Image:=globalalloc(gmem_fixed,65536);
 blockread(f,mem[Image:0],65535);
 blockread(f,mem[Image:65535],1);
 close(f);
end;

{ grayscale p}
procedure setbwpalette;
var
 i: integer;
begin
 for i:=0 to 255 do
     begin port[$3c8]:=i; port[$3c9]:=i  div  4;  port[$3c9]:=i
div 4; port[$3c9]:=i div 4;
     end; end;

{ p}
procedure showImage(Image: word;tx,ty: integer);
{.      256x256  ,  
     x,y }

{pp p}
procedure WarpPic(Grate1,Grate2: TGrate;Image,outImage:  word);
var
 x,y : integer;
begin
 s_scrbuf1seg:=outImage;          {          
 texturemap_simple_256} s_bmpseg:=Image; {  
 } csalias:=cseg+selectorinc;

 for y:=0 to 7 do
     for        x:=0        to        7        do         begin
s_polybmp[1,1]:=round(Grate1[x,y,1]);
s_polybmp[1,2]:=round(Grate1[x,y,2]);
s_polybmp[2,1]:=round(Grate1[x+1,y,1]);
s_polybmp[2,2]:=round(Grate1[x+1,y,2]);
s_polybmp[3,1]:=round(Grate1[x+1,y+1,1]);
s_polybmp[3,2]:=round(Grate1[x+1,y+1,2]);
s_polybmp[4,1]:=round(Grate1[x,y+1,1]);
s_polybmp[4,2]:=round(Grate1[x,y+1,2]);

      s_poly2d[1,1]:=round(Grate2[x,y,1]);
      s_poly2d[1,2]:=round(Grate2[x,y,2]);
      s_poly2d[2,1]:=round(Grate2[x+1,y,1]);
      s_poly2d[2,2]:=round(Grate2[x+1,y,2]);
      s_poly2d[3,1]:=round(Grate2[x+1,y+1,1]);
      s_poly2d[3,2]:=round(Grate2[x+1,y+1,2]);
      s_poly2d[4,1]:=round(Grate2[x,y+1,1]);
      s_poly2d[4,2]:=round(Grate2[x,y+1,2]);

      texturemap_simple_256;
     end; end;

{pp }
procedure WarpGrate(Grate1,Grate2:tGrate ;var Grate: tGrate; t:
single); var
 x,y: integer;
 r: single;
begin
 for y:=0 to 8 do
     for    x:=0    to    8    do    begin    r:=Grate1[y,x,1];
Grate[y,x,1]:=(Grate2[y,x,1]-r)*t+r;          r:=Grate1[y,x,2];
Grate[y,x,2]:=(Grate2[y,x,2]-r)*t+r;
     end; end;

{dissolving p}
procedure MorphPic(pic1,pic2,pic,t: word); assembler; asm
 push ds
 mov ax,pic1
 db 8eh,0e8h  {mov gs,ax}
 mov ds,pic2
 mov es,pic
 xor di,di
 mov si,t
 cld
 mov cx,0ffffh

 @@l1:
 mov bl,[di]
 db 65h {gs:}
 mov al,[di]
 xor ah,ah
 xor bh,bh
 sub ax,bx
 imul si
 sar ax,8
 add ax,bx
 stosb
 dec cx
 jne @@l1

 pop ds
end;

{ p pp}
procedure Morph;
var
 Grate : tGrate;
 i     : integer;
 dir   : boolean;
 r     : single;
 t     : longint;
 label l1,l2;
begin

dir:=true;
l1:
 for i:=0 to 30 do
     begin t:=timercounter; if dir then r:=i/30 else r:=1-i/30;
WarpGrate(Grate1,Grate2,Grate,r);
Warppic(Grate1,Grate,Image1,outImage1);
WarpPic(Grate2,Grate,Image2,outImage2);
MorphPic(outImage2,outImage1,outImage3,(Round(r*256)));
ShowImage(outImage,192,64);  if  KeyPressed then goto l2; while
timercounter-t<1 do; {}
     end;
     delay(6000);
     dir:=not dir; goto l1; l2: while KeyPressed do ReadKey; end;

{p   }
procedure loadGrate (Fname: string);
var
 f:file;
begin
 assign(f,fname); reset(f,1);
 blockread(f,Grate1,sizeof(TGrate));
 blockread(f,Grate2,sizeof(TGrate));
 close(f);
end;

begin
 if paramcount<>3 then halt;
 SetVesaMode($100);   {    p    640x400x256}
 SetBWPalette;       {       grayscale       p}
 LoadImage(Image1,paramstr(1));  LoadImage(Image2,paramstr(2));
 LoadGrate(paramstr(3));

 outImage1:=GlobalAlloc(GMEM_FIXED,65536);
 outImage2:=GlobalAlloc(GMEM_FIXED,65536);
 outImage3:=GlobalAlloc(GMEM_FIXED,65536);
 {   p p}

 Morph;

 textmode(3);
end.


-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
>> source: simple.c <<
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-


 /***************************************************************************
 *         Texture mapper by Dmitry Tjurev  (FidoNet 2:5061/15.49)          *
 *                 compile: wcc386                                          *
 ***************************************************************************/

  #define MNO_VERTS_IN_POLIGON 8    //     
  #define MNO_SCAN_LINES 480        //    

  typedef struct                    //        
  {
    int   verts;                        //   
    float xt[MNO_VERTS_IN_POLIGON];     // 
    float yt[MNO_VERTS_IN_POLIGON];     //                 
    float zt[MNO_VERTS_IN_POLIGON];     //                            
    float xp[MNO_VERTS_IN_POLIGON];     //  
    float yp[MNO_VERTS_IN_POLIGON];     //                     
    float xs[MNO_VERTS_IN_POLIGON];     //  
    float ys[MNO_VERTS_IN_POLIGON];     //                       
    float br[MNO_VERTS_IN_POLIGON];     //   
    char  *texture;                     //   
  } face;

  void __memset(void *where,int what,int how_much);
  #pragma aux __memset parm [edi] [eax] [ecx]=\
    "cld"\
    "rep stosd"\
    modify exact[edi ecx];

  // ******** (    ) *******************

  int win_size_x,win_size_y;    //  -
  char  *vid_buf;               //   -
  char  color_tab[256*32];      //   +=
  int   *z_buf;                 //   Z-
  double l_k;                   //  0x7fffffff*(l-0.1),  l -   

  // ****************   ****************************

  face *p;         //       

 //*****************    *******************

  int ypi[MNO_VERTS_IN_POLIGON];
  int zt_l[MNO_SCAN_LINES],zt_r[MNO_SCAN_LINES];
  int xpi_l[MNO_SCAN_LINES],xpi_r[MNO_SCAN_LINES];
  int xs_l[MNO_SCAN_LINES],ys_l[MNO_SCAN_LINES];
  int xs_r[MNO_SCAN_LINES],ys_r[MNO_SCAN_LINES];
  int br_l[MNO_SCAN_LINES],br_r[MNO_SCAN_LINES];

 //********************   **********************************

 void draw_spans(int line,int height)  //  
 {                                     // line -  
                                       // height -  
    int xsc,ysc,brc,ztc;                    //  
    int xs_add,ys_add,br_add,zt_add;        // 
    int x1,x2,len;
    int offs,offs2;

    offs=line*win_size_x;
m1: x1=xpi_l[line];
    x2=xpi_r[line];
    if ((x1>=win_size_x) || (x2<0)) goto m2;
    ztc=zt_l[line];
    xsc=xs_l[line];
    ysc=ys_l[line];
    brc=br_l[line];
    len=(x2-x1);
    if (len)
    {
      zt_add=(zt_r[line]-ztc)/len;
      xs_add=(xs_r[line]-xsc)/len;
      ys_add=(ys_r[line]-ysc)/len;
      br_add=(br_r[line]-brc)/len;
    }
    len++;
    if (x2>=win_size_x) len-=x2-win_size_x+1;
    if (x1<0)
    {
      len+=x1;
      ztc-=zt_add*x1;
      xsc-=xs_add*x1;
      ysc-=ys_add*x1;
      brc-=br_add*x1;
      x1=0;
    }
    offs2=offs+x1;
    do
    {
      if (ztc>z_buf[offs2])
      {
        z_buf[offs2]=ztc;
        vid_buf[offs2]=color_tab[((brc>>16)<<8)+*(p->texture+(xsc>>16)+((ysc>>16)<<8))];
      }
      offs2++;
      ztc+=zt_add;
      xsc+=xs_add;
      ysc+=ys_add;
      brc+=br_add;
    } while(--len);
m2: offs+=win_size_x;
    line++;
    if (--height) goto m1;
 }

  void scan_edge(int n1,int n2)  //  
  {                              // x1,x2 -      
    int q,y,t;
    int xpc,xsc,ysc,brc,ztc;                  //  
    int xp_add,xs_add,ys_add,br_add,zt_add;   // 

    if (ypi[n1]>ypi[n2])
    {
      t=n1;
      n1=n2;
      n2=t;
    }
    y=ypi[n1];
    q=ypi[n2]-y;
    ztc=l_k/p->zt[n1];
    zt_add=(l_k/p->zt[n2]-ztc)/q;
    xpc=p->xp[n1]*65536;
    xsc=p->xs[n1]*65536;
    ysc=p->ys[n1]*65536;
    brc=p->br[n1]*65536;
    xp_add=((int)(p->xp[n2]*65536)-xpc)/q;
    xs_add=((int)(p->xs[n2]*65536)-xsc)/q;
    ys_add=((int)(p->ys[n2]*65536)-ysc)/q;
    br_add=((int)(p->br[n2]*65536)-brc)/q;
    q++;
    do
    {
      if (y<0) goto m1;
      if (y>=win_size_y) return;
      if ((xpc>>16) < xpi_l[y])
      {
        xpi_l[y]=xpc>>16;
        zt_l[y]=ztc;
        xs_l[y]=xsc;
        ys_l[y]=ysc;
        br_l[y]=brc;
      }
      if ((xpc>>16) > xpi_r[y])
      {
        xpi_r[y]=xpc>>16;
        zt_r[y]=ztc;
        xs_r[y]=xsc;
        ys_r[y]=ysc;
        br_r[y]=brc;
      }
m1:   ztc+=zt_add;
      xpc+=xp_add;
      xsc+=xs_add;
      ysc+=ys_add;
      brc+=br_add;
      y++;
    } while(--q);
  }

 void mapper()             // , 
 {
   int q;
   int ymin,ymax;

   q=p->verts-1;
   do
   {
     ypi[q]=p->yp[q];
   } while(--q>=0);
   ymin=ymax=ypi[0];
   q=p->verts-1;
   do
   {
     if (ypi[q]<ymin) ymin=ypi[q];
       else
         if (ypi[q]>ymax) ymax=ypi[q];
   } while(--q);
   if ((ymin==ymax)||(ymin>=win_size_y)||(ymax<0)) return;
   if (ymin<0) ymin=0;
   if (ymax>=win_size_y) ymax=win_size_y-1;
   __memset(xpi_l+ymin,2100000000,ymax-ymin+1);
   __memset(xpi_r+ymin,-2100000000,ymax-ymin+1);
   q=p->verts-1;
   if (ypi[q]!=ypi[0]) scan_edge(q,0);
   q--;
   do if (ypi[q]!=ypi[q+1]) scan_edge(q,q+1);  while (--q>=0);
   draw_spans(ymin,ymax-ymin+1);
 }


-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
>> source: gamma.pas <<
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-


uses Crt;

var  Scr: array[0..199,0..319] of Byte absolute $A000:$0000;

const Gamma:Real=1.8;

procedure SetPALColor(R,G,B:Real{0..1});
{  }
procedure Out1(V:Real);
begin
  if V<1E-3   then Port[$3C9]:=0
  else if V>1 then Port[$3C9]:=63
              else Port[$3C9]:=Round(63*Exp(Ln(V)/Gamma));
end; {Out1}

begin {SetPalColor}
  Out1(R);
  Out1(G);
  Out1(B);
end;  {SetPalColor}

procedure SetPalette;
var   N : Integer;
begin
  Port[$3C8] := 128;
  for N:=0 to 127 do
    SetPalColor(N/127,N/127,N/127);
end; {of SetPalette}

var   X,Y: Integer;
begin
  DirectVideo:=False;

  asm mov ax,$13; int $10; end;
  for Y:=0 to 39 do begin
    for X:=0 to 99 do begin
      Scr[20+Y*2,159-X]:=128;
      Scr[21+Y*2,159-X]:=254;
      Scr[20+Y*2,160+X]:=191;
      Scr[21+Y*2,160+X]:=191;
    end;
  end;
  for Y:=0 to 79 do begin
    for X:=0 to 49 do begin
      Scr[100+Y,159-X*2]:=191;
      Scr[100+Y,158-X*2]:=191;
      Scr[100+Y,161+X*2]:=128;
      Scr[100+Y,160+X*2]:=254;
    end;
  end;

  for Y:=0 to 79 do begin
    for X:=0 to 99 do begin
      Scr[60+Y,109+X]:=128+((X+Y) and 1)*126;
    end;
  end;

  for Y:=20 to 59 do begin
    for X:=25 to 74 do begin
      Scr[60+Y,109+X]:=191;
    end;
  end;

  Write('                       <+> <-> to adjust');
  repeat
    SetPalette;
    Write(#13'                 '#13,'Gamma = ',Gamma:1:3);
    case ReadKey of
      '+': Gamma:=Gamma*1.01;
      '-': Gamma:=Gamma/1.01;
      #27:Break;
    end;
  until False;
  asm mov ax,$03; int $10; end;
end.
