home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / quake_src / r_aclip.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-17  |  9.0 KB  |  357 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. #if defined(M68KASM) || defined(PPCASM)
  40. extern int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag,
  41.                         int count, void(*clip)(finalvert_t *pfv0,
  42.                         finalvert_t *pfv1, finalvert_t *out) );
  43. #endif
  44.  
  45.  
  46. /*
  47. ================
  48. R_Alias_clip_z
  49.  
  50. pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
  51. ================
  52. */
  53. void R_Alias_clip_z (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
  54. {
  55.   float   scale;
  56.   auxvert_t *pav0, *pav1, avout;
  57.  
  58.   pav0 = &av[pfv0 - &fv[0][0]];
  59.   pav1 = &av[pfv1 - &fv[0][0]];
  60.  
  61.   if (pfv0->v[1] >= pfv1->v[1])
  62.   {
  63.     scale = (ALIAS_Z_CLIP_PLANE - pav0->fv[2]) /
  64.         (pav1->fv[2] - pav0->fv[2]);
  65.   
  66.     avout.fv[0] = pav0->fv[0] + (pav1->fv[0] - pav0->fv[0]) * scale;
  67.     avout.fv[1] = pav0->fv[1] + (pav1->fv[1] - pav0->fv[1]) * scale;
  68.     avout.fv[2] = ALIAS_Z_CLIP_PLANE;
  69.   
  70.     out->v[2] = pfv0->v[2] + (pfv1->v[2] - pfv0->v[2]) * scale;
  71.     out->v[3] = pfv0->v[3] + (pfv1->v[3] - pfv0->v[3]) * scale;
  72.     out->v[4] = pfv0->v[4] + (pfv1->v[4] - pfv0->v[4]) * scale;
  73.   }
  74.   else
  75.   {
  76.     scale = (ALIAS_Z_CLIP_PLANE - pav1->fv[2]) /
  77.         (pav0->fv[2] - pav1->fv[2]);
  78.   
  79.     avout.fv[0] = pav1->fv[0] + (pav0->fv[0] - pav1->fv[0]) * scale;
  80.     avout.fv[1] = pav1->fv[1] + (pav0->fv[1] - pav1->fv[1]) * scale;
  81.     avout.fv[2] = ALIAS_Z_CLIP_PLANE;
  82.   
  83.     out->v[2] = pfv1->v[2] + (pfv0->v[2] - pfv1->v[2]) * scale;
  84.     out->v[3] = pfv1->v[3] + (pfv0->v[3] - pfv1->v[3]) * scale;
  85.     out->v[4] = pfv1->v[4] + (pfv0->v[4] - pfv1->v[4]) * scale;
  86.   }
  87.  
  88.   R_AliasProjectFinalVert (out, &avout);
  89.  
  90.   if (out->v[0] < r_refdef.aliasvrect.x)
  91.     out->flags |= ALIAS_LEFT_CLIP;
  92.   if (out->v[1] < r_refdef.aliasvrect.y)
  93.     out->flags |= ALIAS_TOP_CLIP;
  94.   if (out->v[0] > r_refdef.aliasvrectright)
  95.     out->flags |= ALIAS_RIGHT_CLIP;
  96.   if (out->v[1] > r_refdef.aliasvrectbottom)
  97.     out->flags |= ALIAS_BOTTOM_CLIP;  
  98. }
  99.  
  100.  
  101. #if !id386 && !defined(M68KASM) && !defined(PPCASM)
  102. void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
  103. {
  104.   float   scale;
  105.   int     i;
  106.  
  107.   if (pfv0->v[1] >= pfv1->v[1])
  108.   {
  109.     scale = (float)(r_refdef.aliasvrect.x - pfv0->v[0]) /
  110.         (pfv1->v[0] - pfv0->v[0]);
  111.     for (i=0 ; i<6 ; i++)
  112.       out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
  113.   }
  114.   else
  115.   {
  116.     scale = (float)(r_refdef.aliasvrect.x - pfv1->v[0]) /
  117.         (pfv0->v[0] - pfv1->v[0]);
  118.     for (i=0 ; i<6 ; i++)
  119.       out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
  120.   }
  121. }
  122.  
  123.  
  124. void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
  125.   finalvert_t *out)
  126. {
  127.   float   scale;
  128.   int     i;
  129.  
  130.   if (pfv0->v[1] >= pfv1->v[1])
  131.   {
  132.     scale = (float)(r_refdef.aliasvrectright - pfv0->v[0]) /
  133.         (pfv1->v[0] - pfv0->v[0]);
  134.     for (i=0 ; i<6 ; i++)
  135.       out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
  136.   }
  137.   else
  138.   {
  139.     scale = (float)(r_refdef.aliasvrectright - pfv1->v[0]) /
  140.         (pfv0->v[0] - pfv1->v[0]);
  141.     for (i=0 ; i<6 ; i++)
  142.       out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
  143.   }
  144. }
  145.  
  146.  
  147. void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
  148. {
  149.   float   scale;
  150.   int     i;
  151.  
  152.   if (pfv0->v[1] >= pfv1->v[1])
  153.   {
  154.     scale = (float)(r_refdef.aliasvrect.y - pfv0->v[1]) /
  155.         (pfv1->v[1] - pfv0->v[1]);
  156.     for (i=0 ; i<6 ; i++)
  157.       out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
  158.   }
  159.   else
  160.   {
  161.     scale = (float)(r_refdef.aliasvrect.y - pfv1->v[1]) /
  162.         (pfv0->v[1] - pfv1->v[1]);
  163.     for (i=0 ; i<6 ; i++)
  164.       out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
  165.   }
  166. }
  167.  
  168.  
  169. void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
  170.   finalvert_t *out)
  171. {
  172.   float   scale;
  173.   int     i;
  174.  
  175.   if (pfv0->v[1] >= pfv1->v[1])
  176.   {
  177.     scale = (float)(r_refdef.aliasvrectbottom - pfv0->v[1]) /
  178.         (pfv1->v[1] - pfv0->v[1]);
  179.  
  180.     for (i=0 ; i<6 ; i++)
  181.       out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5;
  182.   }
  183.   else
  184.   {
  185.     scale = (float)(r_refdef.aliasvrectbottom - pfv1->v[1]) /
  186.         (pfv0->v[1] - pfv1->v[1]);
  187.  
  188.     for (i=0 ; i<6 ; i++)
  189.       out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5;
  190.   }
  191. }
  192. #endif
  193.  
  194.  
  195. #if !defined(M68KASM) && !defined(PPCASM)
  196. int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count,
  197.   void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) )
  198. {
  199.   int     i,j,k;
  200.   int     flags, oldflags;
  201.   
  202.   j = count-1;
  203.   k = 0;
  204.   for (i=0 ; i<count ; j = i, i++)
  205.   {
  206.     oldflags = in[j].flags & flag;
  207.     flags = in[i].flags & flag;
  208.  
  209.     if (flags && oldflags)
  210.       continue;
  211.     if (oldflags ^ flags)
  212.     {
  213.       clip (&in[j], &in[i], &out[k]);
  214.       out[k].flags = 0;
  215.       if (out[k].v[0] < r_refdef.aliasvrect.x)
  216.         out[k].flags |= ALIAS_LEFT_CLIP;
  217.       if (out[k].v[1] < r_refdef.aliasvrect.y)
  218.         out[k].flags |= ALIAS_TOP_CLIP;
  219.       if (out[k].v[0] > r_refdef.aliasvrectright)
  220.         out[k].flags |= ALIAS_RIGHT_CLIP;
  221.       if (out[k].v[1] > r_refdef.aliasvrectbottom)
  222.         out[k].flags |= ALIAS_BOTTOM_CLIP;  
  223.       k++;
  224.     }
  225.     if (!flags)
  226.     {
  227.       out[k] = in[i];
  228.       k++;
  229.     }
  230.   }
  231.   
  232.   return k;
  233. }
  234. #endif
  235.  
  236.  
  237. /*
  238. ================
  239. R_AliasClipTriangle
  240. ================
  241. */
  242. void R_AliasClipTriangle (mtriangle_t *ptri)
  243. {
  244.   int       i, k, pingpong;
  245.   mtriangle_t   mtri;
  246.   unsigned    clipflags;
  247.  
  248. // copy vertexes and fix seam texture coordinates
  249.   if (ptri->facesfront)
  250.   {
  251.     fv[0][0] = pfinalverts[ptri->vertindex[0]];
  252.     fv[0][1] = pfinalverts[ptri->vertindex[1]];
  253.     fv[0][2] = pfinalverts[ptri->vertindex[2]];
  254.   }
  255.   else
  256.   {
  257.     for (i=0 ; i<3 ; i++)
  258.     {
  259.       fv[0][i] = pfinalverts[ptri->vertindex[i]];
  260.   
  261.       if (!ptri->facesfront && (fv[0][i].flags & ALIAS_ONSEAM) )
  262.         fv[0][i].v[2] += r_affinetridesc.seamfixupX16;
  263.     }
  264.   }
  265.  
  266. // clip
  267.   clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags;
  268.  
  269.   if (clipflags & ALIAS_Z_CLIP)
  270.   {
  271.     for (i=0 ; i<3 ; i++)
  272.       av[i] = pauxverts[ptri->vertindex[i]];
  273.  
  274.     k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z);
  275.     if (k == 0)
  276.       return;
  277.  
  278.     pingpong = 1;
  279.     clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags;
  280.   }
  281.   else
  282.   {
  283.     pingpong = 0;
  284.     k = 3;
  285.   }
  286.  
  287.   if (clipflags & ALIAS_LEFT_CLIP)
  288.   {
  289.     k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
  290.               ALIAS_LEFT_CLIP, k, R_Alias_clip_left);
  291.     if (k == 0)
  292.       return;
  293.  
  294.     pingpong ^= 1;
  295.   }
  296.  
  297.   if (clipflags & ALIAS_RIGHT_CLIP)
  298.   {
  299.     k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
  300.               ALIAS_RIGHT_CLIP, k, R_Alias_clip_right);
  301.     if (k == 0)
  302.       return;
  303.  
  304.     pingpong ^= 1;
  305.   }
  306.  
  307.   if (clipflags & ALIAS_BOTTOM_CLIP)
  308.   {
  309.     k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
  310.               ALIAS_BOTTOM_CLIP, k, R_Alias_clip_bottom);
  311.     if (k == 0)
  312.       return;
  313.  
  314.     pingpong ^= 1;
  315.   }
  316.  
  317.   if (clipflags & ALIAS_TOP_CLIP)
  318.   {
  319.     k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
  320.               ALIAS_TOP_CLIP, k, R_Alias_clip_top);
  321.     if (k == 0)
  322.       return;
  323.  
  324.     pingpong ^= 1;
  325.   }
  326.  
  327.   for (i=0 ; i<k ; i++)
  328.   {
  329.     if (fv[pingpong][i].v[0] < r_refdef.aliasvrect.x)
  330.       fv[pingpong][i].v[0] = r_refdef.aliasvrect.x;
  331.     else if (fv[pingpong][i].v[0] > r_refdef.aliasvrectright)
  332.       fv[pingpong][i].v[0] = r_refdef.aliasvrectright;
  333.  
  334.     if (fv[pingpong][i].v[1] < r_refdef.aliasvrect.y)
  335.       fv[pingpong][i].v[1] = r_refdef.aliasvrect.y;
  336.     else if (fv[pingpong][i].v[1] > r_refdef.aliasvrectbottom)
  337.       fv[pingpong][i].v[1] = r_refdef.aliasvrectbottom;
  338.  
  339.     fv[pingpong][i].flags = 0;
  340.   }
  341.  
  342. // draw triangles
  343.   mtri.facesfront = ptri->facesfront;
  344.   r_affinetridesc.ptriangles = &mtri;
  345.   r_affinetridesc.pfinalverts = fv[pingpong];
  346.  
  347. // FIXME: do all at once as trifan?
  348.   mtri.vertindex[0] = 0;
  349.   for (i=1 ; i<k-1 ; i++)
  350.   {
  351.     mtri.vertindex[1] = i;
  352.     mtri.vertindex[2] = i+1;
  353.     D_PolysetDraw ();
  354.   }
  355. }
  356.  
  357.