diff options
Diffstat (limited to 'code/renderer/tr_shade.c')
| -rw-r--r-- | code/renderer/tr_shade.c | 193 | 
1 files changed, 160 insertions, 33 deletions
| diff --git a/code/renderer/tr_shade.c b/code/renderer/tr_shade.c index 838e25d..043bd90 100644 --- a/code/renderer/tr_shade.c +++ b/code/renderer/tr_shade.c @@ -402,9 +402,9 @@ ProjectDlightTexture  Perform dynamic lighting with another rendering pass  ===================  */ -static void ProjectDlightTexture( void ) { -	int		i, l;  #if idppc_altivec +static void ProjectDlightTexture_altivec( void ) { +	int		i, l;  	vec_t	origin0, origin1, origin2;  	float   texCoords0, texCoords1;  	vector float floatColorVec0, floatColorVec1; @@ -412,13 +412,10 @@ static void ProjectDlightTexture( void ) {  	vector short colorShort;  	vector signed int colorInt;  	vector unsigned char floatColorVecPerm, modulatePerm, colorChar; -	vector unsigned char vSel = (vector unsigned char){0x00, 0x00, 0x00, 0xff, -							   0x00, 0x00, 0x00, 0xff, -							   0x00, 0x00, 0x00, 0xff, -							   0x00, 0x00, 0x00, 0xff}; -#else -	vec3_t	origin; -#endif +	vector unsigned char vSel = VECCONST_UINT8(0x00, 0x00, 0x00, 0xff, +                                               0x00, 0x00, 0x00, 0xff, +                                               0x00, 0x00, 0x00, 0xff, +                                               0x00, 0x00, 0x00, 0xff);  	float	*texCoords;  	byte	*colors;  	byte	clipBits[SHADER_MAX_VERTEXES]; @@ -429,20 +426,18 @@ static void ProjectDlightTexture( void ) {  	float	scale;  	float	radius;  	vec3_t	floatColor; -	float	modulate; +	float	modulate = 0.0f;  	if ( !backEnd.refdef.num_dlights ) {  		return;  	} -#if idppc_altivec -	// There has to be a better way to do this so that floatColor  +	// There has to be a better way to do this so that floatColor  	// and/or modulate are already 16-byte aligned.  	floatColorVecPerm = vec_lvsl(0,(float *)floatColor);  	modulatePerm = vec_lvsl(0,(float *)&modulate);  	modulatePerm = (vector unsigned char)vec_splat((vector unsigned int)modulatePerm,0);  	zero = (vector float)vec_splat_s8(0); -#endif  	for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) {  		dlight_t	*dl; @@ -454,27 +449,20 @@ static void ProjectDlightTexture( void ) {  		colors = colorArray[0];  		dl = &backEnd.refdef.dlights[l]; -#if idppc_altivec  		origin0 = dl->transformed[0];  		origin1 = dl->transformed[1];  		origin2 = dl->transformed[2]; -#else -		VectorCopy( dl->transformed, origin ); -#endif  		radius = dl->radius;  		scale = 1.0f / radius;  		floatColor[0] = dl->color[0] * 255.0f;  		floatColor[1] = dl->color[1] * 255.0f;  		floatColor[2] = dl->color[2] * 255.0f; -#if idppc_altivec  		floatColorVec0 = vec_ld(0, floatColor);  		floatColorVec1 = vec_ld(11, floatColor);  		floatColorVec0 = vec_perm(floatColorVec0,floatColorVec0,floatColorVecPerm); -#endif  		for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) {  			int		clip = 0; -#if idppc_altivec  #define DIST0 dist0  #define DIST1 dist1  #define DIST2 dist2 @@ -485,16 +473,6 @@ static void ProjectDlightTexture( void ) {  			dist0 = origin0 - tess.xyz[i][0];  			dist1 = origin1 - tess.xyz[i][1];  			dist2 = origin2 - tess.xyz[i][2]; -#else -#define DIST0 dist[0] -#define DIST1 dist[1] -#define DIST2 dist[2] -#define TEXCOORDS0 texCoords[0] -#define TEXCOORDS1 texCoords[1] -			vec3_t	dist; -			 -			VectorSubtract( origin, tess.xyz[i], dist ); -#endif  			backEnd.pc.c_dlightVertexes++; @@ -539,7 +517,6 @@ static void ProjectDlightTexture( void ) {  			}  			clipBits[i] = clip; -#if idppc_altivec  			modulateVec = vec_ld(0,(float *)&modulate);  			modulateVec = vec_perm(modulateVec,modulateVec,modulatePerm);  			colorVec = vec_madd(floatColorVec0,modulateVec,zero); @@ -548,12 +525,150 @@ static void ProjectDlightTexture( void ) {  			colorChar = vec_packsu(colorShort,colorShort);	// RGBxRGBxRGBxRGBx  			colorChar = vec_sel(colorChar,vSel,vSel);		// RGBARGBARGBARGBA replace alpha with 255  			vec_ste((vector unsigned int)colorChar,0,(unsigned int *)colors);	// store color -#else +		} +#undef DIST0 +#undef DIST1 +#undef DIST2 +#undef TEXCOORDS0 +#undef TEXCOORDS1 + +		// build a list of triangles that need light +		numIndexes = 0; +		for ( i = 0 ; i < tess.numIndexes ; i += 3 ) { +			int		a, b, c; + +			a = tess.indexes[i]; +			b = tess.indexes[i+1]; +			c = tess.indexes[i+2]; +			if ( clipBits[a] & clipBits[b] & clipBits[c] ) { +				continue;	// not lighted +			} +			hitIndexes[numIndexes] = a; +			hitIndexes[numIndexes+1] = b; +			hitIndexes[numIndexes+2] = c; +			numIndexes += 3; +		} + +		if ( !numIndexes ) { +			continue; +		} + +		qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); +		qglTexCoordPointer( 2, GL_FLOAT, 0, texCoordsArray[0] ); + +		qglEnableClientState( GL_COLOR_ARRAY ); +		qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, colorArray ); + +		GL_Bind( tr.dlightImage ); +		// include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light +		// where they aren't rendered +		if ( dl->additive ) { +			GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); +		} +		else { +			GL_State( GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL ); +		} +		R_DrawElements( numIndexes, hitIndexes ); +		backEnd.pc.c_totalIndexes += numIndexes; +		backEnd.pc.c_dlightIndexes += numIndexes; +	} +} +#endif + + +static void ProjectDlightTexture_scalar( void ) { +	int		i, l; +	vec3_t	origin; +	float	*texCoords; +	byte	*colors; +	byte	clipBits[SHADER_MAX_VERTEXES]; +	float	texCoordsArray[SHADER_MAX_VERTEXES][2]; +	byte	colorArray[SHADER_MAX_VERTEXES][4]; +	unsigned	hitIndexes[SHADER_MAX_INDEXES]; +	int		numIndexes; +	float	scale; +	float	radius; +	vec3_t	floatColor; +	float	modulate = 0.0f; + +	if ( !backEnd.refdef.num_dlights ) { +		return; +	} + +	for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) { +		dlight_t	*dl; + +		if ( !( tess.dlightBits & ( 1 << l ) ) ) { +			continue;	// this surface definately doesn't have any of this light +		} +		texCoords = texCoordsArray[0]; +		colors = colorArray[0]; + +		dl = &backEnd.refdef.dlights[l]; +		VectorCopy( dl->transformed, origin ); +		radius = dl->radius; +		scale = 1.0f / radius; + +		floatColor[0] = dl->color[0] * 255.0f; +		floatColor[1] = dl->color[1] * 255.0f; +		floatColor[2] = dl->color[2] * 255.0f; +		for ( i = 0 ; i < tess.numVertexes ; i++, texCoords += 2, colors += 4 ) { +			int		clip = 0; +#define DIST0 dist[0] +#define DIST1 dist[1] +#define DIST2 dist[2] +#define TEXCOORDS0 texCoords[0] +#define TEXCOORDS1 texCoords[1] +			vec3_t	dist; +			 +			VectorSubtract( origin, tess.xyz[i], dist ); + +			backEnd.pc.c_dlightVertexes++; + +			TEXCOORDS0 = 0.5f + DIST0 * scale; +			TEXCOORDS1 = 0.5f + DIST1 * scale; + +			if( !r_dlightBacks->integer && +					// dist . tess.normal[i] +					( DIST0 * tess.normal[i][0] + +					DIST1 * tess.normal[i][1] + +					DIST2 * tess.normal[i][2] ) < 0.0f ) { +				clip = 63; +			} else { +				if ( TEXCOORDS0 < 0.0f ) { +					clip |= 1; +				} else if ( TEXCOORDS0 > 1.0f ) { +					clip |= 2; +				} +				if ( TEXCOORDS1 < 0.0f ) { +					clip |= 4; +				} else if ( TEXCOORDS1 > 1.0f ) { +					clip |= 8; +				} +				texCoords[0] = TEXCOORDS0; +				texCoords[1] = TEXCOORDS1; + +				// modulate the strength based on the height and color +				if ( DIST2 > radius ) { +					clip |= 16; +					modulate = 0.0f; +				} else if ( DIST2 < -radius ) { +					clip |= 32; +					modulate = 0.0f; +				} else { +					DIST2 = Q_fabs(DIST2); +					if ( DIST2 < radius * 0.5f ) { +						modulate = 1.0f; +					} else { +						modulate = 2.0f * (radius - DIST2) * scale; +					} +				} +			} +			clipBits[i] = clip;  			colors[0] = myftol(floatColor[0] * modulate);  			colors[1] = myftol(floatColor[1] * modulate);  			colors[2] = myftol(floatColor[2] * modulate);  			colors[3] = 255; -#endif  		}  #undef DIST0  #undef DIST1 @@ -603,6 +718,18 @@ static void ProjectDlightTexture( void ) {  	}  } +static void ProjectDlightTexture( void ) { +    #if idppc_altivec +    extern cvar_t *com_altivec; +    if (com_altivec->integer) { +        // must be in a seperate function or G3 systems will crash. +        ProjectDlightTexture_altivec(); +        return; +    } +    #endif +    ProjectDlightTexture_scalar(); +} +  /*  =================== | 
