1004 lines · 22.1 KB · C
RawDownload
// d_polyset.c: routines for drawing sets of polygons sharing the same// texture (used for Alias models) #include <math.h>#include "quakedef.h"#include "r_shared.h"#include "d_local.h" // TODO: put in span spilling to shrink list size#define DPS_MAXSPANS MAXHEIGHT+1									// 1 extra for spanpackage that marks end typedef struct {	void *pdest;	short *pz;	int count;	uint8_t *ptex;	int sfrac, tfrac, light, zi;} spanpackage_t; typedef struct {	int isflattop;	int numleftedges;	int *pleftedgevert0;	int *pleftedgevert1;	int *pleftedgevert2;	int numrightedges;	int *prightedgevert0;	int *prightedgevert1;	int *prightedgevert2;} edgetable; int r_p0[6], r_p1[6], r_p2[6]; uint8_t *d_pcolormap; int d_aflatcolor;int d_xdenom; edgetable *pedgetable; edgetable edgetables[12] = {	{0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 },	{0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL},	{1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL},	{0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 },	{0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL},	{0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL},	{0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 },	{0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL},	{0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL},	{1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL},	{1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL},	{0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL},}; // FIXME: some of these can become staticsint a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;int r_zistepx, r_zistepy;int d_aspancount, d_countextrastep; spanpackage_t *a_spans;spanpackage_t *d_pedgespanpackage;static int ystart;uint8_t *d_pdest, *d_ptex;short *d_pz;int d_sfrac, d_tfrac, d_light, d_zi;int d_ptexextrastep, d_sfracextrastep;int d_tfracextrastep, d_lightextrastep, d_pdestextrastep;int d_lightbasestep, d_pdestbasestep, d_ptexbasestep;int d_sfracbasestep, d_tfracbasestep;int d_ziextrastep, d_zibasestep;int d_pzextrastep, d_pzbasestep; typedef struct {	int quotient;	int remainder;} adivtab_t; static adivtab_t adivtab[32*32] = {#include "adivtab.h"}; uint8_t *skintable[MAX_LBM_HEIGHT];int skinwidth;uint8_t *skinstart; void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage);void D_PolysetCalcGradients (int skinwidth);void D_DrawSubdiv (void);void D_DrawNonSubdiv (void);void D_PolysetRecursiveTriangle (int *p1, int *p2, int *p3);void D_PolysetSetEdgeTable (void);void D_RasterizeAliasPolySmooth (void);void D_PolysetScanLeftEdge (int height); /*================D_PolysetDraw================*/void D_PolysetDraw (void){	spanpackage_t spans[DPS_MAXSPANS + 1 +			((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1];						// one extra because of cache line pretouching 	a_spans = (spanpackage_t *)			(((long)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); 	if (r_affinetridesc.drawtype)	{		D_DrawSubdiv ();	}	else	{		D_DrawNonSubdiv ();	}} /*================D_PolysetDrawFinalVerts================*/void D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts){	int i, z;	short *zbuf; 	for (i=0 ; i<numverts ; i++, fv++)	{	// valid triangle coordinates for filling can include the bottom and	// right clip edges, due to the fill rule; these shouldn't be drawn		if ((fv->v[0] < r_refdef.vrectright) &&			(fv->v[1] < r_refdef.vrectbottom))		{			z = fv->v[5]>>16;			zbuf = zspantable[fv->v[1]] + fv->v[0];			if (z >= *zbuf)			{				int pix; 				*zbuf = z;				pix = skintable[fv->v[3]>>16][fv->v[2]>>16];				pix = ((uint8_t *)acolormap)[pix + (fv->v[4] & 0xFF00) ];				d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = pix;			}		}	}} /*================D_DrawSubdiv================*/void D_DrawSubdiv (void){	mtriangle_t *ptri;	finalvert_t *pfv, *index0, *index1, *index2;	int i;	int lnumtriangles; 	pfv = r_affinetridesc.pfinalverts;	ptri = r_affinetridesc.ptriangles;	lnumtriangles = r_affinetridesc.numtriangles; 	for (i=0 ; i<lnumtriangles ; i++)	{		index0 = pfv + ptri[i].vertindex[0];		index1 = pfv + ptri[i].vertindex[1];		index2 = pfv + ptri[i].vertindex[2]; 		if (((index0->v[1]-index1->v[1]) *			 (index0->v[0]-index2->v[0]) -			 (index0->v[0]-index1->v[0]) *			 (index0->v[1]-index2->v[1])) >= 0)		{			continue;		} 		d_pcolormap = &((uint8_t *)acolormap)[index0->v[4] & 0xFF00]; 		if (ptri[i].facesfront)		{			D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v);		}		else		{			int s0, s1, s2; 			s0 = index0->v[2];			s1 = index1->v[2];			s2 = index2->v[2]; 			if (index0->flags & ALIAS_ONSEAM)				index0->v[2] += r_affinetridesc.seamfixupX16;			if (index1->flags & ALIAS_ONSEAM)				index1->v[2] += r_affinetridesc.seamfixupX16;			if (index2->flags & ALIAS_ONSEAM)				index2->v[2] += r_affinetridesc.seamfixupX16; 			D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); 			index0->v[2] = s0;			index1->v[2] = s1;			index2->v[2] = s2;		}	}} /*================D_DrawNonSubdiv================*/void D_DrawNonSubdiv (void){	mtriangle_t *ptri;	finalvert_t *pfv, *index0, *index1, *index2;	int i;	int lnumtriangles; 	pfv = r_affinetridesc.pfinalverts;	ptri = r_affinetridesc.ptriangles;	lnumtriangles = r_affinetridesc.numtriangles; 	for (i=0 ; i<lnumtriangles ; i++, ptri++)	{		index0 = pfv + ptri->vertindex[0];		index1 = pfv + ptri->vertindex[1];		index2 = pfv + ptri->vertindex[2]; 		d_xdenom = (index0->v[1]-index1->v[1]) *				(index0->v[0]-index2->v[0]) -				(index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]); 		if (d_xdenom >= 0)		{			continue;		} 		r_p0[0] = index0->v[0]; // u		r_p0[1] = index0->v[1]; // v		r_p0[2] = index0->v[2]; // s		r_p0[3] = index0->v[3]; // t		r_p0[4] = index0->v[4]; // light		r_p0[5] = index0->v[5]; // iz 		r_p1[0] = index1->v[0];		r_p1[1] = index1->v[1];		r_p1[2] = index1->v[2];		r_p1[3] = index1->v[3];		r_p1[4] = index1->v[4];		r_p1[5] = index1->v[5]; 		r_p2[0] = index2->v[0];		r_p2[1] = index2->v[1];		r_p2[2] = index2->v[2];		r_p2[3] = index2->v[3];		r_p2[4] = index2->v[4];		r_p2[5] = index2->v[5]; 		if (!ptri->facesfront)		{			if (index0->flags & ALIAS_ONSEAM)				r_p0[2] += r_affinetridesc.seamfixupX16;			if (index1->flags & ALIAS_ONSEAM)				r_p1[2] += r_affinetridesc.seamfixupX16;			if (index2->flags & ALIAS_ONSEAM)				r_p2[2] += r_affinetridesc.seamfixupX16;		} 		D_PolysetSetEdgeTable ();		D_RasterizeAliasPolySmooth ();	}} /*================D_PolysetRecursiveTriangle================*/void D_PolysetRecursiveTriangle (int *lp1, int *lp2, int *lp3){	int *temp;	int d;	int new[6];	int z;	short *zbuf; 	d = lp2[0] - lp1[0];	if (d < -1 || d > 1)		goto split;	d = lp2[1] - lp1[1];	if (d < -1 || d > 1)		goto split; 	d = lp3[0] - lp2[0];	if (d < -1 || d > 1)		goto split2;	d = lp3[1] - lp2[1];	if (d < -1 || d > 1)		goto split2; 	d = lp1[0] - lp3[0];	if (d < -1 || d > 1)		goto split3;	d = lp1[1] - lp3[1];	if (d < -1 || d > 1)	{split3:		temp = lp1;		lp1 = lp3;		lp3 = lp2;		lp2 = temp; 		goto split;	} 	return; // entire tri is filled split2:	temp = lp1;	lp1 = lp2;	lp2 = lp3;	lp3 = temp; split:// split this edge	new[0] = (lp1[0] + lp2[0]) >> 1;	new[1] = (lp1[1] + lp2[1]) >> 1;	new[2] = (lp1[2] + lp2[2]) >> 1;	new[3] = (lp1[3] + lp2[3]) >> 1;	new[5] = (lp1[5] + lp2[5]) >> 1; // draw the point if splitting a leading edge	if (lp2[1] > lp1[1])		goto nodraw;	if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0]))		goto nodraw; 	z = new[5]>>16;	zbuf = zspantable[new[1]] + new[0];	if (z >= *zbuf)	{		int pix; 		*zbuf = z;		pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]];		d_viewbuffer[d_scantable[new[1]] + new[0]] = pix;	} nodraw:// recursively continue	D_PolysetRecursiveTriangle (lp3, lp1, new);	D_PolysetRecursiveTriangle (lp3, new, lp2);} /*================D_PolysetUpdateTables================*/void D_PolysetUpdateTables (void){	int i;	uint8_t *s; 	if (r_affinetridesc.skinwidth != skinwidth ||		r_affinetridesc.pskin != skinstart)	{		skinwidth = r_affinetridesc.skinwidth;		skinstart = r_affinetridesc.pskin;		s = skinstart;		for (i=0 ; i<MAX_LBM_HEIGHT ; i++, s+=skinwidth)			skintable[i] = s;	}} /*===================D_PolysetScanLeftEdge====================*/void D_PolysetScanLeftEdge (int height){ 	do	{		d_pedgespanpackage->pdest = d_pdest;		d_pedgespanpackage->pz = d_pz;		d_pedgespanpackage->count = d_aspancount;		d_pedgespanpackage->ptex = d_ptex; 		d_pedgespanpackage->sfrac = d_sfrac;		d_pedgespanpackage->tfrac = d_tfrac; 	// FIXME: need to clamp l, s, t, at both ends?		d_pedgespanpackage->light = d_light;		d_pedgespanpackage->zi = d_zi; 		d_pedgespanpackage++; 		errorterm += erroradjustup;		if (errorterm >= 0)		{			d_pdest += d_pdestextrastep;			d_pz += d_pzextrastep;			d_aspancount += d_countextrastep;			d_ptex += d_ptexextrastep;			d_sfrac += d_sfracextrastep;			d_ptex += d_sfrac >> 16; 			d_sfrac &= 0xFFFF;			d_tfrac += d_tfracextrastep;			if (d_tfrac & 0x10000)			{				d_ptex += r_affinetridesc.skinwidth;				d_tfrac &= 0xFFFF;			}			d_light += d_lightextrastep;			d_zi += d_ziextrastep;			errorterm -= erroradjustdown;		}		else		{			d_pdest += d_pdestbasestep;			d_pz += d_pzbasestep;			d_aspancount += ubasestep;			d_ptex += d_ptexbasestep;			d_sfrac += d_sfracbasestep;			d_ptex += d_sfrac >> 16;			d_sfrac &= 0xFFFF;			d_tfrac += d_tfracbasestep;			if (d_tfrac & 0x10000)			{				d_ptex += r_affinetridesc.skinwidth;				d_tfrac &= 0xFFFF;			}			d_light += d_lightbasestep;			d_zi += d_zibasestep;		}	} while (--height);} /*===================D_PolysetSetUpForLineScan====================*/void D_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,		fixed8_t endvertu, fixed8_t endvertv){	double dm, dn;	int tm, tn;	adivtab_t *ptemp; // TODO: implement x86 version 	errorterm = -1; 	tm = endvertu - startvertu;	tn = endvertv - startvertv; 	if (((tm <= 16) && (tm >= -15)) &&		((tn <= 16) && (tn >= -15)))	{		ptemp = &adivtab[((tm+15) << 5) + (tn+15)];		ubasestep = ptemp->quotient;		erroradjustup = ptemp->remainder;		erroradjustdown = tn;	}	else	{		dm = (double)tm;		dn = (double)tn; 		FloorDivMod (dm, dn, &ubasestep, &erroradjustup); 		erroradjustdown = dn;	}} /*================D_PolysetCalcGradients================*/void D_PolysetCalcGradients (int skinwidth){	float xstepdenominv, ystepdenominv, t0, t1;	float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20; 	p00_minus_p20 = r_p0[0] - r_p2[0];	p01_minus_p21 = r_p0[1] - r_p2[1];	p10_minus_p20 = r_p1[0] - r_p2[0];	p11_minus_p21 = r_p1[1] - r_p2[1];

Lines 1–500 of 1004.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t