// ============================================= // Aster: light_manager.h // Copyright (c) 2020-2025 Anish Bhobe // ============================================= #pragma once #include "aster/aster.h" // TODO: Separate files so you only import handles. #include "aster/core/buffer.h" #include "aster/systems/resource.h" #include namespace systems { class RenderingDevice; } namespace systems { class ResourceManager; class CommitManager; } // namespace systems struct DirectionalLight { vec3 m_Direction; u32 m_UnusedPadding0_; u32 m_Color_; // LSB is used for flags. (R G B Flags) f32 m_Intensity; }; struct PointLight { vec3 m_Position; f32 m_Range; u32 m_Color_; // LSB is used for flags. (R G B Flags) f32 m_Intensity; }; struct LightHandle { u8 m_Type; u8 m_Generation; u16 m_Index; }; struct Light { union { vec3 um_Position; vec3 um_Direction; }; f32 m_Range; // < 0.0 for invalid u32 m_Color_; // LSB is used for flags. (R G B Flags) f32 m_Intensity; u32 m_Pad0; u32 m_Pad1; constexpr static u32 MAX_GEN = 0x40; constexpr static u32 GEN_MASK = MAX_GEN - 1; constexpr static u32 TYPE_MASK = 0xC0; constexpr static u32 TYPE_INVALID = 0x0; constexpr static u32 TYPE_DIRECTIONAL = 1 << 6; constexpr static u32 TYPE_POINT = 2 << 6; constexpr static u32 TYPE_SPOT = 3 << 6; // Currently Unused constexpr static u32 COLOR_MASK = ~(GEN_MASK | TYPE_MASK); }; struct LightManager { constexpr static u16 MAX_LIGHTS = MaxValue; struct LightMetaInfo { // The number of directional lights is relatively low (1 - 2) and will almost never change in a scene. // We can use that with Offset = 0, and point light at further offsets. // This way we don't need to move point lights often. systems::ResId m_LightBuffer; // 04 04 u16 m_PointLightMaxCount; // 02 06 u16 m_PointLightOffset; // 02 08 u16 m_DirectionalLightMaxCount; // 02 10 u16 m_UnusedPadding0 = 0; // 02 12 }; systems::RenderingDevice *m_Device; eastl::vector m_Lights; // We don't need a Directional Light free list. We will just brute force iterate. u16 m_DirectionalLightCount; // TODO: A point light free list. We will brute force until we have a lot (100+) of point lights. u16 m_PointLightCount; LightMetaInfo m_MetaInfo; // Using lower bit for flags. Use CAPACITY_MASK for value. u16 m_GpuBufferCapacity_; // Using lower bit. Capacity can be directly a multiple of 2 // Thus, range is up to MaxValue constexpr static u16 UPDATE_REQUIRED_BIT = 1; constexpr static u16 CAPACITY_MASK = static_cast(~UPDATE_REQUIRED_BIT); LightHandle AddDirectional(const vec3 &direction, const vec3 &color, f32 intensity); LightHandle AddPoint(const vec3 &position, const vec3 &color, f32 radius, f32 intensity); void Update(); void RemoveLight(LightHandle handle); ~LightManager() = default; LightManager(systems::RenderingDevice &device); LightManager(LightManager &&other) noexcept; LightManager &operator=(LightManager &&other) noexcept; DISALLOW_COPY_AND_ASSIGN(LightManager); };