home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / r_aclip.c.orig < prev    next >
Text File  |  2000-06-17  |  9KB  |  351 lines

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // r_aclip.c: clip routines for drawing Alias models directly to the screen
  21.  
  22. #include "quakedef.h"
  23. #include "r_local.h"
  24. #include "d_local.h"
  25.  
  26. static finalvert_t    fv[2][8];
  27. static auxvert_t    av[8];
  28.  
  29. void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av);
  30. void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1,
  31.   finalvert_t *out);
  32. void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
  33.   finalvert_t *out);
  34. void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1,
  35.   finalvert_t *out);
  36. void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
  37.   finalvert_t *out);
  38.  
  39.  
  40. /*
  41. ================
  42. R_Alias_clip_z
  43.  
  44. pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
  45. ================
  46. */
  47. void R_Alias_clip_z (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
  48. {
  49.   float   scale;
  50.   auxvert_t *pav0, *pav1, avout;
  51.  
  52.   pav0 = &av[pfv0 - &fv[0][0]];
  53.   pav1 = &av[pfv1 - &fv[0][0]];
  54.  
  55.   if (pfv0->v[1] >= pfv1->v[1])
  56.   {
  57.     scale = (ALIAS_Z_CLIP_PLANE - pav0->fv[2]) /
  58.         (pav1->fv[2] - pav0->fv[2]);
  59.   
  60.     avout.fv[0] = pav0->fv[0] + (pav1->fv[0] - pav0->fv[0]) * scale;
  61.     avout.fv[1] = pav0->fv[1] + (pav1->fv[1] - pav0->fv[1]) * scale;
  62.     avout.fv[2] = ALIAS_Z_CLIP_PLANE;
  63.   
  64.     out->v[2] = pfv0->v[2] + (pfv1->v[2] - pfv0->v[2]) * scale;
  65.     out->v[3] = pfv0->v[3] + (pfv1->v[3] - pfv0->v[3]) * scale;
  66.     out->v[4] = pfv0->v[4] + (pfv1->v[4] - pfv0->v[4]) * scale;
  67.   }
  68.   else
  69.   {
  70.     scale = (ALIAS_Z_CLIP_PLANE - pav1->fv[2]) /
  71.         (pav0->fv[2] - pav1->fv[2]);
  72.   
  73.     avout.fv[0] = pav1->fv[0] + (pav0->fv[0] - pav1->fv[0]) * scale;
  74.     avout.fv[1] = pav1->fv[1] + (pav0->fv[1] - pav1->fv[1]) * scale;
  75.     avout.fv[2] = ALIAS_Z_CLIP_PLANE;
  76.   
  77.     out->v[2] = pfv1->v[2] + (pfv0->v[2] - pfv1->v[2]) * scale;
  78.     out->v[3] = pfv1->v[3] + (pfv0->v[3] - pfv1->v[3]) * scale;
  79.     out->v[4] = pfv1->v[4] + (pfv0->v[4] - pfv1->v[4]) * scale;
  80.   }
  81.  
  82.   R_AliasProjectFinalVert (out, &avout);
  83.  
  84.   if (out->v[0] < r_refdef.aliasvrect.x)
  85.     out->flags |= ALIAS_LEFT_CLIP;
  86.   if (out->v[1] < r_refdef.aliasvrect.y)
  87.     out->flags |= ALIAS_TOP_CLIP;
  88.   if (out->v[0] > r_refdef.aliasvrectright)
  89.     out->flags |= ALIAS_RIGHT_CLIP;
  90.   if (out->v[1] > r_refdef.aliasvrectbottom)
  91.     out->flags |= ALIAS_BOTTOM_CLIP;  
  92. }
  93.  
  94.  
  95. #if !id386
  96.  
  97. void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
  98. {
  99.   float   scale;
  100.   int     i;
  101.  
  102.   if (pfv0->v[1] >= pfv1->v[1])
  103.   {
  104.     scale = (float)(r_refdef.aliasvrect.x - pfv0->v[0]) /
  105.         (pfv1->v[0] - pfv0->v[0]);
  106.     for (i=0 ; i<6 ; i++)
  107.       out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
  108.   }
  109.   else
  110.   {
  111.     scale = (float)(r_refdef.aliasvrect.x - pfv1->v[0]) /
  112.         (pfv0->v[0] - pfv1->v[0]);
  113.     for (i=0 ; i<6 ; i++)
  114.       out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
  115.   }
  116. }
  117.  
  118.  
  119. void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
  120.   finalvert_t *out)
  121. {
  122.   float   scale;
  123.   int     i;
  124.  
  125.   if (pfv0->v[1] >= pfv1->v[1])
  126.   {
  127.     scale = (float)(r_refdef.aliasvrectright - pfv0->v[0]) /
  128.         (pfv1->v[0] - pfv0->v[0]);
  129.     for (i=0 ; i<6 ; i++)
  130.       out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
  131.   }
  132.   else
  133.   {
  134.     scale = (float)(r_refdef.aliasvrectright - pfv1->v[0]) /
  135.         (pfv0->v[0] - pfv1->v[0]);
  136.     for (i=0 ; i<6 ; i++)
  137.       out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
  138.   }
  139. }
  140.  
  141.  
  142. void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
  143. {
  144.   float   scale;
  145.   int     i;
  146.  
  147.   if (pfv0->v[1] >= pfv1->v[1])
  148.   {
  149.     scale = (float)(r_refdef.aliasvrect.y - pfv0->v[1]) /
  150.         (pfv1->v[1] - pfv0->v[1]);
  151.     for (i=0 ; i<6 ; i++)
  152.       out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
  153.   }
  154.   else
  155.   {
  156.     scale = (float)(r_refdef.aliasvrect.y - pfv1->v[1]) /
  157.         (pfv0->v[1] - pfv1->v[1]);
  158.     for (i=0 ; i<6 ; i++)
  159.       out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
  160.   }
  161. }
  162.  
  163.  
  164. void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
  165.   finalvert_t *out)
  166. {
  167.   float   scale;
  168.   int     i;
  169.  
  170.   if (pfv0->v[1] >= pfv1->v[1])
  171.   {
  172.     scale = (float)(r_refdef.aliasvrectbottom - pfv0->v[1]) /
  173.         (pfv1->v[1] - pfv0->v[1]);
  174.  
  175.     for (i=0 ; i<6 ; i++)
  176.       out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
  177.   }
  178.   else
  179.   {
  180.     scale = (float)(r_refdef.aliasvrectbottom - pfv1->v[1]) /
  181.         (pfv0->v[1] - pfv1->v[1]);
  182.  
  183.     for (i=0 ; i<6 ; i++)
  184.       out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
  185.   }
  186. }
  187.  
  188. #endif
  189.  
  190.  
  191. int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count,
  192.   void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) )
  193. {
  194.   int     i,j,k;
  195.   int     flags, oldflags;
  196.   
  197.   j = count-1;
  198.   k = 0;
  199.   for (i=0 ; i<count ; j = i, i++)
  200.   {
  201.     oldflags = in[j].flags & flag;
  202.     flags = in[i].flags & flag;
  203.  
  204.     if (flags && oldflags)
  205.       continue;
  206.     if (oldflags ^ flags)
  207.     {
  208.       clip (&in[j], &in[i], &out[k]);
  209.       out[k].flags = 0;
  210.       if (out[k].v[0] < r_refdef.aliasvrect.x)
  211.         out[k].flags |= ALIAS_LEFT_CLIP;
  212.       if (out[k].v[1] < r_refdef.aliasvrect.y)
  213.         out[k].flags |= ALIAS_TOP_CLIP;
  214.       if (out[k].v[0] > r_refdef.aliasvrectright)
  215.         out[k].flags |= ALIAS_RIGHT_CLIP;
  216.       if (out[k].v[1] > r_refdef.aliasvrectbottom)
  217.         out[k].flags |= ALIAS_BOTTOM_CLIP;  
  218.       k++;
  219.     }
  220.     if (!flags)
  221.     {
  222.       out[k] = in[i];
  223.       k++;
  224.     }
  225.   }
  226.   
  227.   return k;
  228. }
  229.  
  230.  
  231. /*
  232. ================
  233. R_AliasClipTriangle
  234. ================
  235. */
  236. void R_AliasClipTriangle (mtriangle_t *ptri)
  237. {
  238.   int       i, k, pingpong;
  239.   mtriangle_t   mtri;
  240.   unsigned    clipflags;
  241.  
  242. // copy vertexes and fix seam texture coordinates
  243.   if (ptri->facesfront)
  244.   {
  245.     fv[0][0] = pfinalverts[ptri->vertindex[0]];
  246.     fv[0][1] = pfinalverts[ptri->vertindex[1]];
  247.     fv[0][2] = pfinalverts[ptri->vertindex[2]];
  248.   }
  249.   else
  250.   {
  251.     for (i=0 ; i<3 ; i++)
  252.     {
  253.       fv[0][i] = pfinalverts[ptri->vertindex[i]];
  254.   
  255.       if (!ptri->facesfront && (fv[0][i].flags & ALIAS_ONSEAM) )
  256.         fv[0][i].v[2] += r_affinetridesc.seamfixupX16;
  257.     }
  258.   }
  259.  
  260. // clip
  261.   clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags;
  262.  
  263.   if (clipflags & ALIAS_Z_CLIP)
  264.   {
  265.     for (i=0 ; i<3 ; i++)
  266.       av[i] = pauxverts[ptri->vertindex[i]];
  267.  
  268.     k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z);
  269.     if (k == 0)
  270.       return;
  271.  
  272.     pingpong = 1;
  273.     clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags;
  274.   }
  275.   else
  276.   {
  277.     pingpong = 0;
  278.     k = 3;
  279.   }
  280.  
  281.   if (clipflags & ALIAS_LEFT_CLIP)
  282.   {
  283.     k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
  284.               ALIAS_LEFT_CLIP, k, R_Alias_clip_left);
  285.     if (k == 0)
  286.       return;
  287.  
  288.     pingpong ^= 1;
  289.   }
  290.  
  291.   if (clipflags & ALIAS_RIGHT_CLIP)
  292.   {
  293.     k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
  294.               ALIAS_RIGHT_CLIP, k, R_Alias_clip_right);
  295.     if (k == 0)
  296.       return;
  297.  
  298.     pingpong ^= 1;
  299.   }
  300.  
  301.   if (clipflags & ALIAS_BOTTOM_CLIP)
  302.   {
  303.     k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
  304.               ALIAS_BOTTOM_CLIP, k, R_Alias_clip_bottom);
  305.     if (k == 0)
  306.       return;
  307.  
  308.     pingpong ^= 1;
  309.   }
  310.  
  311.   if (clipflags & ALIAS_TOP_CLIP)
  312.   {
  313.     k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
  314.               ALIAS_TOP_CLIP, k, R_Alias_clip_top);
  315.     if (k == 0)
  316.       return;
  317.  
  318.     pingpong ^= 1;
  319.   }
  320.  
  321.   for (i=0 ; i<k ; i++)
  322.   {
  323.     if (fv[pingpong][i].v[0] < r_refdef.aliasvrect.x)
  324.       fv[pingpong][i].v[0] = r_refdef.aliasvrect.x;
  325.     else if (fv[pingpong][i].v[0] > r_refdef.aliasvrectright)
  326.       fv[pingpong][i].v[0] = r_refdef.aliasvrectright;
  327.  
  328.     if (fv[pingpong][i].v[1] < r_refdef.aliasvrect.y)
  329.       fv[pingpong][i].v[1] = r_refdef.aliasvrect.y;
  330.     else if (fv[pingpong][i].v[1] > r_refdef.aliasvrectbottom)
  331.       fv[pingpong][i].v[1] = r_refdef.aliasvrectbottom;
  332.  
  333.     fv[pingpong][i].flags = 0;
  334.   }
  335.  
  336. // draw triangles
  337.   mtri.facesfront = ptri->facesfront;
  338.   r_affinetridesc.ptriangles = &mtri;
  339.   r_affinetridesc.pfinalverts = fv[pingpong];
  340.  
  341. // FIXME: do all at once as trifan?
  342.   mtri.vertindex[0] = 0;
  343.   for (i=1 ; i<k-1 ; i++)
  344.   {
  345.     mtri.vertindex[1] = i;
  346.     mtri.vertindex[2] = i+1;
  347.     D_PolysetDraw ();
  348.   }
  349. }
  350.  
  351.