d_edge.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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 = &r_worldentity;
  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. #ifdef __alpha__
  158. D_DrawSolidSurface (s, (int)((long)s->data & 0xFF));
  159. #else
  160. D_DrawSolidSurface (s, (int)s->data & 0xFF);
  161. #endif
  162. D_DrawZSpans (s->spans);
  163. }
  164. }
  165. else
  166. {
  167. for (s = &surfaces[1] ; s<surface_p ; s++)
  168. {
  169. if (!s->spans)
  170. continue;
  171. r_drawnpolycount++;
  172. d_zistepu = s->d_zistepu;
  173. d_zistepv = s->d_zistepv;
  174. d_ziorigin = s->d_ziorigin;
  175. if (s->flags & SURF_DRAWSKY)
  176. {
  177. if (!r_skymade)
  178. {
  179. R_MakeSky ();
  180. }
  181. D_DrawSkyScans8 (s->spans);
  182. D_DrawZSpans (s->spans);
  183. }
  184. else if (s->flags & SURF_DRAWBACKGROUND)
  185. {
  186. // set up a gradient for the background surface that places it
  187. // effectively at infinity distance from the viewpoint
  188. d_zistepu = 0;
  189. d_zistepv = 0;
  190. d_ziorigin = -0.9;
  191. D_DrawSolidSurface (s, (int)r_clearcolor.value & 0xFF);
  192. D_DrawZSpans (s->spans);
  193. }
  194. else if (s->flags & SURF_DRAWTURB)
  195. {
  196. pface = s->data;
  197. miplevel = 0;
  198. cacheblock = (pixel_t *)
  199. ((byte *)pface->texinfo->texture +
  200. pface->texinfo->texture->offsets[0]);
  201. cachewidth = 64;
  202. if (s->insubmodel)
  203. {
  204. // FIXME: we don't want to do all this for every polygon!
  205. // TODO: store once at start of frame
  206. currententity = s->entity; //FIXME: make this passed in to
  207. // R_RotateBmodel ()
  208. VectorSubtract (r_origin, currententity->origin,
  209. local_modelorg);
  210. TransformVector (local_modelorg, transformed_modelorg);
  211. R_RotateBmodel (); // FIXME: don't mess with the frustum,
  212. // make entity passed in
  213. }
  214. D_CalcGradients (pface);
  215. Turbulent8 (s->spans);
  216. D_DrawZSpans (s->spans);
  217. if (s->insubmodel)
  218. {
  219. //
  220. // restore the old drawing state
  221. // FIXME: we don't want to do this every time!
  222. // TODO: speed up
  223. //
  224. currententity = &r_worldentity;
  225. VectorCopy (world_transformed_modelorg,
  226. transformed_modelorg);
  227. VectorCopy (base_vpn, vpn);
  228. VectorCopy (base_vup, vup);
  229. VectorCopy (base_vright, vright);
  230. VectorCopy (base_modelorg, modelorg);
  231. R_TransformFrustum ();
  232. }
  233. }
  234. else
  235. {
  236. if (s->insubmodel)
  237. {
  238. // FIXME: we don't want to do all this for every polygon!
  239. // TODO: store once at start of frame
  240. currententity = s->entity; //FIXME: make this passed in to
  241. // R_RotateBmodel ()
  242. VectorSubtract (r_origin, currententity->origin, local_modelorg);
  243. TransformVector (local_modelorg, transformed_modelorg);
  244. R_RotateBmodel (); // FIXME: don't mess with the frustum,
  245. // make entity passed in
  246. }
  247. pface = s->data;
  248. miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
  249. * pface->texinfo->mipadjust);
  250. // FIXME: make this passed in to D_CacheSurface
  251. pcurrentcache = D_CacheSurface (pface, miplevel);
  252. cacheblock = (pixel_t *)pcurrentcache->data;
  253. cachewidth = pcurrentcache->width;
  254. D_CalcGradients (pface);
  255. (*d_drawspans) (s->spans);
  256. D_DrawZSpans (s->spans);
  257. if (s->insubmodel)
  258. {
  259. //
  260. // restore the old drawing state
  261. // FIXME: we don't want to do this every time!
  262. // TODO: speed up
  263. //
  264. VectorCopy (world_transformed_modelorg,
  265. transformed_modelorg);
  266. VectorCopy (base_vpn, vpn);
  267. VectorCopy (base_vup, vup);
  268. VectorCopy (base_vright, vright);
  269. VectorCopy (base_modelorg, modelorg);
  270. R_TransformFrustum ();
  271. currententity = &r_worldentity;
  272. }
  273. }
  274. }
  275. }
  276. }