/** * * Copyright (c) 2021, Kitty Barnett * * The source code in this file is provided to you under the terms of the * GNU Lesser General Public License, version 2.1, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. Terms of the LGPL can be found in doc/LGPL-licence.txt * in this distribution, or online at http://www.gnu.org/licenses/lgpl-2.1.txt * * By copying, modifying or distributing this software, you acknowledge that * you have read and understood your obligations described above, and agree to * abide by those obligations. * */ #pragma once #include "llsingleton.h" #include #include // ============================================================================ // // class LLRenderTarget; // ============================================================================ // // enum class EVisualEffect { RlvOverlay, RlvSphere, }; enum class EVisualEffectType { PostProcessShader, Custom, }; // ============================================================================ // // struct LLVisualEffectParams { virtual void step(bool isLast) = 0; }; struct LLShaderEffectParams : LLVisualEffectParams { explicit LLShaderEffectParams(LLRenderTarget* pSrcBuffer, LLRenderTarget* pScratchBuffer, bool fBindLast) : m_pSrcBuffer(pScratchBuffer), m_pDstBuffer(pSrcBuffer), m_fBindLast(fBindLast) {} void step(bool isLast) override { LLRenderTarget* pPrevSrc = m_pSrcBuffer, *pPrevDst = m_pDstBuffer; m_pSrcBuffer = pPrevDst; m_pDstBuffer = (!isLast || !m_fBindLast) ? pPrevSrc : nullptr; } LLRenderTarget* m_pSrcBuffer = nullptr; LLRenderTarget* m_pDstBuffer = nullptr; bool m_fBindLast = false; }; // ============================================================================ // // class LLVisualEffect { friend class LLVfxManager; public: LLVisualEffect(LLUUID id, EVisualEffect eCode, EVisualEffectType eType) : m_id(id), m_eCode(eCode), m_eType(eType) {} virtual ~LLVisualEffect() {} EVisualEffect getCode() const { return m_eCode;} bool getEnabled() const { return m_fEnabled; } const LLUUID& getId() const { return m_id;} U32 getPriority() const { return m_nPriority; } EVisualEffectType getType() const { return m_eType;} void setEnabled(bool enable) { m_fEnabled = enable; } virtual void run(const LLVisualEffectParams* pParams) = 0; protected: void setPriority(U32 priority) { m_nPriority = priority; } /* * Member variables */ protected: LLUUID m_id; EVisualEffect m_eCode; EVisualEffectType m_eType; bool m_fEnabled = true; U32 m_nPriority = 0; }; // ============================================================================ // // template class LLTweenableValue { public: LLTweenableValue(const T& defaultValue) : m_CurValue(defaultValue) {} virtual ~LLTweenableValue() {} virtual T get() = 0; virtual void start(const T& endValue, double duration) = 0; T& operator =(const T& value) { m_CurValue = value; } /* * Member variables */ protected: boost::optional m_CurValue; }; template class LLTweenableValueLerp : public LLTweenableValue { public: LLTweenableValueLerp(const T& defaultValue) : LLTweenableValue(defaultValue) {} T get() override; void start(const T& endValue, double duration) override { m_StartValue = get(); this->m_CurValue = boost::none; m_EndValue = endValue; m_StartTime = LLTimer::getElapsedSeconds(); m_Duration = duration; } /* * Member variables */ protected: double m_StartTime; double m_Duration; T m_StartValue; T m_EndValue; }; // ============================================================================ // // class LLVfxManager : public LLSingleton { LLSINGLETON(LLVfxManager); protected: ~LLVfxManager() {} /* * Member functions */ public: bool addEffect(LLVisualEffect* pEffectInst); LLVisualEffect* getEffect(EVisualEffect eCode, const LLUUID& idEffect) const; template T* getEffect(const LLUUID& idEffect) const { return dynamic_cast(getEffect(T::EffectCode, idEffect)); } bool getEffects(std::list& effectList, std::function fnFilter); template bool getEffects(std::list& effectList); bool hasEffect(EVisualEffect eCode) const; bool removeEffect(EVisualEffect eCode, const LLUUID& idEffect); template bool removeEffect(const LLUUID& idEffect) { return removeEffect(T::EffectCode, idEffect); } void runEffect(EVisualEffect eCode, LLVisualEffectParams* pParams = nullptr); void runEffect(EVisualEffectType eType, LLVisualEffectParams* pParams = nullptr); void updateEffect(LLVisualEffect* pEffect, bool fEnabled, U32 nPriority); protected: void runEffect(std::function fnFilter, LLVisualEffectParams* pParams); static bool cmpEffect(const LLVisualEffect* pLHS, const LLVisualEffect* pRHS); /* * Member variables */ protected: std::vector m_Effects; }; // ============================================================================ // Inlined member functions // inline bool LLVfxManager::hasEffect(EVisualEffect eCode) const { return m_Effects.end() != std::find_if(m_Effects.begin(), m_Effects.end(), [eCode](const LLVisualEffect* pEffect) { return pEffect->getCode() == eCode; }); } template inline bool LLVfxManager::getEffects(std::list& effectList) { effectList.clear(); std::function fnFilter = [](const LLVisualEffect* pEffect) { return pEffect->getCode() == T::EffectCode; }; auto itEffect = boost::make_filter_iterator(fnFilter, m_Effects.begin(), m_Effects.end()), endEffect = boost::make_filter_iterator(fnFilter, m_Effects.end(), m_Effects.end()); while (itEffect != endEffect) { if (T* pEffect = dynamic_cast(*itEffect++)) { effectList.push_back(pEffect); } } return effectList.size(); } // ============================================================================