115 lines
3.3 KiB
C++
115 lines
3.3 KiB
C++
// =============================================
|
|
// 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 <EASTL/vector.h>
|
|
|
|
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;
|
|
|
|
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<u16>;
|
|
|
|
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<Buffer> 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::ResourceManager *m_ResourceManager;
|
|
systems::CommitManager *m_CommitManager;
|
|
eastl::vector<Light> 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<u16>
|
|
constexpr static u16 UPDATE_REQUIRED_BIT = 1;
|
|
constexpr static u16 CAPACITY_MASK = static_cast<u16>(~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::ResourceManager *resourceManager, systems::CommitManager *commitManager);
|
|
LightManager(LightManager &&other) noexcept;
|
|
LightManager &operator=(LightManager &&other) noexcept;
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(LightManager);
|
|
}; |