#pragma once #include #include #include "Runtime/CToken.hpp" #include "Runtime/Graphics/CTexture.hpp" #include "Runtime/Graphics/Shaders/CModelShaders.hpp" #include "Runtime/World/CFluidPlaneManager.hpp" #include "Shaders/shader_CFluidPlaneShader.hpp" //#include #include #include #include #include namespace metaforce { class CFluidPlaneShader { public: struct Vertex { zeus::CVector3f m_pos; zeus::CVector3f m_norm; zeus::CVector3f m_binorm; zeus::CVector3f m_tangent; zeus::CColor m_color; Vertex() = default; Vertex(const zeus::CVector3f& position) : m_pos(position) {} Vertex(const zeus::CVector3f& position, const zeus::CColor& color) : m_pos(position), m_color(color) {} Vertex(const zeus::CVector3f& position, const zeus::CVector3f& normal, const zeus::CColor& color) : m_pos(position), m_norm(normal), m_color(color) {} Vertex(const zeus::CVector3f& position, const zeus::CVector3f& normal, const zeus::CVector3f& binormal, const zeus::CVector3f& tangent, const zeus::CColor& color) : m_pos(position), m_norm(normal), m_binorm(binormal), m_tangent(tangent), m_color(color) {} }; struct PatchVertex { zeus::CVector4f m_pos; std::array m_outerLevels{}; std::array m_innerLevels{}; }; struct RenderSetupInfo { std::array texMtxs; zeus::CMatrix4f normMtx; float indScale = 1.f; std::array kColors; std::vector lights; }; private: // struct ShaderPair { // boo::ObjToken m_regular; // boo::ObjToken m_tessellation; // void reset() { // m_regular.reset(); // m_tessellation.reset(); // } // }; // // struct BindingPair { // boo::ObjToken m_regular; // boo::ObjToken m_tessellation; // }; // class Cache { // std::array m_cache{}; // std::array m_doorCache{}; // ShaderPair& CacheSlot(const SFluidPlaneShaderInfo& info, int i) { return m_cache[i]; } // ShaderPair& CacheSlot(const SFluidPlaneDoorShaderInfo& info, int i) { return m_doorCache[i]; } // static u16 MakeCacheKey(const SFluidPlaneShaderInfo& info); // static u16 MakeCacheKey(const SFluidPlaneDoorShaderInfo& info); // // public: // template // ShaderPair GetOrBuildShader(const T& info); // void Clear(); // }; // static Cache _cache; struct Ripple { zeus::CVector4f center; // time, distFalloff zeus::CVector4f params; // amplitude, lookupPhase, lookupTime }; struct Uniform { zeus::CMatrix4f m_mv; zeus::CMatrix4f m_mvNorm; zeus::CMatrix4f m_proj; std::array m_texMtxs; std::array m_ripple; zeus::CVector4f m_colorMul; std::array m_pad; // rippleNormResolution, Pad out to 1280 bytes CModelShaders::LightingUniform m_lighting; zeus::CVector3f m_pad2; // Pad out to 768 bytes, also holds ind scale }; TLockedToken m_patternTex1; TLockedToken m_patternTex2; TLockedToken m_colorTex; TLockedToken m_bumpMap; TLockedToken m_envMap; TLockedToken m_envBumpMap; TLockedToken m_lightmap; std::shared_ptr m_rippleMap; // boo::ObjToken m_vbo; // boo::ObjToken m_pvbo; // boo::ObjToken m_uniBuf; // ShaderPair m_pipelines; // BindingPair m_dataBind; int m_lastBind = -1; //#if BOO_HAS_GL // static ShaderPair BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info); // static ShaderPair BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info); // BindingPair BuildBinding(boo::GLDataFactory::Context& ctx, const ShaderPair& pipeline); //#endif //#if _WIN32 // static ShaderPair BuildShader(boo::D3D11DataFactory::Context& ctx, const SFluidPlaneShaderInfo& info); // static ShaderPair BuildShader(boo::D3D11DataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info); // BindingPair BuildBinding(boo::D3D11DataFactory::Context& ctx, const ShaderPair& pipeline); //#endif //#if BOO_HAS_METAL // static ShaderPair BuildShader(boo::MetalDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info); // static ShaderPair BuildShader(boo::MetalDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info); // BindingPair BuildBinding(boo::MetalDataFactory::Context& ctx, const ShaderPair& pipeline); //#endif //#if BOO_HAS_VULKAN // static ShaderPair BuildShader(boo::VulkanDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info); // static ShaderPair BuildShader(boo::VulkanDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info); // BindingPair BuildBinding(boo::VulkanDataFactory::Context& ctx, const ShaderPair& pipeline); //#endif template static void _Shutdown(); void PrepareBinding(u32 maxVertCount); public: CFluidPlaneShader(EFluidType type, const TLockedToken& patternTex1, const TLockedToken& patternTex2, const TLockedToken& colorTex, const TLockedToken& bumpMap, const TLockedToken& envMap, const TLockedToken& envBumpMap, const TLockedToken& lightmap, const std::shared_ptr& rippleMap, bool doubleLightmapBlend, bool additive, u32 maxVertCount); CFluidPlaneShader(const TLockedToken& patternTex1, const TLockedToken& patternTex2, const TLockedToken& colorTex, u32 maxVertCount); void prepareDraw(const RenderSetupInfo& info); void prepareDraw(const RenderSetupInfo& info, const zeus::CVector3f& waterCenter, const CRippleManager& rippleManager, const zeus::CColor& colorMul, float rippleNormResolution); void bindRegular() { if (m_lastBind != 0) { // CGraphics::SetShaderDataBinding(m_dataBind.m_regular); m_lastBind = 0; } } bool bindTessellation() { if (m_lastBind != 1) { // CGraphics::SetShaderDataBinding(m_dataBind.m_tessellation); m_lastBind = 1; } return true; } void doneDrawing() { m_lastBind = -1; } void loadVerts(const std::vector& verts, const std::vector& pVerts); bool isReady() const { // return m_pipelines.m_regular->isReady() && (!m_pipelines.m_tessellation || m_pipelines.m_tessellation->isReady()); return false; } static void Shutdown(); }; } // namespace metaforce