From b9374dfb56e7011204844029946cd814f425a65a Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 30 Jan 2013 17:27:36 -0800 Subject: Starting sunlight experimentation branch --- src/renderergl2/tr_bsp.c | 186 +++++++++++++++++++++++++++++++++++++++++++++ src/renderergl2/tr_glsl.c | 3 +- src/renderergl2/tr_light.c | 6 +- src/renderergl2/tr_local.h | 4 +- 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 -- cgit