@@ -37,6 +37,8 @@ static Cvar::Cvar<bool> r_clear( "r_clear", "Clear screen before painting over i
3737Cvar::Cvar<bool > r_drawSky ( " r_drawSky" , " Draw the sky (clear the sky if disabled)" , Cvar::NONE, true );
3838static 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
4143void 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