Пример #1
0
/*
=====================
RE_AddLightToScene

=====================
*/
void RE_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b, int overdraw ) {
	dlight_t    *dl;

	if ( !tr.registered ) {
		return;
	}
	if ( r_numdlights >= MAX_DLIGHTS ) {
		return;
	}
	if ( intensity <= 0 ) {
		return;
	}
	// these cards don't have the correct blend mode
	if ( glConfig.hardwareType == GLHW_RIVA128 || glConfig.hardwareType == GLHW_PERMEDIA2 ) {
		return;
	}
	// RF, allow us to force some dlights under all circumstances
	if ( !( overdraw & REF_FORCE_DLIGHT ) ) {
		if ( r_dynamiclight->integer == 0 ) {
			return;
		}
		if ( r_dynamiclight->integer == 2 && !( backEndData[tr.smpFrame]->dlights[r_numdlights].forced ) ) {
			return;
		}
	}

	overdraw &= ~REF_FORCE_DLIGHT;
	overdraw &= ~REF_JUNIOR_DLIGHT; //----(SA)	added

	dl = &backEndData[tr.smpFrame]->dlights[r_numdlights++];
	VectorCopy( org, dl->origin );
	dl->radius = intensity;
	dl->color[0] = r;
	dl->color[1] = g;
	dl->color[2] = b;
	dl->dlshader = NULL;
	dl->overdraw = 0;

	if ( overdraw == 10 ) { // sorry, hijacking 10 for a quick hack (SA)
		dl->dlshader = R_GetShaderByHandle( RE_RegisterShader( "negdlightshader" ) );
	} else if ( overdraw == 11 ) { // 11 is flames
		dl->dlshader = R_GetShaderByHandle( RE_RegisterShader( "flamedlightshader" ) );
	} else {
		dl->overdraw = overdraw;
	}
}
Пример #2
0
qhandle_t R_GetShaderByNum(int shaderNum, world_t &worldData)
{
	qhandle_t	shader;

	if ( (shaderNum < 0) || (shaderNum >= worldData.numShaders) ) 
	{
		Com_Printf( "Warning: Bad index for R_GetShaderByNum - %i", shaderNum );
		return(0);
	}
	shader = RE_RegisterShader(worldData.shaders[ shaderNum ].shader);
	return(shader);
}
Пример #3
0
void R_SetupEntityLightingGrid( trRefEntity_t *ent ) {
#else
static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) {
#endif
	vec3_t			lightOrigin;
	int				pos[3];
	int				i, j;
	float			frac[3];
	int				gridStep[3];
	vec3_t			direction;
	float			totalFactor;
	unsigned short	*startGridPos;
	
	if (r_fullbright->integer || (tr.refdef.rdflags & RDF_doLAGoggles) )
	{
		ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[2] = 255.0;
		ent->directedLight[0] = ent->directedLight[1] = ent->directedLight[2] = 255.0;
		VectorCopy( tr.sunDirection, ent->lightDir );
		return;
	}

	if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) {
		// seperate lightOrigins are needed so an object that is
		// sinking into the ground can still be lit, and so
		// multi-part models can be lit identically
		VectorCopy( ent->e.lightingOrigin, lightOrigin );
	} else {
		VectorCopy( ent->e.origin, lightOrigin );
	}
#define ACCURATE_LIGHTGRID_SAMPLING 1
#if ACCURATE_LIGHTGRID_SAMPLING
	vec3_t	startLightOrigin;
	VectorCopy( lightOrigin, startLightOrigin );
#endif

	VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin );
	for ( i = 0 ; i < 3 ; i++ ) {
		float	v;

		v = lightOrigin[i]*tr.world->lightGridInverseSize[i];
		pos[i] = floor( v );
		frac[i] = v - pos[i];
		if ( pos[i] < 0 ) {
			pos[i] = 0;
		} else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) {
			pos[i] = tr.world->lightGridBounds[i] - 1;
		}
	}

	VectorClear( ent->ambientLight );
	VectorClear( ent->directedLight );
	VectorClear( direction );

	// trilerp the light value
	gridStep[0] = 1;
	gridStep[1] = tr.world->lightGridBounds[0];
	gridStep[2] = tr.world->lightGridBounds[0] * tr.world->lightGridBounds[1];
	startGridPos = tr.world->lightGridArray	+ pos[0] * gridStep[0] 
					+ pos[1] * gridStep[1] 	+ pos[2] * gridStep[2];
#if ACCURATE_LIGHTGRID_SAMPLING
	vec3_t	startGridOrg;
	VectorCopy( tr.world->lightGridOrigin, startGridOrg );
	startGridOrg[0] += pos[0] * tr.world->lightGridSize[0];
	startGridOrg[1] += pos[1] * tr.world->lightGridSize[1];
	startGridOrg[2] += pos[2] * tr.world->lightGridSize[2];
