summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSmileTheory <SmileTheory@gmail.com>2013-01-30 17:27:36 -0800
committerTim Angus <tim@ngus.net>2013-05-03 16:06:37 +0100
commitb9374dfb56e7011204844029946cd814f425a65a (patch)
tree6114b82cfeb452b6f3257eae67a7e06aaa387051
parent38daed324464666b5a4bb6a758c60e960b4610f0 (diff)
Starting sunlight experimentation branch
-rw-r--r--src/renderergl2/tr_bsp.c186
-rw-r--r--src/renderergl2/tr_glsl.c3
-rw-r--r--src/renderergl2/tr_light.c6
-rw-r--r--src/renderergl2/tr_local.h4
-rw-r--r--src/renderergl2/tr_shade.c15
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