Ejemplo n.º 1
0
/*
* R_BuildLightmap
*/
static void R_BuildLightmap( int w, int h, qboolean deluxe, const qbyte *data, qbyte *dest, int blockWidth )
{
	int x, y;
	qbyte *rgba;
	int bits = mapConfig.pow2MapOvrbr;

	if( !data || (r_fullbright->integer && !deluxe) )
	{
		int val = deluxe ? 127 : 255;
		for( y = 0; y < h; y++, dest )
			memset( dest + y * blockWidth, val, w * LIGHTMAP_BYTES * sizeof( *dest ) );
		return;
	}

	if( deluxe || ( !bits && !r_lighting_grayscale->integer ) )
	{
		int wB = w * LIGHTMAP_BYTES;
		for( y = 0, rgba = dest; y < h; y++, data += wB, rgba += blockWidth )
		{
			memcpy( rgba, data, wB );
		}
	}
	else
	{
		float scaled[3];
		float intensity = (1 << bits) / 255.0f;

		for( y = 0; y < h; y++ )
		{
			for( x = 0, rgba = dest + y * blockWidth; x < w; x++, data += LIGHTMAP_BYTES, rgba += LIGHTMAP_BYTES )
			{
				vec3_t normalized;

				scaled[0] = (float)( (int)data[0] ) * intensity;
				scaled[1] = (float)( (int)data[1] ) * intensity;
				scaled[2] = (float)( (int)data[2] ) * intensity;

				ColorNormalize( scaled, normalized );

				// monochrome lighting: convert to grayscale
				if( r_lighting_grayscale->integer ) {
					vec_t grey = ColorGrayscale( normalized );
					normalized[0] = normalized[1] = normalized[2] = bound( 0, grey, 1 );
				}

				rgba[0] = ( qbyte )( normalized[0] * 255 );
				rgba[1] = ( qbyte )( normalized[1] * 255 );
				rgba[2] = ( qbyte )( normalized[2] * 255 );
			}
		}
	}
}
Ejemplo n.º 2
0
/*
* R_AddLightToScene
*/
void R_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b )
{
	if( ( rsc.numDlights < MAX_DLIGHTS ) && intensity && ( r != 0 || g != 0 || b != 0 ) )
	{
		dlight_t *dl = &rsc.dlights[rsc.numDlights];

		VectorCopy( org, dl->origin );
		dl->intensity = intensity * DLIGHT_SCALE;
		dl->color[0] = r;
		dl->color[1] = g;
		dl->color[2] = b;

		if( r_lighting_grayscale->integer ) {
			vec_t grey = ColorGrayscale( dl->color );
			dl->color[0] = dl->color[1] = dl->color[2] = bound( 0, grey, 1 );
		}

		rsc.numDlights++;
	}
}
Ejemplo n.º 3
0
/*
* R_LightForOrigin
*/
void R_LightForOrigin( const vec3_t origin, vec3_t dir, vec4_t ambient, vec4_t diffuse, float radius )
{
	int i, j;
	int k, s;
	int vi[3], elem[4];
	float dot, t[8], scale;
	vec3_t vf, vf2, tdir;
	vec3_t ambientLocal, diffuseLocal;
	vec_t *gridSize, *gridMins;
	int *gridBounds;
	static mgridlight_t lightarray[8];
	lightstyle_t *lightStyles = rsc.lightStyles;

	VectorSet( ambientLocal, 0, 0, 0 );
	VectorSet( diffuseLocal, 0, 0, 0 );

	if( !rsh.worldModel /* || (rn.refdef.rdflags & RDF_NOWORLDMODEL)*/ ||
		!rsh.worldBrushModel->lightgrid || !rsh.worldBrushModel->numlightgridelems )
	{
		VectorSet( dir, 0.1f, 0.2f, 0.7f );
		goto dynamic;
	}

	gridSize = rsh.worldBrushModel->gridSize;
	gridMins = rsh.worldBrushModel->gridMins;
	gridBounds = rsh.worldBrushModel->gridBounds;

	for( i = 0; i < 3; i++ )
	{
		vf[i] = ( origin[i] - gridMins[i] ) / gridSize[i];
		vi[i] = (int)vf[i];
		vf[i] = vf[i] - floor( vf[i] );
		vf2[i] = 1.0f - vf[i];
	}

	elem[0] = vi[2] * gridBounds[3] + vi[1] * gridBounds[0] + vi[0];
	elem[1] = elem[0] + gridBounds[0];
	elem[2] = elem[0] + gridBounds[3];
	elem[3] = elem[2] + gridBounds[0];

	for( i = 0; i < 4; i++ )
	{
		lightarray[i*2+0] = *rsh.worldBrushModel->lightarray[bound( 0, elem[i]+0, (int)rsh.worldBrushModel->numlightarrayelems-1)];
		lightarray[i*2+1] = *rsh.worldBrushModel->lightarray[bound( 1, elem[i]+1, (int)rsh.worldBrushModel->numlightarrayelems-1)];
	}

	t[0] = vf2[0] * vf2[1] * vf2[2];
	t[1] = vf[0] * vf2[1] * vf2[2];
	t[2] = vf2[0] * vf[1] * vf2[2];
	t[3] = vf[0] * vf[1] * vf2[2];
	t[4] = vf2[0] * vf2[1] * vf[2];
	t[5] = vf[0] * vf2[1] * vf[2];
	t[6] = vf2[0] * vf[1] * vf[2];
	t[7] = vf[0] * vf[1] * vf[2];

	VectorClear( dir );

	for( i = 0; i < 4; i++ )
	{
		R_LatLongToNorm( lightarray[i*2].direction, tdir );
		VectorScale( tdir, t[i*2], tdir );
		for( k = 0; k < MAX_LIGHTMAPS && ( s = lightarray[i*2].styles[k] ) != 255; k++ )
		{
			dir[0] += lightStyles[s].rgb[0] * tdir[0];
			dir[1] += lightStyles[s].rgb[1] * tdir[1];
			dir[2] += lightStyles[s].rgb[2] * tdir[2];
		}

		R_LatLongToNorm( lightarray[i*2+1].direction, tdir );
		VectorScale( tdir, t[i*2+1], tdir );
		for( k = 0; k < MAX_LIGHTMAPS && ( s = lightarray[i*2+1].styles[k] ) != 255; k++ )
		{
			dir[0] += lightStyles[s].rgb[0] * tdir[0];
			dir[1] += lightStyles[s].rgb[1] * tdir[1];
			dir[2] += lightStyles[s].rgb[2] * tdir[2];
		}
	}

	for( j = 0; j < 3; j++ )
	{
		if( ambient )
		{
			for( i = 0; i < 4; i++ )
			{
				for( k = 0; k < MAX_LIGHTMAPS; k++ )
				{
					if( ( s = lightarray[i*2].styles[k] ) != 255 )
						ambientLocal[j] += t[i*2] * lightarray[i*2].ambient[k][j] * lightStyles[s].rgb[j];
					if( ( s = lightarray[i*2+1].styles[k] ) != 255 )
						ambientLocal[j] += t[i*2+1] * lightarray[i*2+1].ambient[k][j] * lightStyles[s].rgb[j];
				}
			}
		}
		if( diffuse || radius )
		{
			for( i = 0; i < 4; i++ )
			{
				for( k = 0; k < MAX_LIGHTMAPS; k++ )
				{
					if( ( s = lightarray[i*2].styles[k] ) != 255 )
						diffuseLocal[j] += t[i*2] * lightarray[i*2].diffuse[k][j] * lightStyles[s].rgb[j];
					if( ( s = lightarray[i*2+1].styles[k] ) != 255 )
						diffuseLocal[j] += t[i*2+1] * lightarray[i*2+1].diffuse[k][j] * lightStyles[s].rgb[j];
				}
			}
		}
	}

	// convert to grayscale
	if( r_lighting_grayscale->integer ) {
		vec_t grey;

		if( ambient ) {
			grey = ColorGrayscale( ambientLocal );
			ambientLocal[0] = ambientLocal[1] = ambientLocal[2] = bound( 0, grey, 255 );
		}

		if( diffuse || radius ) {
			grey = ColorGrayscale( diffuseLocal );
			diffuseLocal[0] = diffuseLocal[1] = diffuseLocal[2] = bound( 0, grey, 255 );
		}
	}

dynamic:
	// add dynamic lights
	if( radius && r_dynamiclight->integer )
	{
		unsigned int lnum;
		dlight_t *dl;
		float dist, dist2, add;
		vec3_t direction;
		qboolean anyDlights = qfalse;

		for( lnum = 0; lnum < rsc.numDlights; lnum++ )
		{
			dl = rsc.dlights + lnum;
			if( Distance( dl->origin, origin ) > dl->intensity + radius )
				continue;

			VectorSubtract( dl->origin, origin, direction );
			dist = VectorLength( direction );

			if( !dist || dist > dl->intensity + radius )
				continue;

			if( !anyDlights )
			{
				VectorNormalizeFast( dir );
				anyDlights = qtrue;
			}

			add = 1.0 - (dist / (dl->intensity + radius));
			dist2 = add * 0.5 / dist;
			for( i = 0; i < 3; i++ )
			{
				dot = dl->color[i] * add;
				diffuseLocal[i] += dot;
				ambientLocal[i] += dot * 0.05;
				dir[i] += direction[i] * dist2;
			}
		}
	}

	VectorNormalizeFast( dir );

	scale = mapConfig.mapLightColorScale / 255.0f;

	if( ambient )
	{
		float scale2 = bound( 0.0f, r_lighting_ambientscale->value, 1.0f ) * scale;

		for( i = 0; i < 3; i++ )
			ambient[i] = ambientLocal[i] * scale2;

		ambient[3] = 1.0f;
	}

	if( diffuse )
	{
		float scale2 = bound( 0.0f, r_lighting_directedscale->value, 1.0f ) * scale;

		for( i = 0; i < 3; i++ )
			diffuse[i] = diffuseLocal[i] * scale2;

		diffuse[3] = 1.0f;
	}
}