Home | History | Annotate | Download | only in WinQuake
      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 */
     44 void D_DrawPoly (void)
     45 {
     46 // this driver takes spans, not polygons
     47 }
     48 
     49 
     50 /*
     51 =============
     52 D_MipLevelForScale
     53 =============
     54 */
     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 
     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 */
    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 */
    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 = &cl_entities[0];
    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 			D_DrawSolidSurface (s, (int)s->data & 0xFF);
    199 			D_DrawZSpans (s->spans);
    200 		}
    201 	}
    202 	else
    203 	{
    204 		for (s = &surfaces[1] ; s<surface_p ; s++)
    205 		{
    206 			if (!s->spans)
    207 				continue;
    208 
    209 			r_drawnpolycount++;
    210 
    211 			d_zistepu = s->d_zistepu;
    212 			d_zistepv = s->d_zistepv;
    213 			d_ziorigin = s->d_ziorigin;
    214 
    215 			if (s->flags & SURF_DRAWSKY)
    216 			{
    217 				if (!r_skymade)
    218 				{
    219 					R_MakeSky ();
    220 				}
    221 
    222 				D_DrawSkyScans8 (s->spans);
    223 				D_DrawZSpans (s->spans);
    224 			}
    225 			else if (s->flags & SURF_DRAWBACKGROUND)
    226 			{
    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;
    232 
    233 				D_DrawSolidSurface (s, (int)r_clearcolor.value & 0xFF);
    234 				D_DrawZSpans (s->spans);
    235 			}
    236 			else if (s->flags & SURF_DRAWTURB)
    237 			{
    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;
    244 
    245 				if (s->insubmodel)
    246 				{
    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);
    254 
    255 					R_RotateBmodel ();	// FIXME: don't mess with the frustum,
    256 										// make entity passed in
    257 				}
    258 
    259 				D_CalcGradients (pface);
    260 				Turbulent8 (s->spans);
    261 				D_DrawZSpans (s->spans);
    262 
    263 				if (s->insubmodel)
    264 				{
    265 				//
    266 				// restore the old drawing state
    267 				// FIXME: we don't want to do this every time!
    268 				// TODO: speed up
    269 				//
    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 ();
    278 				}
    279 			}
    280 			else
    281 			{
    282 				if (s->insubmodel)
    283 				{
    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);
    290 
    291 					R_RotateBmodel ();	// FIXME: don't mess with the frustum,
    292 										// make entity passed in
    293 				}
    294 
    295 				pface = s->data;
    296 				miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip
    297 				* pface->texinfo->mipadjust);
    298 
    299 			// FIXME: make this passed in to D_CacheSurface
    300 				pcurrentcache = D_CacheSurface (pface, miplevel);
    301 
    302 				cacheblock = (pixel_t *)pcurrentcache->data;
    303 				cachewidth = pcurrentcache->width;
    304 
    305 				D_CalcGradients (pface);
    306 
    307 				(*d_drawspans) (s->spans);
    308 
    309 				D_DrawZSpans (s->spans);
    310 
    311 				if (s->insubmodel)
    312 				{
    313 				//
    314 				// restore the old drawing state
    315 				// FIXME: we don't want to do this every time!
    316 				// TODO: speed up
    317 				//
    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 ();
    326 				}
    327 			}
    328 		}
    329 	}
    330 }
    331 
    332