d_edge.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // d_edge.c
  16. #include "quakedef.h"
  17. #include "d_local.h"
  18. static int miplevel;
  19. float scale_for_mip;
  20. int screenwidth;
  21. int ubasestep, errorterm, erroradjustup, erroradjustdown;
  22. int vstartscan;
  23. // FIXME: should go away
  24. extern void R_RotateBmodel (void);
  25. extern void R_TransformFrustum (void);
  26. vec3_t transformed_modelorg;
  27. /*
  28. ==============
  29. D_DrawPoly
  30. ==============
  31. */
  32. void D_DrawPoly (void)
  33. {
  34. // this driver takes spans, not polygons
  35. }
  36. /*
  37. =============
  38. D_MipLevelForScale
  39. =============
  40. */
  41. int D_MipLevelForScale (float scale)
  42. {
  43. int lmiplevel;
  44. if (scale >= d_scalemip[0] )
  45. lmiplevel = 0;
  46. else if (scale >= d_scalemip[1] )
  47. lmiplevel = 1;
  48. else if (scale >= d_scalemip[2] )
  49. lmiplevel = 2;
  50. else
  51. lmiplevel = 3;
  52. if (lmiplevel < d_minmip)
  53. lmiplevel = d_minmip;
  54. return lmiplevel;
  55. }
  56. /*
  57. ==============
  58. D_DrawSolidSurface
  59. ==============
  60. */
  61. // FIXME: clean this up
  62. void D_DrawSolidSurface (surf_t *surf, int color)
  63. {
  64. espan_t *span;
  65. byte *pdest;
  66. int u, u2, pix;
  67. pix = (color<<24) | (color<<16) | (color<<8) | color;
  68. for (span=surf->spans ; span ; span=span->pnext)
  69. {
  70. pdest = (byte *)d_viewbuffer + screenwidth*span->v;
  71. u = span->u;
  72. u2 = span->u + span->count - 1;
  73. ((byte *)pdest)[u] = pix;
  74. if (u2 - u < 8)
  75. {
  76. for (u++ ; u <= u2 ; u++)
  77. ((byte *)pdest)[u] = pix;
  78. }
  79. else
  80. {
  81. for (u++ ; u & 3 ; u++)
  82. ((byte *)pdest)[u] = pix;
  83. u2 -= 4;
  84. for ( ; u <= u2 ; u+=4)
  85. *(int *)((byte *)pdest + u) = pix;
  86. u2 += 4;
  87. for ( ; u <= u2 ; u++)
  88. ((byte *)pdest)[u] = pix;
  89. }
  90. }
  91. }
  92. /*
  93. ==============
  94. D_CalcGradients
  95. ==============
  96. */
  97. void D_CalcGradients (msurface_t *pface)
  98. {
  99. mplane_t *pplane;
  100. float mipscale;
  101. vec3_t p_temp1;
  102. vec3_t p_saxis, p_taxis;
  103. float t;
  104. pplane = pface->plane;
  105. mipscale = 1.0 / (float)(1 << miplevel);
  106. TransformVector (pface->texinfo->vecs[0], p_saxis);
  107. TransformVector (pface->texinfo->vecs[1], p_taxis);
  108. t = xscaleinv * mipscale;
  109. d_sdivzstepu = p_saxis[0] * t;
  110. d_tdivzstepu = p_taxis[0] * t;
  111. t = yscaleinv * mipscale;
  112. d_sdivzstepv = -p_saxis[1] * t;
  113. d_tdivzstepv = -p_taxis[1] * t;
  114. d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
  115. ycenter * d_sdivzstepv;
  116. d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
  117. ycenter * d_tdivzstepv;
  118. VectorScale (transformed_modelorg, mipscale, p_temp1);
  119. t = 0x10000*mipscale;
  120. sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
  121. ((pface->texturemins[0] << 16) >> miplevel)
  122. + pface->texinfo->vecs[0][3]*t;
  123. tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
  124. ((pface->texturemins[1] << 16) >> miplevel)
  125. + pface->texinfo->vecs[1][3]*t;
  126. //
  127. // -1 (-epsilon) so we never wander off the edge of the texture
  128. //
  129. bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
  130. bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
  131. }
  132. /*
  133. ==============
  134. D_DrawSurfaces
  135. ==============
  136. */
  137. void D_DrawSurfaces (void)
  138. {
  139. surf_t *s;
  140. msurface_t *pface;
  141. surfcache_t *pcurrentcache;
  142. vec3_t world_transformed_modelorg;
  143. vec3_t local_modelorg;
  144. currententity = &cl_entities[0];
  145. TransformVector (modelorg, transformed_modelorg);
  146. VectorCopy (transformed_modelorg, world_transformed_modelorg);
  147. // TODO: could preset a lot of this at mode set time
  148. if (r_drawflat.value)
  149. {
  150. for (s = &surfaces[1] ; s<surface_p ; s++)
  151. {
  152. if (!s->spans)
  153. continue;
  154. d_zistepu = s->d_zistepu;
  155. d_zistepv = s->d_zistepv;
  156. d_ziorigin = s->d_ziorigin;
  157. D_DrawSolidSurface (s, (int)s->data & 0xFF);
  158. D_DrawZSpans (s->spans);
  159. }
  160. }
  161. else
  162. {
  163. for (s = &surfaces[1] ; s<surface_p ; s++)
  164. {
  165. if (!s->spans)
  166. continue;
  167. r_drawnpolycount++;
  168. d_zistepu = s->d_zistepu;
  169. d_zistepv = s->d_zistepv;
  170. d_ziorigin = s->d_ziorigin;
  171. if (s->flags & SURF_DRAWSKY)
  172. {
  173. if (!r_skymade)
  174. {
  175. R_MakeSky ();
  176. }
  177. D_DrawSkyScans8 (s->spans);
  178. D_DrawZSpans (s->spans);
  179. }
  180. else if (s->flags & SURF_DRAWBACKGROUND)
  181. {
  182. // set up a gradient for the background surface that places it
  183. // effectively at infinity distance from the viewpoint
  184. d_zistepu = 0;
  185. d_zistepv = 0;
  186. d_ziorigin = -0.9;
  187. D_DrawSolidSurface (s, (int)r_clearcolor.value & 0xFF);
  188. D_DrawZSpans (s->spans);
  189. }
  190. else if (s->flags & SURF_DRAWTURB)
  191. {
  192. pface = s->data;
  193. miplevel = 0;
  194. cacheblock = (pixel_t *)
  195. ((byte *)pface->texinfo->texture +
  196. pface->texinfo->texture->offsets[0]);
  197. cachewidth = 64;
  198. if (s->insubmodel)
  199. {
  200. // FIXME: we don't want to do all this for every polygon!
  201. // TODO: store once at start of frame
  202. currententity = s->entity; //FIXME: make this passed in to
  203. // R_RotateBmodel ()
  204. VectorSubtract (r_origin, currententity->origin,
  205. local_modelorg);
  206. TransformVector (local_modelorg, transformed_modelorg);
  207. R_RotateBmodel (); // FIXME: don't mess with the frustum,
  208. // make entity passed in
  209. }
  210. D_CalcGradients (pface);
  211. Turbulent8 (s->spans);
  212. D_DrawZSpans (s->spans);
  213. if (s->insubmodel)
  214. {
  215. //
  216. // restore the old drawing state
  217. // FIXME: we don't want to do this every time!
  218. // TODO: speed up
  219. //
  220. currententity = &cl_entities[0];
  221. VectorCopy (world_transformed_modelorg,
  222. transformed_modelorg);
  223. VectorCopy (base_vpn, vpn);
  224. VectorCopy (base_vup, vup);
  225. VectorCopy (base_vright, vright);
  226. VectorCopy (base_modelorg, modelorg);
  227. R_TransformFrustum ();
  228. }
  229. }
  230. else
  231. {
  232. if (s->insubmodel)
  233. {
  234. // FIXME: we don't want to do all this for every polygon!
  235. // TODO: store once at start of frame
  236. currententity = s->entity; //FIXME: make this passed in to
  237. // R_RotateBmodel ()
  238. VectorSubtract (r_origin, currententity->origin, local_modelorg);
  239. TransformVector (local_modelorg, transformed_modelorg);
  240. R_RotateBmodel (); // FIXME: don't mess with the frustum,
  241. // make entity passed in
  242. }
  243. pface = s->data;
  244. miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
  245. * pface->texinfo->mipadjust);
  246. // FIXME: make this passed in to D_CacheSurface
  247. pcurrentcache = D_CacheSurface (pface, miplevel);
  248. cacheblock = (pixel_t *)pcurrentcache->data;
  249. cachewidth = pcurrentcache->width;
  250. D_CalcGradients (pface);
  251. (*d_drawspans) (s->spans);
  252. D_DrawZSpans (s->spans);
  253. if (s->insubmodel)
  254. {
  255. //
  256. // restore the old drawing state
  257. // FIXME: we don't want to do this every time!
  258. // TODO: speed up
  259. //
  260. currententity = &cl_entities[0];
  261. VectorCopy (world_transformed_modelorg,
  262. transformed_modelorg);
  263. VectorCopy (base_vpn, vpn);
  264. VectorCopy (base_vup, vup);
  265. VectorCopy (base_vright, vright);
  266. VectorCopy (base_modelorg, modelorg);
  267. R_TransformFrustum ();
  268. }
  269. }
  270. }
  271. }
  272. }