git-svn-id: http://bladebattles.com/kurok/SVN@11 20cd92bb-ff49-0410-b73e-96a06e42c3b9
[kurok.git] / d_edge.c
blobbbd1c2c0dcc58692a9c50e560cf21bb0eeecc8f6
1 /*
2 Copyright (C) 1996-1997 Id Software, Inc.
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.
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.
13 See the GNU General Public License for more details.
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.
20 // d_edge.c
22 #include "quakedef.h"
23 #include "d_local.h"
25 static int miplevel;
27 float scale_for_mip;
28 int screenwidth;
29 int ubasestep, errorterm, erroradjustup, erroradjustdown;
30 int vstartscan;
32 // FIXME: should go away
33 extern void R_RotateBmodel (void);
34 extern void R_TransformFrustum (void);
36 vec3_t transformed_modelorg;
39 ==============
40 D_DrawPoly
42 ==============
44 void D_DrawPoly (void)
46 // this driver takes spans, not polygons
51 =============
52 D_MipLevelForScale
53 =============
55 int D_MipLevelForScale (float scale)
57 int lmiplevel;
59 if (scale >= d_scalemip[0] )
60 lmiplevel = 0;
61 else if (scale >= d_scalemip[1] )
62 lmiplevel = 1;
63 else if (scale >= d_scalemip[2] )
64 lmiplevel = 2;
65 else
66 lmiplevel = 3;
68 if (lmiplevel < d_minmip)
69 lmiplevel = d_minmip;
71 return lmiplevel;
76 ==============
77 D_DrawSolidSurface
78 ==============
81 // FIXME: clean this up
83 void D_DrawSolidSurface (surf_t *surf, int color)
85 espan_t *span;
86 byte *pdest;
87 int u, u2, pix;
89 pix = (color<<24) | (color<<16) | (color<<8) | color;
90 for (span=surf->spans ; span ; span=span->pnext)
92 pdest = (byte *)d_viewbuffer + screenwidth*span->v;
93 u = span->u;
94 u2 = span->u + span->count - 1;
95 ((byte *)pdest)[u] = pix;
97 if (u2 - u < 8)
99 for (u++ ; u <= u2 ; u++)
100 ((byte *)pdest)[u] = pix;
102 else
104 for (u++ ; u & 3 ; u++)
105 ((byte *)pdest)[u] = pix;
107 u2 -= 4;
108 for ( ; u <= u2 ; u+=4)
109 *(int *)((byte *)pdest + u) = pix;
110 u2 += 4;
111 for ( ; u <= u2 ; u++)
112 ((byte *)pdest)[u] = pix;
119 ==============
120 D_CalcGradients
121 ==============
123 void D_CalcGradients (msurface_t *pface)
125 mplane_t *pplane;
126 float mipscale;
127 vec3_t p_temp1;
128 vec3_t p_saxis, p_taxis;
129 float t;
131 pplane = pface->plane;
133 mipscale = 1.0 / (float)(1 << miplevel);
135 TransformVector (pface->texinfo->vecs[0], p_saxis);
136 TransformVector (pface->texinfo->vecs[1], p_taxis);
138 t = xscaleinv * mipscale;
139 d_sdivzstepu = p_saxis[0] * t;
140 d_tdivzstepu = p_taxis[0] * t;
142 t = yscaleinv * mipscale;
143 d_sdivzstepv = -p_saxis[1] * t;
144 d_tdivzstepv = -p_taxis[1] * t;
146 d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
147 ycenter * d_sdivzstepv;
148 d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
149 ycenter * d_tdivzstepv;
151 VectorScale (transformed_modelorg, mipscale, p_temp1);
153 t = 0x10000*mipscale;
154 sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
155 ((pface->texturemins[0] << 16) >> miplevel)
156 + pface->texinfo->vecs[0][3]*t;
157 tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
158 ((pface->texturemins[1] << 16) >> miplevel)
159 + pface->texinfo->vecs[1][3]*t;
162 // -1 (-epsilon) so we never wander off the edge of the texture
164 bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
165 bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
170 ==============
171 D_DrawSurfaces
172 ==============
174 void D_DrawSurfaces (void)
176 surf_t *s;
177 msurface_t *pface;
178 surfcache_t *pcurrentcache;
179 vec3_t world_transformed_modelorg;
180 vec3_t local_modelorg;
182 currententity = &cl_entities[0];
183 TransformVector (modelorg, transformed_modelorg);
184 VectorCopy (transformed_modelorg, world_transformed_modelorg);
186 // TODO: could preset a lot of this at mode set time
187 if (r_drawflat.value)
189 for (s = &surfaces[1] ; s<surface_p ; s++)
191 if (!s->spans)
192 continue;
194 d_zistepu = s->d_zistepu;
195 d_zistepv = s->d_zistepv;
196 d_ziorigin = s->d_ziorigin;
198 D_DrawSolidSurface (s, (int)s->data & 0xFF);
199 D_DrawZSpans (s->spans);
202 else
204 for (s = &surfaces[1] ; s<surface_p ; s++)
206 if (!s->spans)
207 continue;
209 r_drawnpolycount++;
211 d_zistepu = s->d_zistepu;
212 d_zistepv = s->d_zistepv;
213 d_ziorigin = s->d_ziorigin;
215 if (s->flags & SURF_DRAWSKY)
217 if (!r_skymade)
219 R_MakeSky ();
222 D_DrawSkyScans8 (s->spans);
223 D_DrawZSpans (s->spans);
225 else if (s->flags & SURF_DRAWBACKGROUND)
227 // set up a gradient for the background surface that places it
228 // effectively at infinity distance from the viewpoint
229 d_zistepu = 0;
230 d_zistepv = 0;
231 d_ziorigin = -0.9;
233 D_DrawSolidSurface (s, (int)r_clearcolor.value & 0xFF);
234 D_DrawZSpans (s->spans);
236 else if (s->flags & SURF_DRAWTURB)
238 pface = s->data;
239 miplevel = 0;
240 cacheblock = (pixel_t *)
241 ((byte *)pface->texinfo->texture +
242 pface->texinfo->texture->offsets[0]);
243 cachewidth = 64;
245 if (s->insubmodel)
247 // FIXME: we don't want to do all this for every polygon!
248 // TODO: store once at start of frame
249 currententity = s->entity; //FIXME: make this passed in to
250 // R_RotateBmodel ()
251 VectorSubtract (r_origin, currententity->origin,
252 local_modelorg);
253 TransformVector (local_modelorg, transformed_modelorg);
255 R_RotateBmodel (); // FIXME: don't mess with the frustum,
256 // make entity passed in
259 D_CalcGradients (pface);
260 Turbulent8 (s->spans);
261 D_DrawZSpans (s->spans);
263 if (s->insubmodel)
266 // restore the old drawing state
267 // FIXME: we don't want to do this every time!
268 // TODO: speed up
270 currententity = &cl_entities[0];
271 VectorCopy (world_transformed_modelorg,
272 transformed_modelorg);
273 VectorCopy (base_vpn, vpn);
274 VectorCopy (base_vup, vup);
275 VectorCopy (base_vright, vright);
276 VectorCopy (base_modelorg, modelorg);
277 R_TransformFrustum ();
280 else
282 if (s->insubmodel)
284 // FIXME: we don't want to do all this for every polygon!
285 // TODO: store once at start of frame
286 currententity = s->entity; //FIXME: make this passed in to
287 // R_RotateBmodel ()
288 VectorSubtract (r_origin, currententity->origin, local_modelorg);
289 TransformVector (local_modelorg, transformed_modelorg);
291 R_RotateBmodel (); // FIXME: don't mess with the frustum,
292 // make entity passed in
295 pface = s->data;
296 miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
297 * pface->texinfo->mipadjust);
299 // FIXME: make this passed in to D_CacheSurface
300 pcurrentcache = D_CacheSurface (pface, miplevel);
302 cacheblock = (pixel_t *)pcurrentcache->data;
303 cachewidth = pcurrentcache->width;
305 D_CalcGradients (pface);
307 (*d_drawspans) (s->spans);
309 D_DrawZSpans (s->spans);
311 if (s->insubmodel)
314 // restore the old drawing state
315 // FIXME: we don't want to do this every time!
316 // TODO: speed up
318 currententity = &cl_entities[0];
319 VectorCopy (world_transformed_modelorg,
320 transformed_modelorg);
321 VectorCopy (base_vpn, vpn);
322 VectorCopy (base_vup, vup);
323 VectorCopy (base_vright, vright);
324 VectorCopy (base_modelorg, modelorg);
325 R_TransformFrustum ();