@@ -39,6 +39,8 @@ static Cvar::Cvar<bool> r_clear( "r_clear", "Clear screen before painting over i
3939Cvar::Cvar<bool > r_drawSky ( " r_drawSky" , " Draw the sky (clear the sky if disabled)" , Cvar::NONE, true );
4040static Cvar::Cvar<int > r_showEntityBounds (
4141 " r_showEntityBounds" , " show bboxes used for culling (1: wireframe; 2: translucent solid)" , Cvar::CHEAT, 0 );
42+ static Cvar::Cvar<bool > r_showDynamicLights (
43+ " r_showDynamicLights" , " visualize dynamic lights with tetrahedrons" , Cvar::CHEAT, false );
4244
4345void GL_Bind ( image_t *image )
4446{
@@ -1301,7 +1303,7 @@ static void RenderDepthTiles()
13011303 {
13021304 RB_PrepareForSamplingDepthMap ();
13031305 }
1304-
1306+
13051307 TransitionMSAAToMain ( GL_DEPTH_BUFFER_BIT );
13061308
13071309 // 1st step
@@ -1317,7 +1319,7 @@ static void RenderDepthTiles()
13171319
13181320 gl_depthtile1Shader->SetUniform_zFar ( zParams );
13191321 gl_depthtile1Shader->SetUniform_DepthMapBindless (
1320- GL_BindToTMU ( 0 , tr.currentDepthImage )
1322+ GL_BindToTMU ( 0 , tr.currentDepthImage )
13211323 );
13221324
13231325 matrix_t ortho;
@@ -1727,7 +1729,7 @@ void RB_CameraPostFX() {
17271729 gl_cameraEffectsShader->SetUniform_Tonemap ( tonemap );
17281730
17291731 gl_cameraEffectsShader->SetUniform_CurrentMapBindless (
1730- GL_BindToTMU ( 0 , tr.currentRenderImage [backEnd.currentMainFBO ] )
1732+ GL_BindToTMU ( 0 , tr.currentRenderImage [backEnd.currentMainFBO ] )
17311733 );
17321734
17331735 if ( r_FXAA.Get () && gl_fxaaShader )
@@ -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 )
@@ -3486,6 +3607,7 @@ const RenderCommand *SetupLightsCommand::ExecuteSelf() const
34863607 default :
34873608 break ;
34883609 }
3610+ VectorNormalize ( buffer[i].direction );
34893611 }
34903612
34913613 glUnmapBuffer ( bufferTarget );
0 commit comments