19fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
29fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamCopyright (C) 1996-1997 Id Software, Inc.
39fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
49fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamThis program is free software; you can redistribute it and/or
59fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammodify it under the terms of the GNU General Public License
69fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamas published by the Free Software Foundation; either version 2
79fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamof the License, or (at your option) any later version.
89fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
99fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamThis program is distributed in the hope that it will be useful,
109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreambut WITHOUT ANY WARRANTY; without even the implied warranty of
119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamSee the GNU General Public License for more details.
149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamYou should have received a copy of the GNU General Public License
169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamalong with this program; if not, write to the Free Software
179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// r_draw.c
229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "quakedef.h"
249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "r_local.h"
259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "d_local.h"	// FIXME: shouldn't need to include this
269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define MAXLEFTCLIPEDGES		100
289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// !!! if these are changed, they must be changed in asm_draw.h too !!!
309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define FULLY_CLIPPED_CACHED	0x80000000
319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#define FRAMECOUNT_MASK			0x7FFFFFFF
329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamunsigned int	cacheoffset;
349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint			c_faceclip;					// number of faces clipped
369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamzpointdesc_t	r_zpointdesc;
389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreampolydesc_t		r_polydesc;
409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamclipplane_t	*entity_clipplanes;
449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamclipplane_t	view_clipplanes[4];
459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamclipplane_t	world_clipplanes[16];
469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammedge_t			*r_pedge;
489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamqboolean		r_leftclipped, r_rightclipped;
509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic qboolean	makeleftedge, makerightedge;
519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamqboolean		r_nearzionly;
529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint		sintable[SIN_BUFFER_SIZE];
549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint		intsintable[SIN_BUFFER_SIZE];
559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammvertex_t	r_leftenter, r_leftexit;
579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreammvertex_t	r_rightenter, r_rightexit;
589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamtypedef struct
609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	float	u,v;
629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int		ceilv;
639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream} evert_t;
649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint				r_emitted;
669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamfloat			r_nearzi;
679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamfloat			r_u1, r_v1, r_lzi1;
689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint				r_ceilv1;
699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamqboolean	r_lastvertvalid;
719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#if	!id386
749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_EmitEdge
789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	edge_t	*edge, *pcheck;
839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int		u_check;
849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	float	u, u_step;
859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	vec3_t	local, transformed;
869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	float	*world;
879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int		v, v2, ceilv0;
889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	float	scale, lzi0, u0, v0;
899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int		side;
909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (r_lastvertvalid)
929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		u0 = r_u1;
949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		v0 = r_v1;
959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		lzi0 = r_lzi1;
969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		ceilv0 = r_ceilv1;
979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	else
999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
1009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		world = &pv0->position[0];
1019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// transform and project
1039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		VectorSubtract (world, modelorg, local);
1049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		TransformVector (local, transformed);
1059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (transformed[2] < NEAR_CLIP)
1079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			transformed[2] = NEAR_CLIP;
1089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		lzi0 = 1.0 / transformed[2];
1109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// FIXME: build x/yscale into transform?
1129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		scale = xscale * lzi0;
1139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		u0 = (xcenter + scale*transformed[0]);
1149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (u0 < r_refdef.fvrectx_adj)
1159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			u0 = r_refdef.fvrectx_adj;
1169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (u0 > r_refdef.fvrectright_adj)
1179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			u0 = r_refdef.fvrectright_adj;
1189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		scale = yscale * lzi0;
1209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		v0 = (ycenter - scale*transformed[1]);
1219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (v0 < r_refdef.fvrecty_adj)
1229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			v0 = r_refdef.fvrecty_adj;
1239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (v0 > r_refdef.fvrectbottom_adj)
1249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			v0 = r_refdef.fvrectbottom_adj;
1259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		ceilv0 = (int) ceil(v0);
1279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
1289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	world = &pv1->position[0];
1309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// transform and project
1329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	VectorSubtract (world, modelorg, local);
1339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	TransformVector (local, transformed);
1349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (transformed[2] < NEAR_CLIP)
1369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		transformed[2] = NEAR_CLIP;
1379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_lzi1 = 1.0 / transformed[2];
1399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	scale = xscale * r_lzi1;
1419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_u1 = (xcenter + scale*transformed[0]);
1429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (r_u1 < r_refdef.fvrectx_adj)
1439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_u1 = r_refdef.fvrectx_adj;
1449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (r_u1 > r_refdef.fvrectright_adj)
1459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_u1 = r_refdef.fvrectright_adj;
1469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	scale = yscale * r_lzi1;
1489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_v1 = (ycenter - scale*transformed[1]);
1499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (r_v1 < r_refdef.fvrecty_adj)
1509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_v1 = r_refdef.fvrecty_adj;
1519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (r_v1 > r_refdef.fvrectbottom_adj)
1529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_v1 = r_refdef.fvrectbottom_adj;
1539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (r_lzi1 > lzi0)
1559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		lzi0 = r_lzi1;
1569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (lzi0 > r_nearzi)	// for mipmap finding
1589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_nearzi = lzi0;
1599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// for right edges, all we want is the effect on 1/z
1619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (r_nearzionly)
1629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
1639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_emitted = 1;
1659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_ceilv1 = (int) ceil(r_v1);
1679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// create the edge
1709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (ceilv0 == r_ceilv1)
1719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
1729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// we cache unclipped horizontal edges as fully clipped
1739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (cacheoffset != 0x7FFFFFFF)
1749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
1759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			cacheoffset = FULLY_CLIPPED_CACHED |
1769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					(r_framecount & FRAMECOUNT_MASK);
1779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
1789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;		// horizontal edge
1809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
1819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	side = ceilv0 > r_ceilv1;
1839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	edge = edge_p++;
1859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	edge->owner = r_pedge;
1879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	edge->nearzi = lzi0;
1899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (side == 0)
1919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
1929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// trailing edge (go from p1 to p2)
1939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		v = ceilv0;
1949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		v2 = r_ceilv1 - 1;
1959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		edge->surfs[0] = surface_p - surfaces;
1979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		edge->surfs[1] = 0;
1989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		u_step = ((r_u1 - u0) / (r_v1 - v0));
2009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		u = u0 + ((float)v - v0) * u_step;
2019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
2029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	else
2039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
2049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// leading edge (go from p2 to p1)
2059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		v2 = ceilv0 - 1;
2069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		v = r_ceilv1;
2079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		edge->surfs[0] = 0;
2099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		edge->surfs[1] = surface_p - surfaces;
2109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		u_step = ((u0 - r_u1) / (v0 - r_v1));
2129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		u = r_u1 + ((float)v - r_v1) * u_step;
2139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
2149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	edge->u_step = u_step*0x100000;
2169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	edge->u = u*0x100000 + 0xFFFFF;
2179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// we need to do this to avoid stepping off the edges if a very nearly
2199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// horizontal edge is less than epsilon above a scan, and numeric error causes
2209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// it to incorrectly extend to the scan, and the extension of the line goes off
2219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// the edge of the screen
2229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: is this actually needed?
2239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (edge->u < r_refdef.vrect_x_adj_shift20)
2249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		edge->u = r_refdef.vrect_x_adj_shift20;
2259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (edge->u > r_refdef.vrectright_adj_shift20)
2269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		edge->u = r_refdef.vrectright_adj_shift20;
2279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//
2299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// sort the edge in normally
2309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//
2319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	u_check = edge->u;
2329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (edge->surfs[0])
2339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		u_check++;	// sort trailers after leaders
2349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (!newedges[v] || newedges[v]->u >= u_check)
2369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
2379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		edge->next = newedges[v];
2389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		newedges[v] = edge;
2399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
2409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	else
2419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
2429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		pcheck = newedges[v];
2439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		while (pcheck->next && pcheck->next->u < u_check)
2449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			pcheck = pcheck->next;
2459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		edge->next = pcheck->next;
2469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		pcheck->next = edge;
2479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
2489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	edge->nextremove = removeedges[v2];
2509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	removeedges[v2] = edge;
2519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
2529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
2559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
2569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_ClipEdge
2579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
2589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
2599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
2609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
2619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	float		d0, d1, f;
2629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	mvertex_t	clipvert;
2639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (clip)
2659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
2669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		do
2679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
2689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			d0 = DotProduct (pv0->position, clip->normal) - clip->dist;
2699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			d1 = DotProduct (pv1->position, clip->normal) - clip->dist;
2709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			if (d0 >= 0)
2729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			{
2739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			// point 0 is unclipped
2749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				if (d1 >= 0)
2759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				{
2769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				// both points are unclipped
2779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					continue;
2789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				}
2799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			// only point 1 is clipped
2819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			// we don't cache clipped edges
2839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				cacheoffset = 0x7FFFFFFF;
2849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				f = d0 / (d0 - d1);
2869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				clipvert.position[0] = pv0->position[0] +
2879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						f * (pv1->position[0] - pv0->position[0]);
2889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				clipvert.position[1] = pv0->position[1] +
2899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						f * (pv1->position[1] - pv0->position[1]);
2909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				clipvert.position[2] = pv0->position[2] +
2919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						f * (pv1->position[2] - pv0->position[2]);
2929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				if (clip->leftedge)
2949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				{
2959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					r_leftclipped = true;
2969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					r_leftexit = clipvert;
2979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				}
2989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				else if (clip->rightedge)
2999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				{
3009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					r_rightclipped = true;
3019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					r_rightexit = clipvert;
3029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				}
3039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				R_ClipEdge (pv0, &clipvert, clip->next);
3059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				return;
3069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			}
3079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			else
3089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			{
3099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			// point 0 is clipped
3109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				if (d1 < 0)
3119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				{
3129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				// both points are clipped
3139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				// we do cache fully clipped edges
3149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					if (!r_leftclipped)
3159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						cacheoffset = FULLY_CLIPPED_CACHED |
3169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream								(r_framecount & FRAMECOUNT_MASK);
3179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					return;
3189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				}
3199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			// only point 0 is clipped
3219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				r_lastvertvalid = false;
3229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			// we don't cache partially clipped edges
3249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				cacheoffset = 0x7FFFFFFF;
3259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				f = d0 / (d0 - d1);
3279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				clipvert.position[0] = pv0->position[0] +
3289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						f * (pv1->position[0] - pv0->position[0]);
3299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				clipvert.position[1] = pv0->position[1] +
3309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						f * (pv1->position[1] - pv0->position[1]);
3319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				clipvert.position[2] = pv0->position[2] +
3329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						f * (pv1->position[2] - pv0->position[2]);
3339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				if (clip->leftedge)
3359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				{
3369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					r_leftclipped = true;
3379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					r_leftenter = clipvert;
3389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				}
3399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				else if (clip->rightedge)
3409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				{
3419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					r_rightclipped = true;
3429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					r_rightenter = clipvert;
3439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				}
3449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				R_ClipEdge (&clipvert, pv1, clip->next);
3469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				return;
3479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			}
3489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		} while ((clip = clip->next) != NULL);
3499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
3509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// add the edge
3529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	R_EmitEdge (pv0, pv1);
3539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
3549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#endif	// !id386
3569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
3599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
3609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_EmitCachedEdge
3619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
3629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
3639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_EmitCachedEdge (void)
3649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
3659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	edge_t		*pedge_t;
3669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	pedge_t = (edge_t *)((unsigned long)r_edges + r_pedge->cachededgeoffset);
3689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (!pedge_t->surfs[0])
3709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		pedge_t->surfs[0] = surface_p - surfaces;
3719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	else
3729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		pedge_t->surfs[1] = surface_p - surfaces;
3739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (pedge_t->nearzi > r_nearzi)	// for mipmap finding
3759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_nearzi = pedge_t->nearzi;
3769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_emitted = 1;
3789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
3799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
3829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
3839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_RenderFace
3849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
3859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
3869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_RenderFace (msurface_t *fa, int clipflags)
3879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
3889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int			i, lindex;
3899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	unsigned	mask;
3909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	mplane_t	*pplane;
3919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	float		distinv;
3929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	vec3_t		p_normal;
3939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	medge_t		*pedges, tedge;
3949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	clipplane_t	*pclip;
3959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// skip out if no more surfs
3979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if ((surface_p) >= surf_max)
3989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
3999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_outofsurfaces++;
4009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
4019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
4029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// ditto if not enough edges left, or switch to auxedges if possible
4049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if ((edge_p + fa->numedges + 4) >= edge_max)
4059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
4069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_outofedges += fa->numedges;
4079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
4089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
4099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	c_faceclip++;
4119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// set up clip planes
4139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	pclip = NULL;
4149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1)
4169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
4179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (clipflags & mask)
4189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
4199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			view_clipplanes[i].next = pclip;
4209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			pclip = &view_clipplanes[i];
4219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
4229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
4239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// push the edges through
4259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_emitted = 0;
4269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_nearzi = 0;
4279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_nearzionly = false;
4289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	makeleftedge = makerightedge = false;
4299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	pedges = currententity->model->edges;
4309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_lastvertvalid = false;
4319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	for (i=0 ; i<fa->numedges ; i++)
4339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
4349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		lindex = currententity->model->surfedges[fa->firstedge + i];
4359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (lindex > 0)
4379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
4389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			r_pedge = &pedges[lindex];
4399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		// if the edge is cached, we can just reuse the edge
4419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			if (!insubmodel)
4429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			{
4439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED)
4449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				{
4459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) ==
4469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						r_framecount)
4479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					{
4489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						r_lastvertvalid = false;
4499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						continue;
4509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					}
4519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				}
4529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				else
4539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				{
4549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					if ((((unsigned long)edge_p - (unsigned long)r_edges) >
4559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						 r_pedge->cachededgeoffset) &&
4569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						(((edge_t *)((unsigned long)r_edges +
4579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						 r_pedge->cachededgeoffset))->owner == r_pedge))
4589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					{
4599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						R_EmitCachedEdge ();
4609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						r_lastvertvalid = false;
4619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						continue;
4629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					}
4639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				}
4649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			}
4659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		// assume it's cacheable
4679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			cacheoffset = (byte *)edge_p - (byte *)r_edges;
4689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			r_leftclipped = r_rightclipped = false;
4699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]],
4709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						&r_pcurrentvertbase[r_pedge->v[1]],
4719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						pclip);
4729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			r_pedge->cachededgeoffset = cacheoffset;
4739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			if (r_leftclipped)
4759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				makeleftedge = true;
4769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			if (r_rightclipped)
4779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				makerightedge = true;
4789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			r_lastvertvalid = true;
4799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
4809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		else
4819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
4829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			lindex = -lindex;
4839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			r_pedge = &pedges[lindex];
4849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		// if the edge is cached, we can just reuse the edge
4859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			if (!insubmodel)
4869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			{
4879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED)
4889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				{
4899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) ==
4909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						r_framecount)
4919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					{
4929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						r_lastvertvalid = false;
4939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						continue;
4949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					}
4959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				}
4969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				else
4979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				{
4989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				// it's cached if the cached edge is valid and is owned
4999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				// by this medge_t
5009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					if ((((unsigned long)edge_p - (unsigned long)r_edges) >
5019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						 r_pedge->cachededgeoffset) &&
5029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						(((edge_t *)((unsigned long)r_edges +
5039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						 r_pedge->cachededgeoffset))->owner == r_pedge))
5049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					{
5059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						R_EmitCachedEdge ();
5069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						r_lastvertvalid = false;
5079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						continue;
5089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					}
5099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				}
5109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			}
5119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		// assume it's cacheable
5139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			cacheoffset = (byte *)edge_p - (byte *)r_edges;
5149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			r_leftclipped = r_rightclipped = false;
5159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]],
5169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						&r_pcurrentvertbase[r_pedge->v[0]],
5179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						pclip);
5189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			r_pedge->cachededgeoffset = cacheoffset;
5199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			if (r_leftclipped)
5219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				makeleftedge = true;
5229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			if (r_rightclipped)
5239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				makerightedge = true;
5249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			r_lastvertvalid = true;
5259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
5269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
5279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// if there was a clip off the left edge, add that edge too
5299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: faster to do in screen space?
5309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: share clipped edges?
5319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (makeleftedge)
5329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
5339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_pedge = &tedge;
5349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_lastvertvalid = false;
5359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
5369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
5379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// if there was a clip off the right edge, get the right r_nearzi
5399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (makerightedge)
5409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
5419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_pedge = &tedge;
5429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_lastvertvalid = false;
5439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_nearzionly = true;
5449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
5459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
5469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// if no edges made it out, return without posting the surface
5489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (!r_emitted)
5499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
5509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_polycount++;
5529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->data = (void *)fa;
5549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->nearzi = r_nearzi;
5559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->flags = fa->flags;
5569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->insubmodel = insubmodel;
5579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->spanstate = 0;
5589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->entity = currententity;
5599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->key = r_currentkey++;
5609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->spans = NULL;
5619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	pplane = fa->plane;
5639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: cache this?
5649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	TransformVector (pplane->normal, p_normal);
5659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: cache this?
5669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal));
5679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv;
5699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv;
5709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->d_ziorigin = p_normal[2] * distinv -
5719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			xcenter * surface_p->d_zistepu -
5729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			ycenter * surface_p->d_zistepv;
5739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//JDC	VectorCopy (r_worldmodelorg, surface_p->modelorg);
5759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p++;
5769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
5779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
5809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
5819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_RenderBmodelFace
5829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
5839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
5849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf)
5859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
5869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int			i;
5879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	unsigned	mask;
5889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	mplane_t	*pplane;
5899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	float		distinv;
5909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	vec3_t		p_normal;
5919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	medge_t		tedge;
5929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	clipplane_t	*pclip;
5939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// skip out if no more surfs
5959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (surface_p >= surf_max)
5969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
5979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_outofsurfaces++;
5989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
5999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
6009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// ditto if not enough edges left, or switch to auxedges if possible
6029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if ((edge_p + psurf->numedges + 4) >= edge_max)
6039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
6049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_outofedges += psurf->numedges;
6059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
6069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
6079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	c_faceclip++;
6099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// this is a dummy to give the caching mechanism someplace to write to
6119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_pedge = &tedge;
6129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// set up clip planes
6149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	pclip = NULL;
6159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1)
6179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
6189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (r_clipflags & mask)
6199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
6209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			view_clipplanes[i].next = pclip;
6219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			pclip = &view_clipplanes[i];
6229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
6239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
6249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// push the edges through
6269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_emitted = 0;
6279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_nearzi = 0;
6289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_nearzionly = false;
6299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	makeleftedge = makerightedge = false;
6309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: keep clipped bmodel edges in clockwise order so last vertex caching
6319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// can be used?
6329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_lastvertvalid = false;
6339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	for ( ; pedges ; pedges = pedges->pnext)
6359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
6369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_leftclipped = r_rightclipped = false;
6379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		R_ClipEdge (pedges->v[0], pedges->v[1], pclip);
6389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (r_leftclipped)
6409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			makeleftedge = true;
6419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (r_rightclipped)
6429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			makerightedge = true;
6439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
6449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// if there was a clip off the left edge, add that edge too
6469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: faster to do in screen space?
6479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: share clipped edges?
6489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (makeleftedge)
6499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
6509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_pedge = &tedge;
6519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
6529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
6539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// if there was a clip off the right edge, get the right r_nearzi
6559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (makerightedge)
6569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
6579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_pedge = &tedge;
6589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		r_nearzionly = true;
6599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
6609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
6619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// if no edges made it out, return without posting the surface
6639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (!r_emitted)
6649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
6659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_polycount++;
6679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->data = (void *)psurf;
6699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->nearzi = r_nearzi;
6709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->flags = psurf->flags;
6719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->insubmodel = true;
6729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->spanstate = 0;
6739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->entity = currententity;
6749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->key = r_currentbkey;
6759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->spans = NULL;
6769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	pplane = psurf->plane;
6789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: cache this?
6799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	TransformVector (pplane->normal, p_normal);
6809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: cache this?
6819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal));
6829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv;
6849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv;
6859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p->d_ziorigin = p_normal[2] * distinv -
6869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			xcenter * surface_p->d_zistepu -
6879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			ycenter * surface_p->d_zistepv;
6889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//JDC	VectorCopy (r_worldmodelorg, surface_p->modelorg);
6909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	surface_p++;
6919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
6929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
6949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
6959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
6969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_RenderPoly
6979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
6989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
6999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_RenderPoly (msurface_t *fa, int clipflags)
7009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
7019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int			i, lindex, lnumverts, s_axis, t_axis;
7029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	float		dist, lastdist, lzi, scale, u, v, frac;
7039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	unsigned	mask;
7049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	vec3_t		local, transformed;
7059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	clipplane_t	*pclip;
7069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	medge_t		*pedges;
7079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	mplane_t	*pplane;
7089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	mvertex_t	verts[2][100];	//FIXME: do real number
7099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	polyvert_t	pverts[100];	//FIXME: do real number, safely
7109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int			vertpage, newverts, newpage, lastvert;
7119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	qboolean	visible;
7129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: clean this up and make it faster
7149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: guard against running out of vertices
7159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	s_axis = t_axis = 0;	// keep compiler happy
7179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// set up clip planes
7199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	pclip = NULL;
7209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1)
7229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
7239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (clipflags & mask)
7249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
7259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			view_clipplanes[i].next = pclip;
7269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			pclip = &view_clipplanes[i];
7279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
7289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
7299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// reconstruct the polygon
7319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// FIXME: these should be precalculated and loaded off disk
7329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	pedges = currententity->model->edges;
7339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	lnumverts = fa->numedges;
7349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	vertpage = 0;
7359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	for (i=0 ; i<lnumverts ; i++)
7379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
7389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		lindex = currententity->model->surfedges[fa->firstedge + i];
7399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (lindex > 0)
7419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
7429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			r_pedge = &pedges[lindex];
7439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			verts[0][i] = r_pcurrentvertbase[r_pedge->v[0]];
7449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
7459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		else
7469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
7479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			r_pedge = &pedges[-lindex];
7489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			verts[0][i] = r_pcurrentvertbase[r_pedge->v[1]];
7499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
7509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
7519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// clip the polygon, done if not visible
7539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	while (pclip)
7549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
7559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		lastvert = lnumverts - 1;
7569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		lastdist = DotProduct (verts[vertpage][lastvert].position,
7579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream							   pclip->normal) - pclip->dist;
7589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		visible = false;
7609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		newverts = 0;
7619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		newpage = vertpage ^ 1;
7629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		for (i=0 ; i<lnumverts ; i++)
7649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
7659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			dist = DotProduct (verts[vertpage][i].position, pclip->normal) -
7669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream					pclip->dist;
7679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			if ((lastdist > 0) != (dist > 0))
7699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			{
7709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				frac = dist / (dist - lastdist);
7719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				verts[newpage][newverts].position[0] =
7729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						verts[vertpage][i].position[0] +
7739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						((verts[vertpage][lastvert].position[0] -
7749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						  verts[vertpage][i].position[0]) * frac);
7759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				verts[newpage][newverts].position[1] =
7769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						verts[vertpage][i].position[1] +
7779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						((verts[vertpage][lastvert].position[1] -
7789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						  verts[vertpage][i].position[1]) * frac);
7799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				verts[newpage][newverts].position[2] =
7809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						verts[vertpage][i].position[2] +
7819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						((verts[vertpage][lastvert].position[2] -
7829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream						  verts[vertpage][i].position[2]) * frac);
7839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				newverts++;
7849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			}
7859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			if (dist >= 0)
7879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			{
7889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				verts[newpage][newverts] = verts[vertpage][i];
7899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				newverts++;
7909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream				visible = true;
7919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			}
7929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			lastvert = i;
7949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			lastdist = dist;
7959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
7969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
7979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (!visible || (newverts < 3))
7989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			return;
7999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		lnumverts = newverts;
8019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		vertpage ^= 1;
8029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		pclip = pclip->next;
8039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
8049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// transform and project, remembering the z values at the vertices and
8069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// r_nearzi, and extract the s and t coordinates at the vertices
8079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	pplane = fa->plane;
8089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	switch (pplane->type)
8099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
8109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	case PLANE_X:
8119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	case PLANE_ANYX:
8129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		s_axis = 1;
8139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		t_axis = 2;
8149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		break;
8159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	case PLANE_Y:
8169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	case PLANE_ANYY:
8179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		s_axis = 0;
8189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		t_axis = 2;
8199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		break;
8209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	case PLANE_Z:
8219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	case PLANE_ANYZ:
8229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		s_axis = 0;
8239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		t_axis = 1;
8249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		break;
8259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
8269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_nearzi = 0;
8289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	for (i=0 ; i<lnumverts ; i++)
8309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
8319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// transform and project
8329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		VectorSubtract (verts[vertpage][i].position, modelorg, local);
8339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		TransformVector (local, transformed);
8349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (transformed[2] < NEAR_CLIP)
8369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			transformed[2] = NEAR_CLIP;
8379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		lzi = 1.0 / transformed[2];
8399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (lzi > r_nearzi)	// for mipmap finding
8419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			r_nearzi = lzi;
8429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// FIXME: build x/yscale into transform?
8449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		scale = xscale * lzi;
8459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		u = (xcenter + scale*transformed[0]);
8469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (u < r_refdef.fvrectx_adj)
8479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			u = r_refdef.fvrectx_adj;
8489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (u > r_refdef.fvrectright_adj)
8499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			u = r_refdef.fvrectright_adj;
8509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		scale = yscale * lzi;
8529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		v = (ycenter - scale*transformed[1]);
8539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (v < r_refdef.fvrecty_adj)
8549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			v = r_refdef.fvrecty_adj;
8559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (v > r_refdef.fvrectbottom_adj)
8569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			v = r_refdef.fvrectbottom_adj;
8579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		pverts[i].u = u;
8599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		pverts[i].v = v;
8609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		pverts[i].zi = lzi;
8619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		pverts[i].s = verts[vertpage][i].position[s_axis];
8629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		pverts[i].t = verts[vertpage][i].position[t_axis];
8639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
8649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// build the polygon descriptor, including fa, r_nearzi, and u, v, s, t, and z
8669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// for each vertex
8679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_polydesc.numverts = lnumverts;
8689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_polydesc.nearzi = r_nearzi;
8699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_polydesc.pcurrentface = fa;
8709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	r_polydesc.pverts = pverts;
8719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// draw the polygon
8739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	D_DrawPoly ();
8749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
8759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
8789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
8799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamR_ZDrawSubmodelPolys
8809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream================
8819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
8829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid R_ZDrawSubmodelPolys (model_t *pmodel)
8839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
8849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int			i, numsurfaces;
8859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	msurface_t	*psurf;
8869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	float		dot;
8879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	mplane_t	*pplane;
8889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
8909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	numsurfaces = pmodel->nummodelsurfaces;
8919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	for (i=0 ; i<numsurfaces ; i++, psurf++)
8939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
8949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// find which side of the node we are on
8959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		pplane = psurf->plane;
8969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
8989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
8999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// draw the polygon
9009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
9019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
9029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
9039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		// FIXME: use bounding-box-based frustum clipping info?
9049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			R_RenderPoly (psurf, 15);
9059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
9069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
9079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
9089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
909