diff --git a/neo/renderer/RenderLog.cpp b/neo/renderer/RenderLog.cpp index 70d60b18..3fd55bc7 100644 --- a/neo/renderer/RenderLog.cpp +++ b/neo/renderer/RenderLog.cpp @@ -259,6 +259,7 @@ void idRenderLog::StartFrame() indentString[0] = '\0'; activeLevel = r_logLevel.GetInteger(); + /* struct tm* newtime; time_t aclock; @@ -268,6 +269,7 @@ void idRenderLog::StartFrame() sprintf( qpath, "renderlogPC_%04i.txt", r_logFile.GetInteger() ); //idStr finalPath = fileSystem->RelativePathToOSPath( qpath ); sprintf( ospath, "%s", qpath ); + */ /* for ( int i = 0; i < 9999 ; i++ ) { char qpath[128]; diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index 4a9a3fca..b69925d3 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -188,6 +188,7 @@ idCVar r_showTextureVectors( "r_showTextureVectors", "0", CVAR_RENDERER | CVAR_F idCVar r_showOverDraw( "r_showOverDraw", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = geometry overdraw, 2 = light interaction overdraw, 3 = geometry and light interaction overdraw", 0, 3, idCmdSystem::ArgCompletion_Integer<0, 3> ); // RB begin idCVar r_showShadowMaps( "r_showShadowMaps", "0", CVAR_RENDERER | CVAR_BOOL, "" ); +idCVar r_showShadowMapLODs( "r_showShadowMapLODs", "0", CVAR_RENDERER | CVAR_INTEGER, "" ); // RB end idCVar r_useEntityCallbacks( "r_useEntityCallbacks", "1", CVAR_RENDERER | CVAR_BOOL, "if 0, issue the callback immediately at update time, rather than defering" ); @@ -221,6 +222,8 @@ idCVar r_shadowMapBiasScale( "r_shadowMapBiasScale", "0.0001", CVAR_RENDERER | C idCVar r_shadowMapSamples( "r_shadowMapSamples", "16", CVAR_RENDERER | CVAR_INTEGER, "0, 1, 4, or 16" ); idCVar r_shadowMapSplits( "r_shadowMapSplits", "3", CVAR_RENDERER | CVAR_INTEGER, "number of splits for cascaded shadow mapping with parallel lights", 0, 4 ); idCVar r_shadowMapSplitWeight( "r_shadowMapSplitWeight", "0.9", CVAR_RENDERER | CVAR_FLOAT, "" ); +idCVar r_shadowMapLodScale( "r_shadowMapLodScale", "0.8", CVAR_RENDERER | CVAR_FLOAT, "" ); +idCVar r_shadowMapLodBias( "r_shadowMapLodBias", "0", CVAR_RENDERER | CVAR_INTEGER, "" ); // RB end diff --git a/neo/renderer/tr_backend_rendertools.cpp b/neo/renderer/tr_backend_rendertools.cpp index e78c2f71..af9ca2dc 100644 --- a/neo/renderer/tr_backend_rendertools.cpp +++ b/neo/renderer/tr_backend_rendertools.cpp @@ -36,6 +36,8 @@ If you have questions concerning this license or the applicable additional terms idCVar r_showCenterOfProjection( "r_showCenterOfProjection", "0", CVAR_RENDERER | CVAR_BOOL, "Draw a cross to show the center of projection" ); idCVar r_showLines( "r_showLines", "0", CVAR_RENDERER | CVAR_INTEGER, "1 = draw alternate horizontal lines, 2 = draw alternate vertical lines" ); + + #define MAX_DEBUG_LINES 16384 typedef struct debugLine_s @@ -1809,10 +1811,6 @@ static void RB_ShowLights() GL_State( GLS_DEFAULT ); - // we use the 'vLight->invProjectMVPMatrix' -// glMatrixMode( GL_PROJECTION ); -// glLoadIdentity(); - globalImages->BindNull(); renderProgManager.BindShader_Color(); @@ -1867,14 +1865,107 @@ static void RB_ShowLights() } common->Printf( " = %i total\n", count ); - - // set back the default projection matrix - glMatrixMode( GL_PROJECTION ); - glLoadMatrixf( backEnd.viewDef->projectionMatrix ); - glMatrixMode( GL_MODELVIEW ); - glLoadIdentity(); } +// RB begin +static void RB_ShowShadowMapLODs() +{ + if( !r_showShadowMapLODs.GetInteger() ) + { + return; + } + + GL_State( GLS_DEFAULT ); + + globalImages->BindNull(); + + renderProgManager.BindShader_Color(); + + GL_Cull( CT_TWO_SIDED ); + + common->Printf( "volumes: " ); // FIXME: not in back end! + + int count = 0; + for( viewLight_t* vLight = backEnd.viewDef->viewLights; vLight != NULL; vLight = vLight->next ) + { +#if 0 + const idMaterial* lightShader = vLight->lightShader; + + if( lightShader->IsFogLight() ) + { + continue; + } + + if( lightShader->IsBlendLight() ) + { + continue; + } +#endif + + count++; + + // depth buffered planes + if( r_showShadowMapLODs.GetInteger() >= 1 ) + { + GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHMASK ); + + idVec4 c; + if( vLight->shadowLOD == 0 ) + { + c = colorRed; + } + else if( vLight->shadowLOD == 1 ) + { + c = colorGreen; + } + else if( vLight->shadowLOD == 2 ) + { + c = colorBlue; + } + else if( vLight->shadowLOD == 3 ) + { + c = colorYellow; + } + else if( vLight->shadowLOD == 4 ) + { + c = colorMagenta; + } + else if( vLight->shadowLOD == 5 ) + { + c = colorCyan; + } + else + { + c = colorMdGrey; + } + + c[3] = 0.25f; + GL_Color( c ); + + idRenderMatrix invProjectMVPMatrix; + idRenderMatrix::Multiply( backEnd.viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); + RB_SetMVP( invProjectMVPMatrix ); + RB_DrawElementsWithCounters( &backEnd.zeroOneCubeSurface ); + } + + // non-hidden lines + if( r_showShadowMapLODs.GetInteger() >= 2 ) + { + GL_State( GLS_DEPTHFUNC_ALWAYS | GLS_POLYMODE_LINE | GLS_DEPTHMASK ); + GL_Color( 1.0f, 1.0f, 1.0f ); + idRenderMatrix invProjectMVPMatrix; + idRenderMatrix::Multiply( backEnd.viewDef->worldSpace.mvp, vLight->inverseBaseLightProject, invProjectMVPMatrix ); + RB_SetMVP( invProjectMVPMatrix ); + RB_DrawElementsWithCounters( &backEnd.zeroOneCubeSurface ); + } + + common->Printf( "%i ", vLight->lightDef->index ); + } + + common->Printf( " = %i total\n", count ); +} +// RB end + /* ===================== RB_ShowPortals @@ -3119,6 +3210,7 @@ void RB_RenderDebugTools( drawSurf_t** drawSurfs, int numDrawSurfs ) RB_ShowViewEntitys( backEnd.viewDef->viewEntitys ); RB_ShowLights(); // RB begin + RB_ShowShadowMapLODs(); RB_ShowShadowMaps(); // RB end diff --git a/neo/renderer/tr_frontend_addlights.cpp b/neo/renderer/tr_frontend_addlights.cpp index cd9fa4c8..70051c2d 100644 --- a/neo/renderer/tr_frontend_addlights.cpp +++ b/neo/renderer/tr_frontend_addlights.cpp @@ -221,6 +221,8 @@ static void R_AddSingleLight( viewLight_t* vLight ) vLight->lightShader = light->lightShader; vLight->shaderRegisters = lightRegs; + const bool lightCastsShadows = light->LightCastsShadows(); + if( r_useLightScissors.GetInteger() != 0 ) { // Calculate the matrix that projects the zero-to-one cube to exactly cover the @@ -262,6 +264,77 @@ static void R_AddSingleLight( viewLight_t* vLight ) vLight->scissorRect.Intersect( lightScissorRect ); vLight->scissorRect.zmin = projected[0][2]; vLight->scissorRect.zmax = projected[1][2]; + + // RB: calculate shadow LOD similar to Q3A .md3 LOD code + vLight->shadowLOD = -1; + + if( r_useShadowMapping.GetBool() && lightCastsShadows ) + { + float flod, lodscale; + float projectedRadius; + int lod; + int numLods; + + numLods = 5; + + // compute projected bounding sphere + // and use that as a criteria for selecting LOD + idVec3 center = projected.GetCenter(); + projectedRadius = projected.GetRadius( center ); + if( projectedRadius > 1.0f ) + { + projectedRadius = 1.0f; + } + + if( projectedRadius != 0 ) + { + lodscale = r_shadowMapLodScale.GetFloat(); + + if( lodscale > 20 ) + lodscale = 20; + + flod = 1.0f - projectedRadius * lodscale; + } + else + { + // object intersects near view plane, e.g. view weapon + flod = 0; + } + + flod *= numLods; + lod = idMath::Ftoi( flod ); + + if( lod < 0 ) + { + lod = 0; + } + else if( lod >= numLods ) + { + //lod = numLods - 1; + } + + lod += r_shadowMapLodBias.GetInteger(); + + if( lod < 0 ) + { + lod = 0; + } + + if( lod >= numLods ) + { + // don't draw any shadow + lod = -1; + + //lod = numLods - 1; + } + + // never give ultra quality for point lights + if( lod == 0 && light->parms.pointLight ) + lod = 1; + + vLight->shadowLOD = lod; + } + // RB end } // this one stays on the list @@ -277,7 +350,6 @@ static void R_AddSingleLight( viewLight_t* vLight ) // this bool array will be set true whenever the entity will visibly interact with the light vLight->entityInteractionState = ( byte* )R_ClearedFrameAlloc( light->world->entityDefs.Num() * sizeof( vLight->entityInteractionState[0] ), FRAME_ALLOC_INTERACTION_STATE ); - const bool lightCastsShadows = light->LightCastsShadows(); idInteraction** const interactionTableRow = light->world->interactionTable + light->index * light->world->interactionTableWidth; for( areaReference_t* lref = light->references; lref != NULL; lref = lref->ownerNext ) diff --git a/neo/renderer/tr_local.h b/neo/renderer/tr_local.h index 6bd01251..ce684ee2 100644 --- a/neo/renderer/tr_local.h +++ b/neo/renderer/tr_local.h @@ -323,6 +323,7 @@ struct viewLight_t bool pointLight; // otherwise a projection light (should probably invert the sense of this, because points are way more common) bool parallel; // lightCenter gives the direction to the light at infinity idVec3 lightCenter; // offset the lighting direction for shading and + int shadowLOD; // level of detail for shadowmap selection // RB end idRenderMatrix inverseBaseLightProject; // the matrix for deforming the 'zeroOneCubeModel' to exactly cover the light volume in world space const idMaterial* lightShader; // light shader used by backend @@ -1022,6 +1023,7 @@ extern idCVar r_showSkel; // draw the skeleton when model animates extern idCVar r_showOverDraw; // show overdraw // RB begin extern idCVar r_showShadowMaps; +extern idCVar r_showShadowMapLODs; // RB end extern idCVar r_jointNameScale; // size of joint names when r_showskel is set to 1 extern idCVar r_jointNameOffset; // offset of joint names when r_showskel is set to 1 @@ -1061,6 +1063,8 @@ extern idCVar r_shadowMapBiasScale; extern idCVar r_shadowMapSamples; extern idCVar r_shadowMapSplits; extern idCVar r_shadowMapSplitWeight; +extern idCVar r_shadowMapLodScale; +extern idCVar r_shadowMapLodBias; // RB end /*