#endif
	totalFactor = 0;
	for ( i = 0 ; i < 8 ; i++ ) {
		float			factor;
		mgrid_t			*data;
		unsigned short	*gridPos;
		int				lat, lng;
		vec3_t			normal;
#if ACCURATE_LIGHTGRID_SAMPLING
		vec3_t			gridOrg;
		VectorCopy( startGridOrg, gridOrg );
#endif

		factor = 1.0;
		gridPos = startGridPos;
		for ( j = 0 ; j < 3 ; j++ ) {
			if ( i & (1<<j) ) {
				factor *= frac[j];
				gridPos += gridStep[j];
#if ACCURATE_LIGHTGRID_SAMPLING
				gridOrg[j] += tr.world->lightGridSize[j];
#endif
			} else {
				factor *= (1.0 - frac[j]);
			}
		}

		if (gridPos >= tr.world->lightGridArray + tr.world->numGridArrayElements)
		{//we've gone off the array somehow
			continue;
		}
		data = tr.world->lightGridData + *gridPos;

		if ( data->styles[0] == LS_NONE ) 
		{
			continue;	// ignore samples in walls
		}

#if 0
		if ( !SV_inPVS( startLightOrigin, gridOrg ) )
		{
			continue;
		}
#endif

		totalFactor += factor;

		for(j=0;j<MAXLIGHTMAPS;j++)
		{
			if (data->styles[j] != LS_NONE)
			{
				const byte	style= data->styles[j];

				ent->ambientLight[0] += factor * data->ambientLight[j][0] * styleColors[style][0] / 255.0f;
				ent->ambientLight[1] += factor * data->ambientLight[j][1] * styleColors[style][1] / 255.0f;
				ent->ambientLight[2] += factor * data->ambientLight[j][2] * styleColors[style][2] / 255.0f;

				ent->directedLight[0] += factor * data->directLight[j][0] * styleColors[style][0] / 255.0f;
				ent->directedLight[1] += factor * data->directLight[j][1] * styleColors[style][1] / 255.0f;
				ent->directedLight[2] += factor * data->directLight[j][2] * styleColors[style][2] / 255.0f;
			}
			else
			{
				break;
			}
		}

		lat = data->latLong[1];
		lng = data->latLong[0];
		lat *= (FUNCTABLE_SIZE/256);
		lng *= (FUNCTABLE_SIZE/256);

		// decode X as cos( lat ) * sin( long )
		// decode Y as sin( lat ) * sin( long )
		// decode Z as cos( long )

		normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
		normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
		normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];

		VectorMA( direction, factor, normal, direction );

#if ACCURATE_LIGHTGRID_SAMPLING
		if ( r_debugLight->integer && ent->e.hModel == -1 )
		{
			//draw 	
			refEntity_t refEnt;
			refEnt.hModel = 0;
			refEnt.ghoul2 = NULL;
			refEnt.renderfx = 0;
			VectorCopy( gridOrg, refEnt.origin );
			vectoangles( normal, refEnt.angles );
			AnglesToAxis( refEnt.angles, refEnt.axis );
			refEnt.reType = RT_MODEL;
			RE_AddRefEntityToScene( &refEnt );

			refEnt.renderfx = RF_DEPTHHACK;
			refEnt.reType = RT_SPRITE;
			refEnt.customShader = RE_RegisterShader( "gfx/misc/debugAmbient" );
			refEnt.shaderRGBA[0] = data->ambientLight[0][0];
			refEnt.shaderRGBA[1] = data->ambientLight[0][1];
			refEnt.shaderRGBA[2] = data->ambientLight[0][2];
			refEnt.shaderRGBA[3] = 255;
			refEnt.radius = factor*50+2.0f; // maybe always give it a minimum size?
			refEnt.rotation = 0;			// don't let the sprite wobble around
			RE_AddRefEntityToScene( &refEnt );

			refEnt.reType = RT_LINE;
			refEnt.customShader = RE_RegisterShader( "gfx/misc/debugArrow" );
			refEnt.shaderRGBA[0] = data->directLight[0][0];
			refEnt.shaderRGBA[1] = data->directLight[0][1];
			refEnt.shaderRGBA[2] = data->directLight[0][2];
			refEnt.shaderRGBA[3] = 255;
			VectorCopy( refEnt.origin, refEnt.oldorigin );
			VectorMA( gridOrg, (factor*-255) - 2.0f, normal, refEnt.origin ); // maybe always give it a minimum length
			refEnt.radius = 1.5f;
			RE_AddRefEntityToScene( &refEnt );
		}
#endif
	}

	if ( totalFactor > 0 && totalFactor < 0.99 ) 
	{
		totalFactor = 1.0 / totalFactor;
		VectorScale( ent->ambientLight, totalFactor, ent->ambientLight );
		VectorScale( ent->directedLight, totalFactor, ent->directedLight );
	}

	VectorScale( ent->ambientLight, r_ambientScale->value, ent->ambientLight );
	VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight );

	VectorNormalize2( direction, ent->lightDir );
}