@@ -366,7 +366,7 @@ static void RE_RenderCubeProbeFace( const refdef_t* originalRefdef ) {
366366 Log::Warn ( " Cube probe face out of range! (%i/%i)" , probeID, tr.cubeProbes .size () );
367367 return ;
368368 }
369-
369+
370370 refdef_t refdef{};
371371 const int faceID = globalID % 6 ;
372372
@@ -487,6 +487,59 @@ static void RE_RenderCubeProbeFace( const refdef_t* originalRefdef ) {
487487
488488}
489489
490+ // Debug spot light (projected) injection
491+ static Cvar::Cvar<bool > r_debugProjLight ( " r_debugProjLight" , " inject a directional sun light each frame" , Cvar::CHEAT, false );
492+ static Cvar::Range<Cvar::Cvar<float >> r_debugProjLightYaw ( " r_debugProjLightYaw" , " debug projected yaw in degrees" , Cvar::NONE, 45 .0f , -360 .0f , 360 .0f );
493+ static Cvar::Range<Cvar::Cvar<float >> r_debugProjLightPitch ( " r_debugProjLightPitch" , " debug projected pitch in degrees" , Cvar::NONE, -60 .0f , -89 .0f , 89 .0f );
494+ static Cvar::Cvar<float > r_debugProjLightRadius ( " r_debugProjLightRadius" , " debug projected radius (size)" , Cvar::NONE, 100 .0f );
495+ static Cvar::Range<Cvar::Cvar<float >> r_debugProjLightR ( " r_debugProjLightR" , " debug projected color R" , Cvar::NONE, 1 .0f , 0 .0f , 1 .0f );
496+ static Cvar::Range<Cvar::Cvar<float >> r_debugProjLightG ( " r_debugProjLightG" , " debug projected color G" , Cvar::NONE, 1 .0f , 0 .0f , 1 .0f );
497+ static Cvar::Range<Cvar::Cvar<float >> r_debugProjLightB ( " r_debugProjLightB" , " debug projected color B" , Cvar::NONE, 1 .0f , 0 .0f , 1 .0f );
498+ static Cvar::Cvar<float > r_debugProjLightOriginX ( " r_debugProjLightOriginX" , " debug projected origin X" , Cvar::NONE, 0 .0f );
499+ static Cvar::Cvar<float > r_debugProjLightOriginY ( " r_debugProjLightOriginY" , " debug projected origin Y" , Cvar::NONE, 0 .0f );
500+ static Cvar::Cvar<float > r_debugProjLightOriginZ ( " r_debugProjLightOriginZ" , " debug projected origin Z" , Cvar::NONE, 0 .0f );
501+ static Cvar::Cvar<float > r_debugProjLightAngle ( " r_debugProjLightAngle" , " debug projected angle" ,
502+ Cvar::NONE, 60 .0f );
503+
504+ static void AddDebugProjectedLight ()
505+ {
506+ if ( r_numLights >= MAX_REF_LIGHTS )
507+ {
508+ return ;
509+ }
510+ refLight_t *light = &backEndData[ tr.smpFrame ]->lights [ r_numLights++ ];
511+ *light = {};
512+ light->rlType = refLightType_t::RL_PROJ;
513+ // Compute direction from yaw/pitch cvars (in degrees)
514+ float yaw = DEG2RAD ( r_debugProjLightYaw.Get () );
515+ float pitch = DEG2RAD ( r_debugProjLightPitch.Get () );
516+ // Right-handed: X forward, Y left, Z up. Direction vector components:
517+ light->projTarget [ 0 ] = cosf ( pitch ) * cosf ( yaw );
518+ light->projTarget [ 1 ] = cosf ( pitch ) * sinf ( yaw );
519+ light->projTarget [ 2 ] = sinf ( pitch );
520+
521+ vec3_t dir;
522+ VectorCopy ( light->projTarget , dir );
523+ VectorNormalize ( dir );
524+
525+ PerpendicularVector ( light->projUp , dir );
526+
527+ float upLen = VectorLength ( light->projUp );
528+ float tgtLen = VectorLength ( light->projTarget );
529+
530+ VectorScale ( light->projUp , tanf ( DEG2RAD ( r_debugProjLightAngle.Get () ) ) / upLen / tgtLen,
531+ light->projUp );
532+
533+ // Set properties
534+ light->color [ 0 ] = r_debugProjLightR.Get ();
535+ light->color [ 1 ] = r_debugProjLightG.Get ();
536+ light->color [ 2 ] = r_debugProjLightB.Get ();
537+ light->radius = r_debugProjLightRadius.Get ();
538+ light->origin [ 0 ] = r_debugProjLightOriginX.Get ();
539+ light->origin [ 1 ] = r_debugProjLightOriginY.Get ();
540+ light->origin [ 2 ] = r_debugProjLightOriginZ.Get ();
541+ }
542+
490543/*
491544@@@@@@@@@@@@@@@@@@@@@
492545RE_RenderScene
@@ -562,6 +615,11 @@ void RE_RenderScene( const refdef_t *fd )
562615 }
563616 }
564617
618+ if ( r_debugProjLight.Get () )
619+ {
620+ AddDebugProjectedLight ();
621+ }
622+
565623 // derived info
566624 if ( r_forceRendererTime.Get () >= 0 ) {
567625 tr.refdef .floatTime = float ( double ( r_forceRendererTime.Get () ) * 0.001 );
0 commit comments