diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index 58b47a5e..b7b66cdd 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -41,6 +41,7 @@ If you have questions concerning this license or the applicable additional terms #include "renderer/tr_local.h" #include "framework/GameCallbacks_local.h" +#include "framework/Game.h" // Vista OpenGL wrapper check #ifdef _WIN32 @@ -171,6 +172,13 @@ idCVar r_forceLoadImages( "r_forceLoadImages", "0", CVAR_RENDERER | CVAR_ARCHIVE idCVar r_orderIndexes( "r_orderIndexes", "1", CVAR_RENDERER | CVAR_BOOL, "perform index reorganization to optimize vertex use" ); idCVar r_lightAllBackFaces( "r_lightAllBackFaces", "0", CVAR_RENDERER | CVAR_BOOL, "light all the back faces, even when they would be shadowed" ); +// DG: added this to support "nospecular" param of lights +// NOTE: if you're developing a standalone game, you'll probably want to use "1" as default value +idCVar r_supportNoSpecular( "r_supportNoSpecular", "-1", CVAR_RENDERER | CVAR_INTEGER | CVAR_ARCHIVE, + "Support 'nospecular' parm on lights. Vanilla Doom3 didn't, so the original maps are probably " + "expecting it to not do anything. -1: Only support in maps that have have \"allow_nospecular\" \"1\" set in worldspawn (default), " + "0: never respect 'nospecular' parm 1: support 'nospecular' in all maps", -1, 1 ); + // visual debugging info idCVar r_showPortals( "r_showPortals", "0", CVAR_RENDERER | CVAR_BOOL, "draw portal outlines in color based on passed / not passed" ); idCVar r_showUnsmoothedTangents( "r_showUnsmoothedTangents", "0", CVAR_RENDERER | CVAR_BOOL, "if 1, put all nvidia register combiner programming in display lists" ); @@ -2330,6 +2338,7 @@ void idRenderSystemLocal::Clear( void ) { guiModel = NULL; demoGuiModel = NULL; takingScreenshot = false; + allowNoSpecular = false; } /* @@ -2439,6 +2448,23 @@ void idRenderSystemLocal::EndLevelLoad( void ) { if ( r_forceLoadImages.GetBool() ) { RB_ShowImages(); } + // DG: check if the levels worldspawn has "allow_nospecular" set, which tells us that + // the map author wants "nospecular" parms of lights to be respected by the renderer + // (Vanilla Doom3 didn't, even though some official levels have it set, so to not + // change the look of the original game it must be enabled in the worldspawn of new maps) + // See also the r_supportNoSpecular CVar (the allowNoSpecular set here only makes + // a difference if r_supportNoSpecular is -1, which is the default) + allowNoSpecular = false; + if ( gameEdit != NULL ) { + idEntity* ent = gameEdit->FindEntity( "world" ); // the worldspawn always called "world" + const idDict* ws = gameEdit->EntityGetSpawnArgs( ent ); + if ( ws != NULL ) { + allowNoSpecular = ws->GetBool( "allow_nospecular", "0" ); + if ( allowNoSpecular ) { + common->Printf( "This map allows lights to use the 'nospecular' parm on lights\n" ); + } + } + } } /* diff --git a/neo/renderer/RenderWorld_load.cpp b/neo/renderer/RenderWorld_load.cpp index 86af311e..33cbbe0a 100644 --- a/neo/renderer/RenderWorld_load.cpp +++ b/neo/renderer/RenderWorld_load.cpp @@ -491,6 +491,9 @@ bool idRenderWorldLocal::InitFromMap( const char *name ) { return true; } + // DG: this must be set to false somewhere as a default, here feels safe + // (it will be properly set in idRenderSystemLocal::EndLevelLoad()) + tr.allowNoSpecular = false; // load it filename = name; diff --git a/neo/renderer/tr_local.h b/neo/renderer/tr_local.h index 51ae91d4..efa76bbe 100644 --- a/neo/renderer/tr_local.h +++ b/neo/renderer/tr_local.h @@ -805,6 +805,10 @@ public: // so they can be reset in EndFrame() (Editors tend to mess up the viewport by using BeginFrame()) int origWidth; int origHeight; + + // DG: taken from the current map's worldspawn ("allow_nospecular") + // true if (unlike in Vanilla Doom3) the "nospecular" parm of a light should be respected + bool allowNoSpecular; }; extern backEndState_t backEnd; @@ -882,6 +886,8 @@ extern idCVar r_useEntityCallbacks; // if 0, issue the callback immediately at extern idCVar r_lightAllBackFaces; // light all the back faces, even when they would be shadowed extern idCVar r_useDepthBoundsTest; // use depth bounds test to reduce shadow fill +extern idCVar r_supportNoSpecular; // support nospecular parm of lights + extern idCVar r_skipPostProcess; // skip all post-process renderings extern idCVar r_skipSuppress; // ignore the per-view suppressions extern idCVar r_skipInteractions; // skip all light/surface interaction drawing diff --git a/neo/renderer/tr_render.cpp b/neo/renderer/tr_render.cpp index 2b7e10fc..c83ebb54 100644 --- a/neo/renderer/tr_render.cpp +++ b/neo/renderer/tr_render.cpp @@ -706,6 +706,16 @@ void RB_CreateSingleDrawInteractions( const drawSurf_t *surf, void (*DrawInterac return; } + // DG: support lights nospecular parm, if desired by mapper and/or user + int noSpecVar = r_supportNoSpecular.GetInteger(); + bool allowNoSpecular = (noSpecVar == 1); + if ( noSpecVar == -1 ) { + // r_supportNoSpecular -1 only allows nospecular if the map enables + // it in the worldspawn by setting "allow_nospecular" "1" + // the value of that is saved in tr.allowNoSpecular by idRenderSystemLocal::EndLevelLoad() + allowNoSpecular = tr.allowNoSpecular; + } + // change the matrix and light projection vectors if needed if ( surf->space != backEnd.currentSpace ) { backEnd.currentSpace = surf->space; @@ -823,13 +833,18 @@ void RB_CreateSingleDrawInteractions( const drawSurf_t *surf, void (*DrawInterac if ( inter.specularImage ) { RB_SubmittInteraction( &inter, DrawInteraction ); } - R_SetDrawInteraction( surfaceStage, surfaceRegs, &inter.specularImage, - inter.specularMatrix, inter.specularColor.ToFloatPtr() ); - inter.specularColor[0] *= lightColor[0]; - inter.specularColor[1] *= lightColor[1]; - inter.specularColor[2] *= lightColor[2]; - inter.specularColor[3] *= lightColor[3]; - inter.vertexColor = surfaceStage->vertexColor; +// jmarshall - add no specular support(great for fill lighting). + if ( !allowNoSpecular || !vLight->lightDef->parms.noSpecular ) + { + R_SetDrawInteraction( surfaceStage, surfaceRegs, &inter.specularImage, + inter.specularMatrix, inter.specularColor.ToFloatPtr() ); + inter.specularColor[0] *= lightColor[0]; + inter.specularColor[1] *= lightColor[1]; + inter.specularColor[2] *= lightColor[2]; + inter.specularColor[3] *= lightColor[3]; + inter.vertexColor = surfaceStage->vertexColor; + } +// jmarshall end break; } }