From 2fe74a1bd078fa8684b11fc555d6501cbdd3513c Mon Sep 17 00:00:00 2001 From: divverent Date: Tue, 28 Sep 2010 12:04:33 +0000 Subject: [PATCH] r_fakelight: 1 = use "fake" lighting (falloff-less light source at eye origin) if the loaded worldmodel is unlit, 2 = always use "fake" lighting; controlling cvar r_fakelight_intensity (0.75 is an empiric default value that on average seems to match the lightmap brightness of a selection of nexuiz maps) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10503 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 108 +++++++++++++++++++++++++++++++++++++++++++++---- model_brush.c | 4 ++ model_shared.h | 3 ++ 3 files changed, 108 insertions(+), 7 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 641242ab..52572fdf 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -92,6 +92,11 @@ cvar_t r_cullentities_trace_enlarge = {0, "r_cullentities_trace_enlarge", "0", " cvar_t r_cullentities_trace_delay = {0, "r_cullentities_trace_delay", "1", "number of seconds until the entity gets actually culled"}; cvar_t r_speeds = {0, "r_speeds","0", "displays rendering statistics and per-subsystem timings"}; cvar_t r_fullbright = {0, "r_fullbright","0", "makes map very bright and renders faster"}; + +cvar_t r_fakelight = {0, "r_fakelight","0", "render 'fake' lighting instead of real lightmaps"}; +cvar_t r_fakelight_intensity = {0, "r_fakelight_intensity","0.75", "fakelight intensity modifier"}; +#define FAKELIGHT_ENABLED (r_fakelight.integer >= 2 || (r_fakelight.integer && r_refdef.scene.worldmodel && !r_refdef.scene.worldmodel->lit)) + cvar_t r_wateralpha = {CVAR_SAVE, "r_wateralpha","1", "opacity of water polygons"}; cvar_t r_dynamic = {CVAR_SAVE, "r_dynamic","1", "enables dynamic lights (rocket glow and such)"}; cvar_t r_fullbrights = {CVAR_SAVE, "r_fullbrights", "1", "enables glowing pixels in quake textures (changes need r_restart to take effect)"}; @@ -583,7 +588,7 @@ static const char *builtinshaderstring = "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n" "#define USELIGHTMAP\n" "#endif\n" -"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE)\n" +"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE) || defined(MODE_FAKELIGHT)\n" "#define USEEYEVECTOR\n" "#endif\n" "\n" @@ -1664,6 +1669,15 @@ static const char *builtinshaderstring = "\n" "\n" "\n" +"#ifdef MODE_FAKELIGHT\n" +"#define SHADING\n" +"myhalf3 lightnormal = myhalf3(normalize(EyeVector));\n" +"myhalf3 lightcolor = myhalf3(1.0);\n" +"#endif // MODE_FAKELIGHT\n" +"\n" +"\n" +"\n" +"\n" "#ifdef MODE_LIGHTMAP\n" " color.rgb = diffusetex * (Color_Ambient + myhalf3(texture2D(Texture_Lightmap, TexCoordLightmap)) * Color_Diffuse);\n" "#endif // MODE_LIGHTMAP\n" @@ -1796,7 +1810,7 @@ const char *builtincgshaderstring = "#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n" "#define USELIGHTMAP\n" "#endif\n" -"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE)\n" +"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING) || defined(USEREFLECTCUBE) || defined(MODE_FAKELIGHT)\n" "#define USEEYEVECTOR\n" "#endif\n" "\n" @@ -3163,6 +3177,15 @@ const char *builtincgshaderstring = "\n" "\n" "\n" +"#ifdef MODE_FAKELIGHT\n" +"#define SHADING\n" +"half3 lightnormal = half3(normalize(EyeVector));\n" +"half3 lightcolor = half3(1.0);\n" +"#endif // MODE_FAKELIGHT\n" +"\n" +"\n" +"\n" +"\n" "#ifdef MODE_LIGHTMAP\n" " color.rgb = diffusetex * (Color_Ambient + half3(tex2D(Texture_Lightmap, TexCoordLightmap).rgb) * Color_Diffuse);\n" "#endif // MODE_LIGHTMAP\n" @@ -3351,6 +3374,7 @@ typedef enum shadermode_e SHADERMODE_FLATCOLOR, ///< (lightmap) modulate texture by uniform color (q1bsp, q3bsp) SHADERMODE_VERTEXCOLOR, ///< (lightmap) modulate texture by vertex colors (q3bsp) SHADERMODE_LIGHTMAP, ///< (lightmap) modulate texture by lightmap texture (q1bsp, q3bsp) + SHADERMODE_FAKELIGHT, ///< (fakelight) modulate texture by "fake" lighting (no lightmaps, no nothing) SHADERMODE_LIGHTDIRECTIONMAP_MODELSPACE, ///< (lightmap) use directional pixel shading from texture containing modelspace light directions (q3bsp deluxemap) SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE, ///< (lightmap) use directional pixel shading from texture containing tangentspace light directions (q1bsp deluxemap) SHADERMODE_LIGHTDIRECTION, ///< (lightmap) use directional pixel shading from fixed light direction (q3bsp) @@ -3373,6 +3397,7 @@ shadermodeinfo_t glslshadermodeinfo[SHADERMODE_COUNT] = {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FLATCOLOR\n", " flatcolor"}, {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_VERTEXCOLOR\n", " vertexcolor"}, {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTMAP\n", " lightmap"}, + {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_FAKELIGHT\n", " fakelight"}, {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"}, {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"}, {"glsl/default.glsl", NULL, "glsl/default.glsl", "#define MODE_LIGHTDIRECTION\n", " lightdirection"}, @@ -3393,6 +3418,7 @@ shadermodeinfo_t cgshadermodeinfo[SHADERMODE_COUNT] = {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_FLATCOLOR\n", " flatcolor"}, {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_VERTEXCOLOR\n", " vertexcolor"}, {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTMAP\n", " lightmap"}, + {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_FAKELIGHT\n", " fakelight"}, {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n", " lightdirectionmap_modelspace"}, {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n", " lightdirectionmap_tangentspace"}, {"cg/default.cg", NULL, "cg/default.cg", "#define MODE_LIGHTDIRECTION\n", " lightdirection"}, @@ -5505,7 +5531,19 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_DEFERREDLIGHTMAP; if (rsurface.texture->reflectmasktexture) permutation |= SHADERPERMUTATION_REFLECTCUBE; - if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping) + if (FAKELIGHT_ENABLED) + { + // fake lightmapping (q1bsp, q3bsp, fullbright map) + mode = SHADERMODE_FAKELIGHT; + permutation |= SHADERPERMUTATION_DIFFUSE; + if (specularscale > 0) + { + permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; + if (r_shadow_glossexact.integer) + permutation |= SHADERPERMUTATION_EXACTSPECULARMATH; + } + } + else if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping) { // deluxemapping (light direction texture) if (rsurface.uselightmaptexture && r_refdef.scene.worldmodel && r_refdef.scene.worldmodel->brushq3.deluxemapping && r_refdef.scene.worldmodel->brushq3.deluxemapping_modelspace) @@ -5520,7 +5558,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_EXACTSPECULARMATH; } } - else if (r_glsl_deluxemapping.integer >= 2) + else if (r_glsl_deluxemapping.integer >= 2 && rsurface.uselightmaptexture) { // fake deluxemapping (uniform light direction in tangentspace) mode = SHADERMODE_LIGHTDIRECTIONMAP_TANGENTSPACE; @@ -7204,6 +7242,8 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_fullbrights); Cvar_RegisterVariable(&r_wateralpha); Cvar_RegisterVariable(&r_dynamic); + Cvar_RegisterVariable(&r_fakelight); + Cvar_RegisterVariable(&r_fakelight_intensity); Cvar_RegisterVariable(&r_fullbright); Cvar_RegisterVariable(&r_shadows); Cvar_RegisterVariable(&r_shadows_darken); @@ -9190,6 +9230,10 @@ void R_UpdateVariables(void) r_refdef.scene.rtdlight = (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) && !gl_flashblend.integer && r_dynamic.integer; r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil; r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1; + if (FAKELIGHT_ENABLED) + { + r_refdef.lightmapintensity *= r_fakelight_intensity.value; + } if (r_showsurfaces.integer) { r_refdef.scene.rtworld = false; @@ -10280,6 +10324,10 @@ texture_t *R_GetCurrentTexture(texture_t *t) t->currentmaterialflags &= ~(MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION | MATERIALFLAG_CAMERA); if (!(rsurface.ent_flags & RENDER_LIGHT)) t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT; + else if (FAKELIGHT_ENABLED) + { + // no modellight if using fakelight for the map + } else if (rsurface.modeltexcoordlightmap2f == NULL && !(t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) { // pick a model lighting mode @@ -12082,6 +12130,40 @@ static void RSurf_DrawBatch_GL11_ClampColor(void) } } +static void RSurf_DrawBatch_GL11_ApplyFakeLight(void) +{ + int i; + float f; + const float *v; + const float *n; + float *c; + //vec3_t eyedir; + + // fake shading + for (i = 0, v = rsurface.batchvertex3f + rsurface.batchfirstvertex * 3, n = rsurface.batchnormal3f + rsurface.batchfirstvertex * 3, c = rsurface.array_passcolor4f + rsurface.batchfirstvertex * 4;i < rsurface.batchnumvertices;i++, v += 3, n += 3, c += 4) + { + f = -DotProduct(r_refdef.view.forward, n); + f = max(0, f); + f = f * 0.85 + 0.15; // work around so stuff won't get black + f *= r_refdef.lightmapintensity; + Vector4Set(c, f, f, f, 1); + } + + rsurface.passcolor4f = rsurface.array_passcolor4f; + rsurface.passcolor4f_vertexbuffer = 0; + rsurface.passcolor4f_bufferoffset = 0; +} + +static void RSurf_DrawBatch_GL11_FakeLight(float r, float g, float b, float a, qboolean applycolor, qboolean applyfog) +{ + RSurf_DrawBatch_GL11_ApplyFakeLight(); + if (applyfog) RSurf_DrawBatch_GL11_ApplyFog(); + if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(r, g, b, a); + R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), rsurface.passcolor4f, rsurface.passcolor4f_vertexbuffer, rsurface.passcolor4f_bufferoffset); + GL_Color(r, g, b, a); + RSurf_DrawBatch(); +} + static void RSurf_DrawBatch_GL11_ApplyVertexShade(float *r, float *g, float *b, float *a, qboolean *applycolor) { int i; @@ -12332,6 +12414,8 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, const msurface R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordtexture2f_vertexbuffer, rsurface.batchtexcoordtexture2f_bufferoffset); if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) RSurf_DrawBatch_GL11_VertexShade(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog); + else if (FAKELIGHT_ENABLED) + RSurf_DrawBatch_GL11_FakeLight(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog); else if (rsurface.uselightmaptexture) RSurf_DrawBatch_GL11_Lightmap(layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog); else @@ -12417,6 +12501,8 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, const msurface R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordlightmap2f_vertexbuffer, rsurface.batchtexcoordlightmap2f_bufferoffset); if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT) RSurf_DrawBatch_GL11_VertexShade(1, 1, 1, 1, false, false); + else if (FAKELIGHT_ENABLED) + RSurf_DrawBatch_GL11_FakeLight(1, 1, 1, 1, false, false); else if (rsurface.uselightmaptexture) RSurf_DrawBatch_GL11_Lightmap(1, 1, 1, 1, false, false); else @@ -12568,6 +12654,14 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, const RSurf_DrawBatch_GL11_ApplyVertexShade(&one, &one, &one, &one, &applycolor); r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all } + else if (FAKELIGHT_ENABLED) + { + RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_NORMAL | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); + + r_refdef.lightmapintensity = r_fakelight_intensity.value; + RSurf_DrawBatch_GL11_ApplyFakeLight(); + r_refdef.lightmapintensity = 0; // we're in showsurfaces, after all + } else { RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX | BATCHNEED_ARRAY_VERTEXCOLOR | BATCHNEED_NOGAPS, texturenumsurfaces, texturesurfacelist); @@ -12802,7 +12896,7 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const surface = rsurface.modelsurfaces + surfacelist[i]; texture = surface->texture; rsurface.texture = R_GetCurrentTexture(texture); - rsurface.lightmaptexture = surface->lightmaptexture; + rsurface.lightmaptexture = FAKELIGHT_ENABLED ? NULL : surface->lightmaptexture; rsurface.deluxemaptexture = surface->deluxemaptexture; rsurface.uselightmaptexture = surface->lightmaptexture != NULL; // scan ahead until we find a different texture @@ -12908,7 +13002,7 @@ void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacelist, in // use skin 1 instead) texture = surfacelist[i]->texture; rsurface.texture = R_GetCurrentTexture(texture); - rsurface.lightmaptexture = surfacelist[i]->lightmaptexture; + rsurface.lightmaptexture = FAKELIGHT_ENABLED ? NULL : surfacelist[i]->lightmaptexture; rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture; rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL && !depthonly && !prepass; if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW)) @@ -12972,7 +13066,7 @@ void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const msurfa // use skin 1 instead) texture = surfacelist[i]->texture; rsurface.texture = R_GetCurrentTexture(texture); - rsurface.lightmaptexture = surfacelist[i]->lightmaptexture; + rsurface.lightmaptexture = FAKELIGHT_ENABLED ? NULL : surfacelist[i]->lightmaptexture; rsurface.deluxemaptexture = surfacelist[i]->deluxemaptexture; rsurface.uselightmaptexture = surfacelist[i]->lightmaptexture != NULL && !depthonly && !prepass; if (!(rsurface.texture->currentmaterialflags & flagsmask) || (rsurface.texture->currentmaterialflags & MATERIALFLAG_NODRAW)) diff --git a/model_brush.c b/model_brush.c index d9de089a..9c7c9ad4 100644 --- a/model_brush.c +++ b/model_brush.c @@ -2413,6 +2413,7 @@ static void Mod_Q1BSP_LoadFaces(lump_t *l) // lightmap is needed on this surface (rather than duplicating the // logic above) loadmodel->brushq1.lightmapupdateflags[surfacenum] = true; + loadmodel->lit = true; } } @@ -4506,6 +4507,8 @@ static void Mod_Q3BSP_LoadVertices(lump_t *l) loadmodel->brushq3.data_color4f[i * 4 + 1] = in->color4ub[1] * (1.0f / 255.0f); loadmodel->brushq3.data_color4f[i * 4 + 2] = in->color4ub[2] * (1.0f / 255.0f); loadmodel->brushq3.data_color4f[i * 4 + 3] = in->color4ub[3] * (1.0f / 255.0f); + if(in->color4ub[0] != 255 || in->color4ub[1] != 255 || in->color4ub[2] != 255) + loadmodel->lit = true; } } @@ -4957,6 +4960,7 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l) out->lightmaptexture = loadmodel->brushq3.data_lightmaps[n >> loadmodel->brushq3.num_lightmapmergedwidthheightdeluxepower]; if (loadmodel->brushq3.deluxemapping) out->deluxemaptexture = loadmodel->brushq3.data_deluxemaps[n >> loadmodel->brushq3.num_lightmapmergedwidthheightdeluxepower]; + loadmodel->lit = true; } } diff --git a/model_shared.h b/model_shared.h index 73972184..8b8a91a2 100644 --- a/model_shared.h +++ b/model_shared.h @@ -1036,6 +1036,9 @@ typedef struct model_s model_brushq3_t brushq3; // flags this model for offseting sounds to the model center (used by brush models) int soundfromcenter; + + // if set, the model contains light information (lightmap, or vertexlight) + qboolean lit; } dp_model_t; -- 2.39.2