#pragma once #include #include #include #include "DataSpec/DNAMP1/CMDLMaterials.hpp" #include "Runtime/Graphics/CGraphics.hpp" #include #include #include #define URDE_MAX_LIGHTS 8 namespace hecl::Backend { class ShaderTag; } // namespace hecl::Backend namespace urde { class CLight; struct CModelFlags; struct CBooSurface; class CBooModel; enum class EExtendedShader : uint8_t { Flat, Lighting, Thermal, ForcedAlpha, ForcedAdditive, SolidColor, SolidColorAdditive, SolidColorFrontfaceCullLEqualAlphaOnly, SolidColorFrontfaceCullAlwaysAlphaOnly, // No Z-write or test SolidColorBackfaceCullLEqualAlphaOnly, SolidColorBackfaceCullGreaterAlphaOnly, // No Z-write MorphBallShadow, WorldShadow, ForcedAlphaNoCull, ForcedAdditiveNoCull, ForcedAlphaNoZWrite, ForcedAdditiveNoZWrite, ForcedAlphaNoCullNoZWrite, ForcedAdditiveNoCullNoZWrite, DepthGEqualNoZWrite, Disintegrate, ForcedAdditiveNoZWriteDepthGreater, ThermalCold, LightingAlphaWrite, LightingAlphaWriteNoZTestNoZWrite, LightingCubeReflection, LightingCubeReflectionWorldShadow, MAX }; enum class EShaderType : uint8_t { DiffuseOnly, Normal, Dynamic, DynamicAlpha, DynamicCharacter }; enum class EPostType : uint8_t { Normal, ThermalHot, ThermalCold, Solid, MBShadow, Disintegrate }; struct ModelInstance; class CModelShaders { friend class CModel; public: template struct VertData { hsh::float3 posIn; hsh::float3 normIn; // FIXME: compiler bug? // [[no_unique_address]] hsh::array colIn; [[no_unique_address]] hsh::array uvIn; [[no_unique_address]] hsh::array weightIn; }; static_assert(sizeof(VertData<0, 0, 0>) == 24, "VertData size incorrect"); static_assert(sizeof(VertData<0, 1, 0>) == 32, "VertData size incorrect"); static_assert(sizeof(VertData<0, 2, 0>) == 40, "VertData size incorrect"); static_assert(sizeof(VertData<0, 1, 1>) == 48, "VertData size incorrect"); template struct VertUniform { hsh::array objs [[no_unique_address]]; hsh::array objsInv [[no_unique_address]]; hsh::float4x4 mv; hsh::float4x4 mvInv; hsh::float4x4 proj; }; static_assert(sizeof(VertUniform<0>) == 192, "VertUniform size incorrect"); static_assert(sizeof(VertUniform<1>) == 320, "VertUniform size incorrect"); struct TCGMatrix { hsh::float4x4 mtx; hsh::float4x4 postMtx; }; using TCGMatrixUniform = std::array; struct ReflectMtx { hsh::float4x4 indMtx; hsh::float4x4 reflectMtx; float reflectAlpha; }; struct Light { alignas(16) hsh::float3 pos; alignas(16) hsh::float3 dir; alignas(16) hsh::float4 color; alignas(16) hsh::float3 linAtt{1.f, 0.f, 0.f}; alignas(16) hsh::float3 angAtt{1.f, 0.f, 0.f}; }; struct FragmentUniform { std::array lights; hsh::float4 ambient; hsh::float4 lightmapMul; hsh::float4 flagsColor; CGraphics::CFogState fog; void ActivateLights(const std::vector& lts); }; static void SetCurrent(hsh::binding& binding, const CModelFlags& modelFlags, const CBooModel& model, const ModelInstance& inst, const CBooSurface& surface); using Material = DataSpec::DNAMP1::HMDLMaterialSet::Material; }; struct ModelInstance { hsh::dynamic_owner> m_fragmentUniform; std::vector>> m_tcgUniforms; std::vector>> m_reflectUniforms; std::vector> m_geometryUniforms; std::vector m_shaderDataBindings; mutable hsh::dynamic_owner m_dynamicVbo; hsh::vertex_buffer_typeless GetBooVBO(const CBooModel& model) const; }; } // namespace urde