#pragma once #include "BsCorePrerequisites.h" #include "BsColor.h" #include "BsIReflectable.h" #include "BsCoreObject.h" namespace BansheeEngine { /** * @brief Descriptor structure used for initializing a shader pass. */ struct PASS_DESC { BlendStatePtr blendState; RasterizerStatePtr rasterizerState; DepthStencilStatePtr depthStencilState; UINT32 stencilRefValue; GpuProgramPtr vertexProgram; GpuProgramPtr fragmentProgram; GpuProgramPtr geometryProgram; GpuProgramPtr hullProgram; GpuProgramPtr domainProgram; GpuProgramPtr computeProgram; }; /** * @brief Descriptor structure used for initializing a core thread * variant of a shader pass. */ struct PASS_DESC_CORE { SPtr blendState; SPtr rasterizerState; SPtr depthStencilState; UINT32 stencilRefValue; SPtr vertexProgram; SPtr fragmentProgram; SPtr geometryProgram; SPtr hullProgram; SPtr domainProgram; SPtr computeProgram; }; /** * @brief Contains all data used by a pass, templated * so it may contain both core and sim thread data. */ template struct TPassTypes { }; template<> struct TPassTypes < false > { typedef BlendStatePtr BlendStateType; typedef RasterizerStatePtr RasterizerStateType; typedef DepthStencilStatePtr DepthStencilStateType; typedef GpuProgramPtr GpuProgramType; typedef PASS_DESC PassDescType; }; template<> struct TPassTypes < true > { typedef SPtr BlendStateType; typedef SPtr RasterizerStateType; typedef SPtr DepthStencilStateType; typedef SPtr GpuProgramType; typedef PASS_DESC_CORE PassDescType; }; /** * @brief Class defining a single pass of a technique (of a material), i.e. * a single rendering call. * * Pass may contain multiple GPU programs (vertex, fragment, geometry, etc.), and * a set of pipeline states (blend, rasterizer, etc.). * * @note Templated so it can be used for both core and non-core versions of a pass. */ template class BS_CORE_EXPORT TPass { public: typedef typename TPassTypes::BlendStateType BlendStateType; typedef typename TPassTypes::RasterizerStateType RasterizerStateType; typedef typename TPassTypes::DepthStencilStateType DepthStencilStateType; typedef typename TPassTypes::GpuProgramType GpuProgramType; typedef typename TPassTypes::PassDescType PassDescType; virtual ~TPass() { } bool hasVertexProgram() const { return mData.vertexProgram != nullptr; } bool hasFragmentProgram() const { return mData.fragmentProgram != nullptr; } bool hasGeometryProgram() const { return mData.geometryProgram != nullptr; } bool hasHullProgram() const { return mData.hullProgram != nullptr; } bool hasDomainProgram() const { return mData.domainProgram != nullptr; } bool hasComputeProgram() const { return mData.computeProgram != nullptr; } /** * @brief Returns true if this pass has some element of transparency. */ bool hasBlending() const; BlendStateType getBlendState() const { return mData.blendState; } RasterizerStateType getRasterizerState() const { return mData.rasterizerState; } DepthStencilStateType getDepthStencilState() const { return mData.depthStencilState; } /** * @brief Gets the stencil reference value that is used when performing operations using the * stencil buffer. */ UINT32 getStencilRefValue() const { return mData.stencilRefValue; } const GpuProgramType& getVertexProgram() const { return mData.vertexProgram; } const GpuProgramType& getFragmentProgram() const { return mData.fragmentProgram; } const GpuProgramType& getGeometryProgram() const { return mData.geometryProgram; } const GpuProgramType& getHullProgram(void) const { return mData.hullProgram; } const GpuProgramType& getDomainProgram(void) const { return mData.domainProgram; } const GpuProgramType& getComputeProgram(void) const { return mData.computeProgram; } protected: TPass(); TPass(const PassDescType& desc); PassDescType mData; }; /** * @copydoc PassBase * * @note Core thread. */ class BS_CORE_EXPORT PassCore : public CoreObjectCore, public TPass { public: virtual ~PassCore() { } /** * @brief Creates a new empty pass. */ static SPtr create(const PASS_DESC_CORE& desc); protected: friend class Pass; friend class TechniqueCore; PassCore() { } PassCore(const PASS_DESC_CORE& desc); /** * @copydoc CoreObjectCore::syncToCore */ void syncToCore(const CoreSyncData& data) override; }; /** * @copydoc PassBase * * @note Sim thread. */ class BS_CORE_EXPORT Pass : public IReflectable, public CoreObject, public TPass { public: virtual ~Pass() { } /** * @brief Retrieves an implementation of a pass usable only from the * core thread. */ SPtr getCore() const; /** * @brief Creates a new empty pass. */ static PassPtr create(const PASS_DESC& desc); protected: friend class Technique; Pass() { } Pass(const PASS_DESC& desc); /** * @copydoc CoreObject::syncToCore */ CoreSyncData syncToCore(FrameAlloc* allocator) override; /** * @copydoc CoreObject::createCore */ SPtr createCore() const override; /** * @copydoc CoreObject::syncToCore */ void getCoreDependencies(FrameVector>& dependencies) override; /** * @brief Creates a new empty pass but doesn't initialize it. */ static PassPtr createEmpty(); /************************************************************************/ /* RTTI */ /************************************************************************/ public: friend class PassRTTI; static RTTITypeBase* getRTTIStatic(); virtual RTTITypeBase* getRTTI() const override; }; }