GraphicsPoly.cpp
上传用户:lhwx1029
上传日期:2013-03-07
资源大小:1173k
文件大小:25k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /** 3DGPL *************************************************
  2.  * ()                                                     *
  3.  * 2D graphics and 2D clipping extentions for shaded      *
  4.  * and textured polygons (has to be linked with regular   *
  5.  * routines).                                             *
  6.  *                                                        *
  7.  * Ifdefs:                                                *
  8.  *  _CI_                     Colour/Intensity model;      *
  9.  *  _RGB_                    RGB model;                   *
  10.  *  _Z_BUFFER_               Depth array;                 *
  11.  *  _PAINTER_                Back front order.            *
  12.  *                                                        *
  13.  * Defines:                                               *
  14.  *  G_flat_polygon           Regular polygon;             *
  15.  *  G_shaded_polygon         Shaded polygon;              *
  16.  *  G_lin_textured_polygon   Textured polygon (approx);   *
  17.  *  G_prp_textured_polygon   Textured polygon (true).     *
  18.  *                                                        *
  19.  * Internals:                                             *
  20.  *  GI_scan                  Scanning an edge;            *
  21.  *  GI_boarder_array_init    Init left/right boundaries.  *
  22.  *                                                        *
  23.  * (c) 1995-98 Sergei Savchenko, (savs@cs.mcgill.ca)      *
  24. **********************************************************/
  25. #include "RayTracing.h"           /* hardware specific stuff */
  26. #include "Colour.h"               /* colour and light */
  27. #include "Clipper.h"             /* 2D clipping */
  28. #include "Graphics.h"           /* 2D macros */
  29. #include "Engine.h"               /* M_LNG_SHADED */
  30. #include <limits.h>                         /* INT_MAX and INT_MIN */
  31. extern HW_pixel *G_c_buffer;                /* the bitmap's bits */
  32. extern int G_page_start;                    /* always 0 for _MONO_ */
  33. #if defined(_Z_BUFFER_)
  34. extern int *G_z_buffer;                     /* Z buffer */
  35. #endif
  36. #define G_LINEAR 32                         /* interpolate for */
  37. int G_miny,G_maxy;                          /* vertical boundaries */
  38. int G_x_start[HW_SCREEN_Y_SIZE];            /* polygon's */
  39. int G_x_end[HW_SCREEN_Y_SIZE];              /* horizontal boundaries */
  40. HW_32_bit G_0_start[HW_SCREEN_Y_SIZE];      /* [32-G_P].[G_P] values */
  41. HW_32_bit G_0_end[HW_SCREEN_Y_SIZE];        /* the thingie is to work faster */
  42. HW_32_bit G_1_start[HW_SCREEN_Y_SIZE];      /* then multidimensional array */
  43. HW_32_bit G_1_end[HW_SCREEN_Y_SIZE];        /* hope so, */
  44. HW_32_bit G_2_start[HW_SCREEN_Y_SIZE];
  45. HW_32_bit G_2_end[HW_SCREEN_Y_SIZE];        /* space for interpolating */
  46. HW_32_bit G_3_start[HW_SCREEN_Y_SIZE];      /* Z R G B Tx Ty */
  47. HW_32_bit G_3_end[HW_SCREEN_Y_SIZE];
  48. HW_32_bit G_4_start[HW_SCREEN_Y_SIZE];
  49. HW_32_bit G_4_end[HW_SCREEN_Y_SIZE];
  50. HW_32_bit G_5_start[HW_SCREEN_Y_SIZE];
  51. HW_32_bit G_5_end[HW_SCREEN_Y_SIZE];
  52. HW_32_bit *G_start[C_MAX_DIMENSIONS]=
  53. {G_0_start,G_1_start,G_2_start,G_3_start,G_4_start,G_5_start};
  54. HW_32_bit *G_end[C_MAX_DIMENSIONS]=
  55. {G_0_end,G_1_end,G_2_end,G_3_end,G_4_end,G_5_end};
  56. #if defined(_CI_)
  57.  #if defined(_Z_BUFFER_)                    /* Z I Tx Ty */
  58.   #define G_Z_INDX_START  G_0_start         /* indexed colour, z-buffer */
  59.   #define G_I_INDX_START  G_1_start
  60.   #define G_TX_INDX_START G_2_start
  61.   #define G_TY_INDX_START G_3_start
  62.   #define G_Z_INDX_END  G_0_end             /* indexed colour, z-buffer */
  63.   #define G_I_INDX_END  G_1_end
  64.   #define G_TX_INDX_END G_2_end
  65.   #define G_TY_INDX_END G_3_end
  66.  #endif
  67.  #if defined(_PAINTER_)                     /* I Tx Ty */
  68.   #define G_I_INDX_START  G_0_start         /* indexed colour, painter */
  69.   #define G_TX_INDX_START G_1_start
  70.   #define G_TY_INDX_START G_2_start
  71.   #define G_I_INDX_END  G_0_end             /* indexed colour, painter */
  72.   #define G_TX_INDX_END G_1_end
  73.   #define G_TY_INDX_END G_2_end
  74.  #endif
  75. #endif
  76. #if defined(_RGB_)
  77.  #if defined(_Z_BUFFER_)                    /* Z R G B Tx Ty */
  78.   #define G_Z_INDX_START  G_0_start         /* RGB colour, z-buffer */
  79.   #define G_R_INDX_START  G_1_start
  80.   #define G_G_INDX_START  G_2_start
  81.   #define G_B_INDX_START  G_3_start
  82.   #define G_TX_INDX_START G_4_start
  83.   #define G_TY_INDX_START G_5_start
  84.   #define G_Z_INDX_END  G_0_end             /* RGB colour, z-buffer */
  85.   #define G_R_INDX_END  G_1_end
  86.   #define G_G_INDX_END  G_2_end
  87.   #define G_B_INDX_END  G_3_end
  88.   #define G_TX_INDX_END G_4_end
  89.   #define G_TY_INDX_END G_5_end
  90.  #endif
  91.  #if defined(_PAINTER_)                     /* R G B Tx Ty */
  92.   #define G_R_INDX_START  G_0_start         /* RGB colou, painter */
  93.   #define G_G_INDX_START  G_1_start
  94.   #define G_B_INDX_START  G_2_start
  95.   #define G_TX_INDX_START G_3_start
  96.   #define G_TY_INDX_START G_4_start
  97.   #define G_R_INDX_END  G_0_end             /* RGB colou, painter */
  98.   #define G_G_INDX_END  G_1_end
  99.   #define G_B_INDX_END  G_2_end
  100.   #define G_TX_INDX_END G_3_end
  101.   #define G_TY_INDX_END G_4_end
  102.  #endif
  103. #endif
  104. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  105.  * INTERNAL: Scan converting a N dimensional line.       *
  106.  * ---------                                             *
  107.  * SETS: G_x_start,G_x_end,G_start,G_end,G_miny,G_maxy   *
  108.  * -----                                                 *
  109. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  110. void GI_scan(int *edges,int dimension,int skip)
  111. {
  112.  HW_32_bit cur_v[C_MAX_DIMENSIONS];         /* initial values for Z+ dims */
  113.  HW_32_bit inc_v[C_MAX_DIMENSIONS];         /* increment for Z+ dimensions */
  114.  int dx,dy,long_d,short_d;
  115.  register int d,add_dh,add_dl;
  116.  register int inc_xh,inc_yh,inc_xl,inc_yl;
  117.  int x,y,i,j;
  118.  int *v1,*v2;                               /* first and second vertices */
  119.  v1=edges; edges+=skip; v2=edges;           /* length ints in each */
  120.  if(C_line_y_clipping(&v1,&v2,dimension))   /* vertical clipping */
  121.  {
  122.   dx=*v2++; dy=*v2++;                       /* extracting 2-D coordinates */
  123.   x=*v1++; y=*v1++;                         /* v2/v1 point remaining dim-2 */
  124.   dimension-=2;
  125.   if(y<G_miny) G_miny=y;
  126.   if(y>G_maxy) G_maxy=y;
  127.   if(dy<G_miny) G_miny=dy;
  128.   if(dy>G_maxy) G_maxy=dy;                  /* updating vertical size */
  129.   dx-=x; dy-=y;                             /* ranges */
  130.   if(dx<0){dx=-dx; inc_xh=-1; inc_xl=-1;}   /* making sure dx and dy >0 */
  131.   else    {        inc_xh=1;  inc_xl=1; }   /* adjusting increments */
  132.   if(dy<0){dy=-dy; inc_yh=-1; inc_yl=-1;}
  133.   else    {        inc_yh=1;  inc_yl=1; }
  134.   if(dx>dy){long_d=dx;short_d=dy;inc_yl=0;} /* long range,&make sure either */
  135.   else     {long_d=dy;short_d=dx;inc_xl=0;} /* x or y is changed in L case */
  136.   d=2*short_d-long_d;                       /* initial value of d */
  137.   add_dl=2*short_d;                         /* d adjustment for H case */
  138.   add_dh=2*(short_d-long_d);                /* d adjustment for L case */
  139. #if defined(_Z_BUFFER_)
  140.   cur_v[0]=((HW_32_bit)v1[0])<<G_P;         /* Z */
  141.   if(long_d>0)
  142.    inc_v[0]=(((HW_32_bit)(v2[0]-v1[0]))<<G_P)/long_d;
  143.   i=1;                                      /* the rest */
  144. #endif
  145. #if defined(_PAINTER_)
  146.   i=0;                                      /* all */
  147. #endif
  148.   for(;i<dimension;i++)                     /* for all remaining dimensions */
  149.   {
  150.    cur_v[i]=((HW_32_bit)v1[i]);
  151.    if(long_d>0)
  152.     inc_v[i]=((HW_32_bit)(v2[i]-v1[i]))/long_d;
  153.   }
  154.   for(i=0;i<=long_d;i++)                    /* for all points in long range */
  155.   {
  156.    if(x<G_x_start[y])                       /* further than rightmost */
  157.    {
  158.     G_x_start[y]=x;                         /* the begining of scan line */
  159.     for(j=0;j<dimension;j++)
  160.      G_start[j][y]=cur_v[j];                /* all other dimensions */
  161.    }
  162.    if(G_x_end[y]<x)                         /* further the leftmost */
  163.    {
  164.     G_x_end[y]=x;                           /* the end of scan line */
  165.     for(j=0;j<dimension;j++)
  166.      G_end[j][y]=cur_v[j];                  /* and for other dimension */
  167.    }
  168.    if(d>=0){x+=inc_xh;y+=inc_yh;d+=add_dh;} /* previous point was H type */
  169.    else    {x+=inc_xl;y+=inc_yl;d+=add_dl;} /* previous point was L type */
  170.    for(j=0;j<dimension;j++)
  171.     cur_v[j]+=inc_v[j];                     /* for all other dimensions */
  172.   }
  173.  }
  174. }
  175. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  176.  * INTERNAL: Initialization of polygon boundaries.       *
  177.  * ---------                                             *
  178.  * SETS: G_miny,G_maxy,G_x_start,G_x_end                 *
  179.  * -----                                                 *
  180. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  181. void GI_boarder_array_init(void)
  182. {
  183.  G_miny=INT_MAX;                            /* polygon starts here */
  184.  G_maxy=INT_MIN;                            /* polygon ends here */
  185.  HW_set_int(G_x_start,HW_SCREEN_Y_SIZE,INT_MAX);
  186.  HW_set_int(G_x_end,HW_SCREEN_Y_SIZE,INT_MIN);
  187. }
  188. /**********************************************************
  189.  * Rendering a polygon.                                   *
  190.  * Accepts a stream of two-tuples X Y (_PAINTER_) or      *
  191.  * three-tuples X Y Z (_Z_BUFFER_).                       *
  192. **********************************************************/
  193. #if defined(_CI_)
  194. void G_flat_polygon(int *edges,int length,
  195.                        HW_pixel colour,int intensity
  196.                       )
  197. #endif
  198. #if defined(_RGB_)
  199. void G_flat_polygon(int *edges,int length,
  200.                        HW_pixel colour,int red,int green,int blue
  201.                       )
  202. #endif
  203. {
  204.  int new_edges[G_MAX_POLYGON_VERTICES*G_LNG_FLAT];
  205.  int new_length,i;                          /* although no edges there yet */
  206.  long pos;
  207.  register HW_pixel *adr_c;                  /* position in the Colour buffer */
  208.  register int beg,end,span;
  209. #if defined(_CI_)
  210.  HW_pixel hwcolour=CL_light(colour,intensity);
  211. #endif
  212. #if defined(_RGB_)
  213.  HW_pixel hwcolour=CL_light(colour,red,green,blue);
  214. #endif
  215. #if defined(_Z_BUFFER_)
  216.  int *adr_z;                                /* position in the Z buffer */
  217.  register HW_32_bit cur_z,inc_z;            /* current deapth */
  218. #endif
  219.  GI_boarder_array_init();                   /* initializing the arrays */
  220.  new_length=C_polygon_x_clipping(edges,new_edges,G_LNG_FLAT,length);
  221.  for(i=0;i<new_length;i++)                  /* Searching polygon boarders */
  222.   GI_scan(&new_edges[i*G_LNG_FLAT],G_LNG_FLAT,G_LNG_FLAT);
  223.  if(G_miny<G_maxy)                          /* nothing to do? */
  224.  {
  225.   pos=G_miny*HW_SCREEN_LINE_SIZE+G_page_start;
  226.   for(;G_miny<G_maxy;G_miny++,pos+=HW_SCREEN_LINE_SIZE)
  227.   {                                         /* rendering all lines */
  228.    adr_c=G_c_buffer+pos+(beg=G_x_start[G_miny]);
  229. #if defined(_Z_BUFFER_)
  230.    adr_z=G_z_buffer+pos+beg;                /* corresponding position in Z buffer */
  231. #endif
  232.    end=G_x_end[G_miny];                     /* ends here */
  233.    span=end-beg;
  234. #if defined(_Z_BUFFER_)
  235.    cur_z=G_Z_INDX_START[G_miny];
  236.    if(span!=0)
  237.     inc_z=(G_Z_INDX_END[G_miny]-cur_z)/span;
  238.    for(;beg<=end;beg++,adr_c++,adr_z++)     /* render this lines */
  239.    {
  240.     if(*adr_z>(cur_z>>G_P))                 /* Z buffer check */
  241.     {
  242.      *adr_z=cur_z>>G_P;                     /* store new deapth here */
  243.      *adr_c=hwcolour;                       /* flat colour here */
  244.     }
  245.     cur_z+=inc_z;                           /* next value for Z */
  246.    }
  247. #endif
  248. #if defined(_PAINTER_)
  249.    HW_set_pixel(adr_c,span+1,hwcolour);     /* drawing a strip */
  250. #endif
  251.   }
  252.  }
  253. }
  254. /**********************************************************
  255.  * Rendering an Interpolatively shaded polygon.           *
  256.  * Accepts a stream of three-tuples ( X Y Intensity )     *
  257.  * for _CI_ and 5-tuples ( X Y R G B ) for _RGB_          *
  258.  * similarely it is ( X Y Z etc. ) if _Z_BUFFER_          *
  259. **********************************************************/
  260. void G_shaded_polygon(int *edges,int length,HW_pixel colour)
  261. {
  262.  int new_edges[G_MAX_POLYGON_VERTICES*G_LNG_SHADED];
  263.  int new_length,i;
  264.  long pos;
  265.  register HW_pixel *adr_c;
  266.  register int beg,end,span;
  267. #if defined(_CI_)
  268.  register HW_32_bit cur_i,inc_i;            /* current colour */
  269. #endif
  270. #if defined(_RGB_)
  271.  register HW_32_bit cur_r,inc_r,cur_g,inc_g,cur_b,inc_b;
  272. #endif
  273. #if defined(_Z_BUFFER_)
  274.  int *adr_z;                                /* position in the Z buffer */
  275.  register HW_32_bit cur_z,inc_z;            /* current depth */
  276. #endif
  277.  GI_boarder_array_init();                   /* initializing the array */
  278.  new_length=C_polygon_x_clipping(edges,new_edges,G_LNG_SHADED,length);
  279.  for(i=0;i<new_length;i++)                  /* Searching polygon boarders */
  280.   GI_scan(&new_edges[i*G_LNG_SHADED],G_LNG_SHADED,G_LNG_SHADED);
  281.  if(G_miny<G_maxy)                          /* nothing to do? */
  282.  {
  283.   pos=G_miny*HW_SCREEN_LINE_SIZE+G_page_start;
  284.   for(;G_miny<G_maxy;G_miny++,pos+=HW_SCREEN_LINE_SIZE)
  285.   {                                         /* rendering all lines */
  286.    adr_c=G_c_buffer+pos+(beg=G_x_start[G_miny]);
  287. #if defined(_Z_BUFFER_)
  288.    adr_z=G_z_buffer+pos+beg;                /* corresponding place in Z buffer */
  289. #endif
  290.    end=G_x_end[G_miny];                     /* ends here */
  291.    span=end-beg;
  292.    if(span==0) span=1;                      /* not to divide by 0 */
  293. #if defined(_CI_)
  294.    cur_i=G_I_INDX_START[G_miny];
  295.    inc_i=(G_I_INDX_END[G_miny]-cur_i)/span;
  296. #endif
  297. #if defined(_RGB_)
  298.    cur_r=G_R_INDX_START[G_miny];
  299.    inc_r=(G_R_INDX_END[G_miny]-cur_r)/span;
  300.    cur_g=G_G_INDX_START[G_miny];
  301.    inc_g=(G_G_INDX_END[G_miny]-cur_g)/span;
  302.    cur_b=G_B_INDX_START[G_miny];
  303.    inc_b=(G_B_INDX_END[G_miny]-cur_b)/span;
  304. #endif
  305. #if defined(_Z_BUFFER_)
  306.    cur_z=G_Z_INDX_START[G_miny];
  307.    inc_z=(G_Z_INDX_END[G_miny]-cur_z)/span;
  308.    for(;beg<=end;beg++,adr_c++,adr_z++)     /* render this lines */
  309.    {
  310.     if(*adr_z>(cur_z>>G_P))                 /* Z buffer check */
  311.     {
  312.      *adr_z=cur_z>>G_P;                     /* store new deapth here */
  313. #endif
  314. #if defined(_PAINTER_)
  315.    for(;beg<=end;beg++,adr_c++)             /* same, no Z check */
  316.    {
  317.     {
  318. #endif
  319. #if defined(_CI_)
  320.      *adr_c=CL_light(colour,cur_i>>G_P);    /* rendering single point */
  321.     }
  322.     cur_i+=inc_i;                           /* incrementing colour */
  323. #endif
  324. #if defined(_RGB_)
  325.      *adr_c=CL_light(colour,cur_r>>G_P,cur_g>>G_P,cur_b>>G_P);
  326.     }
  327.     cur_r+=inc_r;
  328.     cur_g+=inc_g;
  329.     cur_b+=inc_b;                           /* increment RGB */
  330. #endif
  331. #if defined(_Z_BUFFER_)
  332.     cur_z+=inc_z;                           /* increment Z */
  333. #endif
  334.    }
  335.   }
  336.  }
  337. }
  338. /**********************************************************
  339.  * Rendering a leanerely textured polygon.                *
  340.  * The applied texture is a square colourmap with:        *
  341.  *                                                        *
  342.  * log_texture_size=log texture_size                      *
  343.  *                     2                                  *
  344.  *                                                        *
  345.  * Accepts a stream of 5-tuples ( X Y Intensity Tx Ty)    *
  346.  * for _CI_ and 5-tuples ( X Y R G B Tx Ty) for _RGB_     *
  347.  * similarely it is one more ( X Y Z etc. ) if _Z_BUFFER_ *
  348. **********************************************************/
  349. void G_lin_textured_polygon(int *edges,int length,
  350.                             HW_pixel *texture,
  351.                             int log_texture_size
  352.                            )
  353. {
  354.  int new_edges[G_MAX_POLYGON_VERTICES*G_LNG_TEXTURED];
  355.  int new_length,i;                          /* although no edges there yet */
  356.  long pos;
  357.  register HW_pixel *adr_c;
  358.  register int beg,end,span;
  359.  register HW_32_bit cur_tx,inc_tx;          /* current position inside */
  360.  register HW_32_bit cur_ty,inc_ty;          /* the texture */
  361. #if defined(_CI_)
  362.  register HW_32_bit cur_i,inc_i;            /* current colour and it's inc */
  363. #endif
  364. #if defined(_RGB_)
  365.  register HW_32_bit cur_r,inc_r,cur_g,inc_g,cur_b,inc_b;
  366. #endif
  367. #if defined(_Z_BUFFER_)
  368.  int *adr_z;                                /* position in the Z buffer */
  369.  register HW_32_bit cur_z,inc_z;            /* current deapth */
  370. #endif
  371.  HW_32_bit txtrmasc=(0x1<<(log_texture_size+G_P))-0x1;
  372.  GI_boarder_array_init();                   /* initializing the array */
  373.  new_length=C_polygon_x_clipping(edges,new_edges,G_LNG_TEXTURED,length);
  374.  for(i=0;i<new_length;i++)
  375.   GI_scan(&new_edges[i*G_LNG_TEXTURED],G_LNG_TEXTURED,G_LNG_TEXTURED);
  376.  if(G_miny<G_maxy)                          /* nothing to do? */
  377.  {
  378.   pos=G_miny*HW_SCREEN_LINE_SIZE+G_page_start;
  379.   for(;G_miny<G_maxy;G_miny++,pos+=HW_SCREEN_LINE_SIZE)
  380.   {                                         /* rendering all lines */
  381.    adr_c=G_c_buffer+pos+(beg=G_x_start[G_miny]);
  382. #if defined(_Z_BUFFER_)
  383.    adr_z=G_z_buffer+pos+beg;                /* corresponding place in Z buffer */
  384. #endif
  385.    end=G_x_end[G_miny];                     /* ends here */
  386.    span=end-beg;
  387.    if(span==0) span=1;                      /* not to divide by 0 */
  388.    cur_tx=G_TX_INDX_START[G_miny];
  389.    inc_tx=(G_TX_INDX_END[G_miny]-cur_tx)/span;
  390.    cur_ty=G_TY_INDX_START[G_miny];
  391.    inc_ty=(G_TY_INDX_END[G_miny]-cur_ty)/span;
  392. #if defined(_CI_)
  393.    cur_i=G_I_INDX_START[G_miny];
  394.    inc_i=(G_I_INDX_END[G_miny]-cur_i)/span;
  395. #endif
  396. #if defined(_RGB_)
  397.    cur_r=G_R_INDX_START[G_miny];
  398.    inc_r=(G_R_INDX_END[G_miny]-cur_r)/span;
  399.    cur_g=G_G_INDX_START[G_miny];
  400.    inc_g=(G_G_INDX_END[G_miny]-cur_g)/span;
  401.    cur_b=G_B_INDX_START[G_miny];
  402.    inc_b=(G_B_INDX_END[G_miny]-cur_b)/span;
  403. #endif
  404. #if defined(_Z_BUFFER_)
  405.    cur_z=G_Z_INDX_START[G_miny];
  406.    inc_z=(G_Z_INDX_END[G_miny]-cur_z)/span;
  407.    for(;beg<=end;beg++,adr_c++,adr_z++)
  408.    {
  409.     cur_tx&=txtrmasc; cur_ty&=txtrmasc;
  410.     if(*adr_z>(cur_z>>G_P))                 /* Z buffer check */
  411.     {
  412.      *adr_z=cur_z>>G_P;
  413. #endif
  414. #if defined(_PAINTER_)
  415.    for(;beg<=end;beg++,adr_c++)             /* render all lines: */
  416.    {
  417.     cur_tx&=txtrmasc;
  418.     cur_ty&=txtrmasc;                       /* wrap around */
  419.     {
  420. #endif
  421. #if defined(_CI_)
  422.      *adr_c=CL_light(*(texture+((cur_ty>>G_P)<<log_texture_size)+(cur_tx>>G_P)),
  423.                       cur_i>>G_P
  424.                      );
  425.      cur_i+=inc_i;
  426.     }
  427. #endif
  428. #if defined(_RGB_)
  429.      *adr_c=CL_light(*(texture+((cur_ty>>G_P)<<log_texture_size)+(cur_tx>>G_P)),
  430.                       cur_r>>G_P,cur_g>>G_P,cur_b>>G_P
  431.                      );
  432.      cur_r+=inc_r;
  433.      cur_g+=inc_g;
  434.      cur_b+=inc_b;
  435.     }
  436. #endif
  437.     cur_tx+=inc_tx;
  438.     cur_ty+=inc_ty;                         /* new position inside texture */
  439. #if defined(_Z_BUFFER_)
  440.     cur_z+=inc_z;
  441. #endif
  442.    }
  443.   }
  444.  }
  445. }
  446. /**********************************************************
  447.  * Rendering a perspectively textured polygon.            *
  448.  * The applied texture is a square colourmap with:        *
  449.  *                                                        *
  450.  * log_texture_size=log texture_size                      *
  451.  *                     2                                  *
  452.  *                                                        *
  453.  * Accepts a stream of 5-tuples ( X Y Intensity Tx Ty)    *
  454.  * for _CI_ and 5-tuples ( X Y R G B Tx Ty) for _RGB_     *
  455.  * similarely it is one more ( X Y Z etc. ) if _Z_BUFFER_ *
  456.  *                                                        *
  457.  * log_texture_scale allowing scaling the texture, i.e.   *
  458.  * mapping a larger texture onto a smaller polygon or     *
  459.  * smaller texture onto a larger polygon.                 *
  460. **********************************************************/
  461. void G_prp_textured_polygon(int *edges,int length,
  462.                             int *O,int *u,int *v,
  463.                             HW_pixel *texture,
  464.                             int log_texture_size,
  465.                             int log_texture_scale
  466.                            )
  467. {
  468.  int new_edges[G_MAX_POLYGON_VERTICES*G_LNG_TEXTURED];
  469.  int new_length,i;
  470.  HW_32_bit Vx,Vy,Vz;
  471.  HW_32_bit Ux,Uy,Uz;                        /* extracting vectors */
  472.  HW_32_bit x0,y0,z0;
  473.  HW_32_bit ui,uj,uc;
  474.  HW_32_bit vi,vj,vc;
  475.  HW_32_bit zi,zj,zc;                        /* back to texture coeficients */
  476.  HW_32_bit v0,u0;
  477.  HW_32_bit xx,yy,zz,zzz;
  478.  long pos;
  479.  HW_pixel *adr_c;
  480.  register int beg,end,span;
  481.  HW_32_bit cur_tx,inc_tx,end_tx,cur_ty,inc_ty,end_ty;
  482. #if defined(_CI_)
  483.  register HW_32_bit cur_i,inc_i;            /* current colour and it's inc */
  484. #endif
  485. #if defined(_RGB_)
  486.  register HW_32_bit cur_r,inc_r,cur_g,inc_g,cur_b,inc_b;
  487. #endif
  488. #if defined(_Z_BUFFER_)
  489.  int *adr_z;                                /* position in the Z buffer */
  490.  register HW_32_bit cur_z,inc_z;            /* current deapth */
  491. #endif
  492.  register int x,y;
  493.  HW_32_bit txtrmasc=(0x1<<(log_texture_size+G_P))-0x1;
  494.  GI_boarder_array_init();                   /* initializing the array */
  495.  new_length=C_polygon_x_clipping(edges,new_edges,G_LNG_TEXTURED,length);
  496.  for(i=0;i<new_length;i++)
  497.   GI_scan(&new_edges[i*G_LNG_TEXTURED],G_LNG_SHADED,G_LNG_TEXTURED);
  498.  if(G_miny<G_maxy)                          /* nothing to do? */
  499.  {
  500.   x0=O[0]; y0=O[1]; z0=O[2];                /* X Y Z */
  501.   u0=O[M_LNG_SHADED];
  502.   v0=O[M_LNG_SHADED+1];                     /* world point <-> texture point */
  503.   Vx=v[0]; Vy=v[1]; Vz=v[2];
  504.   Ux=u[0]; Uy=u[1]; Uz=u[2];                /* extracting vectors */
  505.   ui=(Vz*y0)-(Vy*z0);
  506.   uj=(Vx*z0)-(Vz*x0);
  507.   uc=(Vy*x0)-(Vx*y0);
  508.   vi=(Uy*z0)-(Uz*y0);
  509.   vj=(Uz*x0)-(Ux*z0);
  510.   vc=(Ux*y0)-(Uy*x0);
  511.   zi=(Vy*Uz)-(Vz*Uy);
  512.   zj=(Vz*Ux)-(Vx*Uz);
  513.   zc=(Vx*Uy)-(Vy*Ux);                       /* back to texture coefs */
  514.   pos=G_miny*HW_SCREEN_LINE_SIZE+G_page_start;
  515.   for(;G_miny<G_maxy;G_miny++,pos+=HW_SCREEN_LINE_SIZE)
  516.   {                                         /* rendering all lines */
  517.    adr_c=G_c_buffer+pos+(beg=G_x_start[G_miny]);
  518. #if defined(_Z_BUFFER_)
  519.    adr_z=G_z_buffer+pos+beg;                /* corresponding place in Z buffer */
  520. #endif
  521.    end=G_x_end[G_miny];                     /* ends here */
  522.    span=end-beg;
  523.    if(span==0) span=1;                      /* not to divide by 0 */
  524.    beg-=HW_SCREEN_X_CENTRE;
  525.    x=beg;
  526.    end-=HW_SCREEN_X_CENTRE;
  527.    y=G_miny-HW_SCREEN_Y_CENTRE;             /* pure perspective space */
  528. #if defined(_CI_)
  529.    cur_i=G_I_INDX_START[G_miny];
  530.    inc_i=(G_I_INDX_END[G_miny]-cur_i)/span;
  531. #endif
  532. #if defined(_RGB_)
  533.    cur_r=G_R_INDX_START[G_miny];
  534.    inc_r=(G_R_INDX_END[G_miny]-cur_r)/span;
  535.    cur_g=G_G_INDX_START[G_miny];
  536.    inc_g=(G_G_INDX_END[G_miny]-cur_g)/span;
  537.    cur_b=G_B_INDX_START[G_miny];
  538.    inc_b=(G_B_INDX_END[G_miny]-cur_b)/span;
  539. #endif
  540. #if defined(_Z_BUFFER_)
  541.    cur_z=G_Z_INDX_START[G_miny];
  542.    inc_z=(G_Z_INDX_END[G_miny]-cur_z)/span;
  543. #endif
  544.    xx=((y*uj)>>M_camera_log_focus)+uc;
  545.    yy=((y*vj)>>M_camera_log_focus)+vc;
  546.    zz=((y*zj)>>M_camera_log_focus)+zc;      /* valid for the whole run */
  547.    if((zzz=zz+((x*zi)>>M_camera_log_focus))!=0)
  548.    {
  549.     end_tx=((((xx+((x*ui)>>M_camera_log_focus))<<log_texture_scale)/zzz)<<G_P)+u0;
  550.     end_ty=((((yy+((x*vi)>>M_camera_log_focus))<<log_texture_scale)/zzz)<<G_P)+v0;
  551.    } else { end_tx=end_ty=0; }              /* not important actually */
  552.    for(;beg<=end;)
  553.    {
  554.     x+=G_LINEAR; if(x>end) x=end;           /* size of linear run */
  555.     cur_tx=end_tx;
  556.     cur_ty=end_ty;
  557.     if((zzz=zz+((x*zi)>>M_camera_log_focus))!=0)
  558.     {
  559.      end_tx=((((xx+((x*ui)>>M_camera_log_focus))<<log_texture_scale)/zzz)<<G_P)+u0;
  560.      end_ty=((((yy+((x*vi)>>M_camera_log_focus))<<log_texture_scale)/zzz)<<G_P)+v0;
  561.     } else { end_tx=end_ty=0; }             /* not important to what */
  562.     if((span=x-beg)!=0)                     /* ends here */
  563.     {
  564.      inc_tx=(end_tx-cur_tx)/span;
  565.      inc_ty=(end_ty-cur_ty)/span;
  566.     } else { inc_tx=inc_ty=0; }             /* not important to what */
  567. #if defined(_Z_BUFFER_)
  568.     for(;beg<=x;beg++,adr_c++,adr_z++)
  569.     {
  570.      cur_tx&=txtrmasc;
  571.      cur_ty&=txtrmasc;
  572.      if(*adr_z>(cur_z>>G_P))                /* Z buffer check */
  573.      {
  574.       *adr_z=cur_z>>G_P;
  575. #endif
  576. #if defined(_PAINTER_)
  577.     for(;beg<=x;beg++,adr_c++)              /* linear run */
  578.     {
  579.      cur_tx&=txtrmasc;
  580.      cur_ty&=txtrmasc;                      /* wrap around */
  581.      {
  582. #endif
  583. #if defined(_CI_)
  584.       *adr_c=CL_light(*(texture+((cur_ty>>G_P)<<log_texture_size)+(cur_tx>>G_P)),
  585.                        cur_i>>G_P
  586.                       );
  587.       cur_i+=inc_i;
  588.      }
  589. #endif
  590. #if defined(_RGB_)
  591.       *adr_c=CL_light(*(texture+((cur_ty>>G_P)<<log_texture_size)+(cur_tx>>G_P)),
  592.                        cur_r>>G_P,cur_g>>G_P,cur_b>>G_P
  593.                       );
  594.       cur_r+=inc_r;
  595.       cur_g+=inc_g;
  596.       cur_b+=inc_b;
  597.      }
  598. #endif
  599.      cur_tx+=inc_tx;
  600.      cur_ty+=inc_ty;                        /* new position in the texture */
  601. #if defined(_Z_BUFFER_)
  602.      cur_z+=inc_z;
  603. #endif
  604.     }
  605.    }
  606.   }
  607.  }
  608. }
  609. /**********************************************************/