Files
sbox-public/engine/Sandbox.Engine/Systems/Render/CameraRenderer.cs
s&box team 71f266059a Open source release
This commit imports the C# engine code and game files, excluding C++ source code.

[Source-Commit: ceb3d758046e50faa6258bc3b658a30c97743268]
2025-11-24 09:05:18 +00:00

139 lines
3.6 KiB
C#

using Sandbox.Rendering;
namespace Sandbox;
/// <summary>
/// Camera setup for rendering a View.
/// </summary>
internal ref struct CameraRenderer
{
public CCameraRenderer Native;
int cameraId;
public CameraRenderer( string name, int cameraId )
{
this.cameraId = cameraId;
Native = CCameraRenderer.Create( name, cameraId );
}
public void Dispose()
{
Native.DeleteThis();
}
internal void Configure( SceneCamera camera, ViewSetup config )
{
var _world = camera.World;
var Attributes = new RenderAttributes();
camera.Attributes.MergeTo( Attributes );
if ( _world.IsValid() && !Graphics.IsActive )
{
_world.UpdateObjectsForRendering( camera.Position, camera.ZFar );
}
Color ambientLight = camera.AmbientLightColor;
// update attributes from primary world
if ( camera.World is not null )
{
camera.World.GradientFog.Apply( Attributes );
ambientLight += camera.World.AmbientLightColor;
}
if ( config.AmbientLightTint is Color ambientTint )
{
ambientLight *= ambientTint;
}
if ( config.AmbientLightAdd is Color ambientAdd )
{
ambientLight += ambientAdd;
}
if ( config.GradientFog is GradientFogSetup gradientFog )
{
gradientFog.Apply( Attributes );
}
// The values added to this make IBL lerp value go beyond 0-1, clamp it
ambientLight.a = ambientLight.a.Clamp( 0.0f, 1.0f );
Attributes.Set( "ambientColor", ambientLight );
Attributes.Set( "clearColor", config.ClearColor ?? camera.BackgroundColor );
camera.GatherVolumetricFog( Attributes );
camera.GatherTonemapper( Attributes );
camera.CubemapFog?.Write( Attributes );
// Set clear flags
Attributes.Set( "clearFlags", (int)camera.ClearFlags );
Native.ClearSceneWorlds();
Native.SetRenderAttributes( Attributes.Get() );
Native.ClearRenderTags();
Native.ClearExcludeTags();
foreach ( var tag in camera.RenderTags.TryGetAll() )
{
Native.AddRenderTag( StringToken.FindOrCreate( tag ) );
}
foreach ( var tag in camera.ExcludeTags.TryGetAll() )
{
Native.AddExcludeTag( StringToken.FindOrCreate( tag ) );
}
Native.ViewUniqueId = HashCode.Combine( cameraId, config.ViewHash );
Native.CameraPosition = config.Transform?.Position ?? camera.Position;
Native.CameraRotation = config.Transform?.Rotation.Angles() ?? camera.Rotation.Angles();
Native.ZNear = config.ZNear ?? camera.ZNear;
Native.ZFar = config.ZFar ?? camera.ZFar;
Native.FieldOfView = config.FieldOfView ?? camera.FieldOfView;
Native.Rect = new Rect( 0, 0, camera.Size.x, camera.Size.y );
Native.Viewport = new Vector4( camera.Rect.Left, camera.Rect.Top, Math.Min( camera.Rect.Width, 1 - camera.Rect.Left ), Math.Min( camera.Rect.Height, 1 - camera.Rect.Top ) );
Native.Ortho = camera.Ortho;
Native.ClipSpaceBounds = config.ClipSpaceBounds ?? new Vector4( -1, -1, 1, 1 );
Native.EnablePostprocessing = config.EnablePostprocessing ?? camera.EnablePostProcessing;
Native.EnableEngineOverlays = camera.EnableEngineOverlays;
Native.FlipX = config.FlipX ?? false;
Native.FlipY = config.FlipY ?? false;
var customproj = config.ProjectionMatrix ?? camera.CustomProjectionMatrix;
if ( customproj.HasValue )
{
Native.HasOverrideProjection = true;
Native.OverrideProjection = customproj.Value;
}
else
{
Native.HasOverrideProjection = false;
}
if ( Native.Ortho )
{
Native.OrthoSize = camera.OrthoHeight / camera.Size.y;
}
//
// add worlds
//
if ( _world is not null )
{
Native.AddSceneWorld( _world );
}
foreach ( var world in camera.Worlds )
{
if ( world is null ) continue;
if ( world == _world ) continue;
Native.AddSceneWorld( world );
}
}
}