diff options
| author | SmileTheory <SmileTheory@gmail.com> | 2013-01-30 17:27:36 -0800 | 
|---|---|---|
| committer | Tim Angus <tim@ngus.net> | 2013-05-03 16:06:37 +0100 | 
| commit | b9374dfb56e7011204844029946cd814f425a65a (patch) | |
| tree | 6114b82cfeb452b6f3257eae67a7e06aaa387051 | |
| parent | 38daed324464666b5a4bb6a758c60e960b4610f0 (diff) | |
Starting sunlight experimentation branch
| -rw-r--r-- | src/renderergl2/tr_bsp.c | 186 | ||||
| -rw-r--r-- | src/renderergl2/tr_glsl.c | 3 | ||||
| -rw-r--r-- | src/renderergl2/tr_light.c | 6 | ||||
| -rw-r--r-- | src/renderergl2/tr_local.h | 4 | ||||
| -rw-r--r-- | src/renderergl2/tr_shade.c | 15 | 
5 files changed, 210 insertions, 4 deletions
diff --git a/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c index 824e6c2b..b85189fd 100644 --- a/src/renderergl2/tr_bsp.c +++ b/src/renderergl2/tr_bsp.c @@ -3348,6 +3348,192 @@ void RE_LoadWorldMap( const char *name ) {  	// determine vertex light directions  	R_CalcVertexLightDirs(); +	// determine which parts of the map are in sunlight +	if (0) +	{ +		world_t	*w; + +		w = &s_worldData; +		uint8_t *primaryLightGrid, *data; +		int lightGridSize; +		int i; + +		lightGridSize = w->lightGridBounds[0] * w->lightGridBounds[1] * w->lightGridBounds[2]; +		primaryLightGrid = ri.Malloc(lightGridSize * sizeof(*primaryLightGrid)); + +		memset(primaryLightGrid, 0, lightGridSize * sizeof(*primaryLightGrid)); + +		data = w->lightGridData; +		for (i = 0; i < lightGridSize; i++, data += 8) +		{ +			int lat, lng; +			vec3_t gridLightDir, gridLightCol; + +			// skip samples in wall +			if (!(data[0]+data[1]+data[2]+data[3]+data[4]+data[5]) ) +				continue; + +			gridLightCol[0] = ByteToFloat(data[3]); +			gridLightCol[1] = ByteToFloat(data[4]); +			gridLightCol[2] = ByteToFloat(data[5]); + +			lat = data[7]; +			lng = data[6]; +			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 ) + +			gridLightDir[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; +			gridLightDir[1] = tr.sinTable[lat] * tr.sinTable[lng]; +			gridLightDir[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; + +			// FIXME: magic number for determining if light direction is close enough to sunlight +			if (DotProduct(gridLightDir, tr.sunDirection) > 0.75f) +			{ +				primaryLightGrid[i] = 1; +			} +			else +			{ +				primaryLightGrid[i] = 255; +			} +		} + +		if (0) +		{ +			int i; +			byte *buffer = ri.Malloc(w->lightGridBounds[0] * w->lightGridBounds[1] * 3 + 18); +			byte *out; +			uint8_t *in; +			char fileName[MAX_QPATH]; +			 +			Com_Memset (buffer, 0, 18); +			buffer[2] = 2;		// uncompressed type +			buffer[12] = w->lightGridBounds[0] & 255; +			buffer[13] = w->lightGridBounds[0] >> 8; +			buffer[14] = w->lightGridBounds[1] & 255; +			buffer[15] = w->lightGridBounds[1] >> 8; +			buffer[16] = 24;	// pixel size + +			in = primaryLightGrid; +			for (i = 0; i < w->lightGridBounds[2]; i++) +			{ +				int j; + +				sprintf(fileName, "primarylg%d.tga", i); + +				out = buffer + 18; +				for (j = 0; j < w->lightGridBounds[0] * w->lightGridBounds[1]; j++) +				{ +					if (*in == 1) +					{ +						*out++ = 255; +						*out++ = 255; +						*out++ = 255; +					} +					else if (*in == 255) +					{ +						*out++ = 64; +						*out++ = 64; +						*out++ = 64; +					} +					else +					{ +						*out++ = 0; +						*out++ = 0; +						*out++ = 0; +					} +					in++; +				} + +				ri.FS_WriteFile(fileName, buffer, w->lightGridBounds[0] * w->lightGridBounds[1] * 3 + 18); +			} + +			ri.Free(buffer); +		} + +		for (i = 0; i < w->numWorldSurfaces; i++) +		{ +			msurface_t *surf = w->surfaces + i; +			cullinfo_t *ci = &surf->cullinfo; + +			if(ci->type & CULLINFO_PLANE) +			{ +				if (DotProduct(ci->plane.normal, tr.sunDirection) <= 0.0f) +				{ +					//ri.Printf(PRINT_ALL, "surface %d is not oriented towards sunlight\n", i); +					continue; +				} +			} + +			if(ci->type & CULLINFO_BOX) +			{ +				int ibounds[2][3], x, y, z, goodSamples, numSamples; +				vec3_t lightOrigin; + +				VectorSubtract( ci->bounds[0], w->lightGridOrigin, lightOrigin ); + +				ibounds[0][0] = floor(lightOrigin[0] * w->lightGridInverseSize[0]); +				ibounds[0][1] = floor(lightOrigin[1] * w->lightGridInverseSize[1]); +				ibounds[0][2] = floor(lightOrigin[2] * w->lightGridInverseSize[2]); + +				VectorSubtract( ci->bounds[1], w->lightGridOrigin, lightOrigin ); + +				ibounds[1][0] = ceil(lightOrigin[0] * w->lightGridInverseSize[0]); +				ibounds[1][1] = ceil(lightOrigin[1] * w->lightGridInverseSize[1]); +				ibounds[1][2] = ceil(lightOrigin[2] * w->lightGridInverseSize[2]); + +				ibounds[0][0] = CLAMP(ibounds[0][0], 0, w->lightGridSize[0]); +				ibounds[0][1] = CLAMP(ibounds[0][1], 0, w->lightGridSize[1]); +				ibounds[0][2] = CLAMP(ibounds[0][2], 0, w->lightGridSize[2]); + +				ibounds[1][0] = CLAMP(ibounds[1][0], 0, w->lightGridSize[0]); +				ibounds[1][1] = CLAMP(ibounds[1][1], 0, w->lightGridSize[1]); +				ibounds[1][2] = CLAMP(ibounds[1][2], 0, w->lightGridSize[2]); + +				/* +				ri.Printf(PRINT_ALL, "surf %d bounds (%f %f %f)-(%f %f %f) ibounds (%d %d %d)-(%d %d %d)\n", i, +					ci->bounds[0][0], ci->bounds[0][1], ci->bounds[0][2], +					ci->bounds[1][0], ci->bounds[1][1], ci->bounds[1][2], +					ibounds[0][0], ibounds[0][1], ibounds[0][2], +					ibounds[1][0], ibounds[1][1], ibounds[1][2]); +				*/ + +				goodSamples = 0; +				numSamples = 0; +				for (x = ibounds[0][0]; x <= ibounds[1][0]; x++) +				{ +					for (y = ibounds[0][1]; y <= ibounds[1][1]; y++) +					{ +						for (z = ibounds[0][2]; z <= ibounds[1][2]; z++) +						{ +							uint8_t primaryLight = primaryLightGrid[x * 8 + y * 8 * w->lightGridBounds[0] + z * 8 * w->lightGridBounds[0] * w->lightGridBounds[2]]; + +							if (primaryLight == 0) +								continue; + +							numSamples++; + +							if (primaryLight == 1) +								goodSamples++; +						} +					} +				} + +				// FIXME: magic number for determining whether object is mostly in sunlight +				if (goodSamples > numSamples * 0.75f) +				{ +					//ri.Printf(PRINT_ALL, "surface %d is in sunlight\n", i); +					//surf->primaryLight = 1; +				} +			} +		} + +		ri.Free(primaryLightGrid); +	} +  	// create static VBOS from the world  	R_CreateWorldVBO();  	if (r_mergeLeafSurfaces->integer) diff --git a/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c index d0e99651..163da908 100644 --- a/src/renderergl2/tr_glsl.c +++ b/src/renderergl2/tr_glsl.c @@ -1008,7 +1008,8 @@ void GLSL_InitGPUShaders(void)  		if (!(i & LIGHTDEF_USE_NORMALMAP) && (i & LIGHTDEF_USE_PARALLAXMAP))  			continue; -		if (!((i & LIGHTDEF_LIGHTTYPE_MASK) == LIGHTDEF_USE_LIGHT_VECTOR)) +		//if (!((i & LIGHTDEF_LIGHTTYPE_MASK) == LIGHTDEF_USE_LIGHT_VECTOR)) +		if (!(i & LIGHTDEF_LIGHTTYPE_MASK))  		{  			if (i & LIGHTDEF_USE_SHADOWMAP)  				continue; diff --git a/src/renderergl2/tr_light.c b/src/renderergl2/tr_light.c index a54e7c04..82e088e8 100644 --- a/src/renderergl2/tr_light.c +++ b/src/renderergl2/tr_light.c @@ -442,7 +442,11 @@ int R_LightDirForPoint( vec3_t point, vec3_t lightDir, vec3_t normal, world_t *w  	Com_Memset(&ent, 0, sizeof(ent));  	VectorCopy( point, ent.e.origin );  	R_SetupEntityLightingGrid( &ent, world ); -	VectorCopy(ent.lightDir, lightDir); + +	if (DotProduct(ent.lightDir, normal) > 0.2f) +		VectorCopy(ent.lightDir, lightDir); +	else +		VectorCopy(normal, lightDir);  	return qtrue;  } diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index 7d5439d4..c550ca18 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -363,12 +363,12 @@ enum  	TB_DIFFUSEMAP  = 0,  	TB_LIGHTMAP    = 1,  	TB_LEVELSMAP   = 1, -	TB_SHADOWMAP   = 1, +	TB_SHADOWMAP3  = 1,  	TB_NORMALMAP   = 2,  	TB_DELUXEMAP   = 3,  	TB_SHADOWMAP2  = 3,  	TB_SPECULARMAP = 4, -	TB_SHADOWMAP3  = 5, +	TB_SHADOWMAP   = 5,  	NUM_TEXTURE_BUNDLES = 6  }; diff --git a/src/renderergl2/tr_shade.c b/src/renderergl2/tr_shade.c index ace5b2dc..fbf11d6a 100644 --- a/src/renderergl2/tr_shade.c +++ b/src/renderergl2/tr_shade.c @@ -1330,6 +1330,11 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )  				index |= LIGHTDEF_ENTITY;  			} +			if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && ((index & LIGHTDEF_USE_LIGHTMAP) || (index & LIGHTDEF_USE_LIGHT_VERTEX))) +			{ +				index |= LIGHTDEF_USE_SHADOWMAP; +			} +  			if (r_lightmap->integer && index & LIGHTDEF_USE_LIGHTMAP)  			{  				index = LIGHTDEF_USE_LIGHTMAP; @@ -1493,6 +1498,14 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )  		{  			int i; +			if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && ((pStage->glslShaderIndex & LIGHTDEF_USE_LIGHTMAP) || (pStage->glslShaderIndex & LIGHTDEF_USE_LIGHT_VERTEX))) +			{ +				GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP); +				GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT,   backEnd.refdef.sunAmbCol); +				GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT,  backEnd.refdef.sunCol); +				GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_LIGHTORIGIN, backEnd.refdef.sunDir); +			} +  			if ((r_lightmap->integer == 1 || r_lightmap->integer == 2) && pStage->bundle[TB_LIGHTMAP].image[0])  			{  				for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) @@ -1783,11 +1796,13 @@ void RB_StageIteratorGeneric( void )  		}  	} +#if 0  	if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && tess.shader->sort <= SS_OPAQUE   	//if ((tr.sunShadows || r_forceSunlight->value > 0.0f) && tess.shader->sort <= SS_OPAQUE   	    && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) && tess.xstages[0]->glslShaderGroup == tr.lightallShader) {  		ForwardSunlight();  	} +#endif  	//  	// now do fog  | 
