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