Skip to content

Commit d9e38db

Browse files
committed
lights: Add r_showDynamicLights for dynamic light debugging
This adds a debug cvar to draw a tetrahedron (similar to what you get when yuou enable r_showSkeleton) in the direction of a spot light or in 6 directions for an omnilight that is proportional to the radius of the light. This makes it easier to visualize dynamic lights and see what they should be doing, what direction they are intended to point, etc. Also, while here, normalize spotlight direction.
1 parent 1672200 commit d9e38db

1 file changed

Lines changed: 125 additions & 3 deletions

File tree

src/engine/renderer/tr_backend.cpp

Lines changed: 125 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ static Cvar::Cvar<bool> r_clear( "r_clear", "Clear screen before painting over i
3737
Cvar::Cvar<bool> r_drawSky( "r_drawSky", "Draw the sky (clear the sky if disabled)", Cvar::NONE, true );
3838
static Cvar::Cvar<int> r_showEntityBounds(
3939
"r_showEntityBounds", "show bboxes used for culling (1: wireframe; 2: translucent solid)", Cvar::CHEAT, 0);
40+
static Cvar::Cvar<bool> r_showDynamicLights(
41+
"r_showDynamicLights", "visualize dynamic lights with tetrahedrons", Cvar::CHEAT, false );
4042

4143
void GL_Bind( image_t *image )
4244
{
@@ -1303,7 +1305,7 @@ static void RenderDepthTiles()
13031305
{
13041306
RB_PrepareForSamplingDepthMap();
13051307
}
1306-
1308+
13071309
TransitionMSAAToMain( GL_DEPTH_BUFFER_BIT );
13081310

13091311
// 1st step
@@ -1319,7 +1321,7 @@ static void RenderDepthTiles()
13191321

13201322
gl_depthtile1Shader->SetUniform_zFar( zParams );
13211323
gl_depthtile1Shader->SetUniform_DepthMapBindless(
1322-
GL_BindToTMU( 0, tr.currentDepthImage )
1324+
GL_BindToTMU( 0, tr.currentDepthImage )
13231325
);
13241326

13251327
matrix_t ortho;
@@ -1753,7 +1755,7 @@ void RB_CameraPostFX() {
17531755
// tr.mainFBO
17541756
R_BindNullFBO();
17551757
gl_cameraEffectsShader->SetUniform_CurrentMapBindless(
1756-
GL_BindToTMU( 0, tr.currentRenderImage[backEnd.currentMainFBO] )
1758+
GL_BindToTMU( 0, tr.currentRenderImage[backEnd.currentMainFBO] )
17571759
);
17581760

17591761
if ( glConfig.colorGrading ) {
@@ -2312,6 +2314,125 @@ static void RB_RenderDebugUtils()
23122314
Tess_End();
23132315
}
23142316

2317+
if ( r_showDynamicLights.Get() && backEnd.refdef.numLights > 0 )
2318+
{
2319+
gl_genericShader->SetVertexSkinning( false );
2320+
gl_genericShader->SetVertexAnimation( false );
2321+
gl_genericShader->SetTCGenEnvironment( false );
2322+
gl_genericShader->SetTCGenLightmap( false );
2323+
gl_genericShader->SetDepthFade( false );
2324+
gl_genericShader->SetDeform( 0 );
2325+
gl_genericShader->BindProgram();
2326+
2327+
GL_State( GLS_DEFAULT );
2328+
GL_Cull( cullType_t::CT_TWO_SIDED );
2329+
2330+
// set uniforms
2331+
gl_genericShader->SetUniform_AlphaTest( GLS_ATEST_NONE );
2332+
SetUniform_ColorModulateColorGen( gl_genericShader, colorGen_t::CGEN_VERTEX,
2333+
alphaGen_t::AGEN_VERTEX );
2334+
SetUniform_Color( gl_genericShader, Color::Black );
2335+
gl_genericShader->SetUniform_ColorMapBindless( GL_BindToTMU( 0, tr.whiteImage ) );
2336+
gl_genericShader->SetUniform_TextureMatrix( matrixIdentity );
2337+
2338+
// set up the transformation matrix
2339+
backEnd.orientation = backEnd.viewParms.world;
2340+
GL_LoadModelViewMatrix( backEnd.orientation.modelViewMatrix );
2341+
gl_genericShader->SetUniform_ModelViewProjectionMatrix(
2342+
glState.modelViewProjectionMatrix[ glState.stackIndex ] );
2343+
2344+
Tess_Begin( Tess_StageIteratorDebug, nullptr, true, -1, 0 );
2345+
GL_CheckErrors();
2346+
2347+
const refLight_t *lights = backEnd.refdef.lights;
2348+
for ( int i = 0; i < backEnd.refdef.numLights; ++i )
2349+
{
2350+
const refLight_t &light = lights[ i ];
2351+
// We can't really visualize directional lights since they don't
2352+
// have an origin or a radius.
2353+
if ( light.rlType >= refLightType_t::RL_DIRECTIONAL )
2354+
{
2355+
continue;
2356+
}
2357+
2358+
vec3_t baseOrigin;
2359+
VectorCopy( light.origin, baseOrigin );
2360+
2361+
if ( light.radius <= 0.0f )
2362+
{
2363+
Log::Warn( "Light with index %d has no radius", i );
2364+
}
2365+
2366+
auto addArrow = [ & ]( const vec3_t dirInput, const Color::Color &arrowColor )
2367+
{
2368+
vec3_t dir;
2369+
VectorCopy( dirInput, dir );
2370+
if ( VectorNormalize( dir ) == 0.0f )
2371+
{
2372+
VectorSet( dir, 0.0f, 0.0f, 1.0f );
2373+
}
2374+
// idk why we need to negate here, but the arrow points the wrong way otherwise.
2375+
VectorNegate( dir, dir );
2376+
2377+
vec3_t tip;
2378+
VectorMA( baseOrigin, light.radius, dir, tip );
2379+
2380+
vec3_t tmp;
2381+
vec3_t tmp2;
2382+
vec3_t tmp3;
2383+
PerpendicularVector( tmp, dir );
2384+
VectorScale( tmp, light.radius * 0.2f, tmp2 );
2385+
VectorMA( tmp2, light.radius * 0.3f, dir, tmp2 );
2386+
2387+
vec4_t tetraVerts[ 4 ];
2388+
for ( int k = 0; k < 3; k++ )
2389+
{
2390+
RotatePointAroundVector( tmp3, dir, tmp2, k * 120.0f );
2391+
VectorAdd( tmp3, baseOrigin, tmp3 );
2392+
VectorCopy( tmp3, tetraVerts[ k ] );
2393+
tetraVerts[ k ][ 3 ] = 1.0f;
2394+
}
2395+
2396+
VectorCopy( baseOrigin, tetraVerts[ 3 ] );
2397+
tetraVerts[ 3 ][ 3 ] = 1.0f;
2398+
Tess_AddTetrahedron( tetraVerts, arrowColor );
2399+
2400+
VectorCopy( tip, tetraVerts[ 3 ] );
2401+
tetraVerts[ 3 ][ 3 ] = 1.0f;
2402+
2403+
Tess_AddTetrahedron( tetraVerts, arrowColor );
2404+
};
2405+
2406+
Color::Color color;
2407+
switch ( light.rlType )
2408+
{
2409+
case refLightType_t::RL_PROJ:
2410+
color = Color::LtGrey;
2411+
addArrow( light.projTarget, color );
2412+
break;
2413+
default:
2414+
color = Color::MdGrey;
2415+
{
2416+
static const vec3_t kOmniDirs[ 6 ] = {
2417+
{ 1.0f, 0.0f, 0.0f },
2418+
{ -1.0f, 0.0f, 0.0f },
2419+
{ 0.0f, 1.0f, 0.0f },
2420+
{ 0.0f, -1.0f, 0.0f },
2421+
{ 0.0f, 0.0f, 1.0f },
2422+
{ 0.0f, 0.0f, -1.0f}
2423+
};
2424+
for ( int dirIndex = 0; dirIndex < 6; ++dirIndex )
2425+
{
2426+
addArrow( kOmniDirs[ dirIndex ], color );
2427+
}
2428+
}
2429+
break;
2430+
}
2431+
}
2432+
2433+
Tess_End();
2434+
}
2435+
23152436
if ( r_showBspNodes->integer )
23162437
{
23172438
if ( ( backEnd.refdef.rdflags & ( RDF_NOWORLDMODEL ) ) || !tr.world )
@@ -3489,6 +3610,7 @@ const RenderCommand *SetupLightsCommand::ExecuteSelf( ) const
34893610
default:
34903611
break;
34913612
}
3613+
VectorNormalize( buffer[i].direction );
34923614
}
34933615

34943616
glUnmapBuffer( bufferTarget );

0 commit comments

Comments
 (0)