home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 15 / MA_Cover_15.iso / source / winquake / d_edge.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-03-03  |  7.5 KB  |  340 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. // d_edge.c
  21.  
  22. #include "quakedef.h"
  23. #include "d_local.h"
  24.  
  25. #if !id68k
  26. static
  27. #endif
  28.  int    miplevel;
  29.  
  30. float        scale_for_mip;
  31. /* int            screenwidth; */
  32. int            ubasestep, errorterm, erroradjustup, erroradjustdown;
  33. int            vstartscan;
  34.  
  35. // FIXME: should go away
  36. extern void            R_RotateBmodel (void);
  37. extern void            R_TransformFrustum (void);
  38.  
  39. vec3_t        transformed_modelorg;
  40.  
  41. /*
  42. ==============
  43. D_DrawPoly
  44.  
  45. ==============
  46. */
  47. void D_DrawPoly (void)
  48. {
  49. // this driver takes spans, not polygons
  50. }
  51.  
  52.  
  53. /*
  54. =============
  55. D_MipLevelForScale
  56. =============
  57. */
  58. int D_MipLevelForScale (float scale)
  59. {
  60.     int        lmiplevel;
  61.  
  62.     if (scale >= d_scalemip[0] )
  63.         lmiplevel = 0;
  64.     else if (scale >= d_scalemip[1] )
  65.         lmiplevel = 1;
  66.     else if (scale >= d_scalemip[2] )
  67.         lmiplevel = 2;
  68.     else
  69.         lmiplevel = 3;
  70.  
  71.     if (lmiplevel < d_minmip)
  72.         lmiplevel = d_minmip;
  73.  
  74.     return lmiplevel;
  75. }
  76.  
  77.  
  78. /*
  79. ==============
  80. D_DrawSolidSurface
  81. ==============
  82. */
  83.  
  84. // FIXME: clean this up
  85.  
  86. void D_DrawSolidSurface (surf_t *surf, int color)
  87. {
  88.     espan_t    *span;
  89.     byte    *pdest;
  90.     int        u, u2, pix;
  91.     
  92.     pix = (color<<24) | (color<<16) | (color<<8) | color;
  93.     for (span=surf->spans ; span ; span=span->pnext)
  94.     {
  95.         pdest = (byte *)d_viewbuffer + screenwidth*span->v;
  96.         u = span->u;
  97.         u2 = span->u + span->count - 1;
  98.         ((byte *)pdest)[u] = pix;
  99.  
  100.         if (u2 - u < 8)
  101.         {
  102.             for (u++ ; u <= u2 ; u++)
  103.                 ((byte *)pdest)[u] = pix;
  104.         }
  105.         else
  106.         {
  107.             for (u++ ; u & 3 ; u++)
  108.                 ((byte *)pdest)[u] = pix;
  109.  
  110.             u2 -= 4;
  111.             for ( ; u <= u2 ; u+=4)
  112.                 *(int *)((byte *)pdest + u) = pix;
  113.             u2 += 4;
  114.             for ( ; u <= u2 ; u++)
  115.                 ((byte *)pdest)[u] = pix;
  116.         }
  117.     }
  118. }
  119.  
  120.  
  121. #if id68k
  122. extern void D_CalcGradients (msurface_t *pface);
  123. #else
  124. /*
  125. ==============
  126. D_CalcGradients
  127. ==============
  128. */
  129. void D_CalcGradients (msurface_t *pface)
  130. {
  131.     mplane_t    *pplane;
  132.     float        mipscale;
  133.     vec3_t        p_temp1;
  134.     vec3_t        p_saxis, p_taxis;
  135.     float        t;
  136.  
  137.     pplane = pface->plane;
  138.  
  139.     mipscale = 1.0 / (float)(1 << miplevel);
  140.  
  141.     TransformVector (pface->texinfo->vecs[0], p_saxis);
  142.     TransformVector (pface->texinfo->vecs[1], p_taxis);
  143.  
  144.     t = xscaleinv * mipscale;
  145.     d_sdivzstepu = p_saxis[0] * t;
  146.     d_tdivzstepu = p_taxis[0] * t;
  147.  
  148.     t = yscaleinv * mipscale;
  149.     d_sdivzstepv = -p_saxis[1] * t;
  150.     d_tdivzstepv = -p_taxis[1] * t;
  151.  
  152.     d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
  153.             ycenter * d_sdivzstepv;
  154.     d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
  155.             ycenter * d_tdivzstepv;
  156.  
  157.     VectorScale (transformed_modelorg, mipscale, p_temp1);
  158.  
  159.     t = 0x10000*mipscale;
  160.     sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
  161.             ((pface->texturemins[0] << 16) >> miplevel)
  162.             + pface->texinfo->vecs[0][3]*t;
  163.     tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
  164.             ((pface->texturemins[1] << 16) >> miplevel)
  165.             + pface->texinfo->vecs[1][3]*t;
  166.  
  167. //
  168. // -1 (-epsilon) so we never wander off the edge of the texture
  169. //
  170.     bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
  171.     bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
  172. }
  173.  
  174. #endif
  175.  
  176.  
  177. /*
  178. ==============
  179. D_DrawSurfaces
  180. ==============
  181. */
  182. void D_DrawSurfaces (void)
  183. {
  184.     surf_t            *s;
  185.     msurface_t        *pface;
  186.     surfcache_t        *pcurrentcache;
  187.     vec3_t            world_transformed_modelorg;
  188.     vec3_t            local_modelorg;
  189.  
  190.     currententity = &cl_entities[0];
  191.     TransformVector (modelorg, transformed_modelorg);
  192.     VectorCopy (transformed_modelorg, world_transformed_modelorg);
  193.  
  194. // TODO: could preset a lot of this at mode set time
  195.     if (r_drawflat.value)
  196.     {
  197.         for (s = &surfaces[1] ; s<surface_p ; s++)
  198.         {
  199.             if (!s->spans)
  200.                 continue;
  201.  
  202.             d_zistepu = s->d_zistepu;
  203.             d_zistepv = s->d_zistepv;
  204.             d_ziorigin = s->d_ziorigin;
  205.  
  206.             D_DrawSolidSurface (s, (int)s->data & 0xFF);
  207.             D_DrawZSpans (s->spans);
  208.         }
  209.     }
  210.     else
  211.     {
  212.         for (s = &surfaces[1] ; s<surface_p ; s++)
  213.         {
  214.             if (!s->spans)
  215.                 continue;
  216.  
  217.             r_drawnpolycount++;
  218.  
  219.             d_zistepu = s->d_zistepu;
  220.             d_zistepv = s->d_zistepv;
  221.             d_ziorigin = s->d_ziorigin;
  222.  
  223.             if (s->flags & SURF_DRAWSKY)
  224.             {
  225.                 if (!r_skymade)
  226.                 {
  227.                     R_MakeSky ();
  228.                 }
  229.  
  230.                 D_DrawSkyScans8 (s->spans);
  231.                 D_DrawZSpans (s->spans);
  232.             }
  233.             else if (s->flags & SURF_DRAWBACKGROUND)
  234.             {
  235.             // set up a gradient for the background surface that places it
  236.             // effectively at infinity distance from the viewpoint
  237.                 d_zistepu = 0;
  238.                 d_zistepv = 0;
  239.                 d_ziorigin = -0.9;
  240.  
  241.                 D_DrawSolidSurface (s, (int)r_clearcolor.value & 0xFF);
  242.                 D_DrawZSpans (s->spans);
  243.             }
  244.             else if (s->flags & SURF_DRAWTURB)
  245.             {
  246.                 pface = s->data;
  247.                 miplevel = 0;
  248.                 cacheblock = (pixel_t *)
  249.                         ((byte *)pface->texinfo->texture +
  250.                         pface->texinfo->texture->offsets[0]);
  251.                 cachewidth = 64;
  252.  
  253.                 if (s->insubmodel)
  254.                 {
  255.                 // FIXME: we don't want to do all this for every polygon!
  256.                 // TODO: store once at start of frame
  257.                     currententity = s->entity;    //FIXME: make this passed in to
  258.                                                 // R_RotateBmodel ()
  259.                     VectorSubtract (r_origin, currententity->origin,
  260.                             local_modelorg);
  261.                     TransformVector (local_modelorg, transformed_modelorg);
  262.  
  263.                     R_RotateBmodel ();    // FIXME: don't mess with the frustum,
  264.                                         // make entity passed in
  265.                 }
  266.  
  267.                 D_CalcGradients (pface);
  268.                 Turbulent8 (s->spans);
  269.                 D_DrawZSpans (s->spans);
  270.  
  271.                 if (s->insubmodel)
  272.                 {
  273.                 //
  274.                 // restore the old drawing state
  275.                 // FIXME: we don't want to do this every time!
  276.                 // TODO: speed up
  277.                 //
  278.                     currententity = &cl_entities[0];
  279.                     VectorCopy (world_transformed_modelorg,
  280.                                 transformed_modelorg);
  281.                     VectorCopy (base_vpn, vpn);
  282.                     VectorCopy (base_vup, vup);
  283.                     VectorCopy (base_vright, vright);
  284.                     VectorCopy (base_modelorg, modelorg);
  285.                     R_TransformFrustum ();
  286.                 }
  287.             }
  288.             else
  289.             {
  290.                 if (s->insubmodel)
  291.                 {
  292.                 // FIXME: we don't want to do all this for every polygon!
  293.                 // TODO: store once at start of frame
  294.                     currententity = s->entity;    //FIXME: make this passed in to
  295.                                                 // R_RotateBmodel ()
  296.                     VectorSubtract (r_origin, currententity->origin, local_modelorg);
  297.                     TransformVector (local_modelorg, transformed_modelorg);
  298.  
  299.                     R_RotateBmodel ();    // FIXME: don't mess with the frustum,
  300.                                         // make entity passed in
  301.                 }
  302.  
  303.                 pface = s->data;
  304.                 miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
  305.                 * pface->texinfo->mipadjust);
  306.  
  307.             // FIXME: make this passed in to D_CacheSurface
  308.                 pcurrentcache = D_CacheSurface (pface, miplevel);
  309.  
  310.                 cacheblock = (pixel_t *)pcurrentcache->data;
  311.                 cachewidth = pcurrentcache->width;
  312.  
  313.                 D_CalcGradients (pface);
  314.  
  315.                 (*d_drawspans) (s->spans);
  316.  
  317.                 D_DrawZSpans (s->spans);
  318.  
  319.                 if (s->insubmodel)
  320.                 {
  321.                 //
  322.                 // restore the old drawing state
  323.                 // FIXME: we don't want to do this every time!
  324.                 // TODO: speed up
  325.                 //
  326.                     currententity = &cl_entities[0];
  327.                     VectorCopy (world_transformed_modelorg,
  328.                                 transformed_modelorg);
  329.                     VectorCopy (base_vpn, vpn);
  330.                     VectorCopy (base_vup, vup);
  331.                     VectorCopy (base_vright, vright);
  332.                     VectorCopy (base_modelorg, modelorg);
  333.                     R_TransformFrustum ();
  334.                 }
  335.             }
  336.         }
  337.     }
  338. }
  339.  
  340.