#pragma once #include "BsCorePrerequisites.h" #include "BsIReflectable.h" #include "BsCoreObject.h" namespace BansheeEngine { /** * @brief Structure that describes pipeline rasterizer state. Used for initializing * a RasterizerState. * * @see RasterizerState */ struct BS_CORE_EXPORT RASTERIZER_STATE_DESC { RASTERIZER_STATE_DESC() : polygonMode(PM_SOLID) , cullMode(CULL_COUNTERCLOCKWISE) , depthBias(0) , depthBiasClamp(0.0f) , slopeScaledDepthBias(0.0f) , depthClipEnable(true) , scissorEnable(false) , multisampleEnable(true) , antialiasedLineEnable(false) { } bool operator==(const RASTERIZER_STATE_DESC& rhs) const; PolygonMode polygonMode; CullingMode cullMode; float depthBias; float depthBiasClamp; float slopeScaledDepthBias; bool depthClipEnable; bool scissorEnable; bool multisampleEnable; bool antialiasedLineEnable; }; /** * @brief Properties of RasterizerState. Shared between sim and core thread versions of RasterizerState. */ class BS_CORE_EXPORT RasterizerProperties { public: RasterizerProperties(const RASTERIZER_STATE_DESC& desc); /** * @brief Polygon mode allows you to draw polygons as solid objects or as wireframe by * just drawing their edges. */ PolygonMode getPolygonMode() const { return mData.polygonMode; } /** * @brief Sets vertex winding order. Faces that contain vertices with this order will * be culled and not rasterized. Used primarily for saving cycles by not rendering * backfacing faces. */ CullingMode getCullMode() const { return mData.cullMode; } /** * @brief Represents a constant depth bias that will offset the depth values of new pixels * by the specified amount. * * @note This is useful if you want to avoid z fighting for objects at the same or similar depth. */ float getDepthBias() const { return mData.depthBias; } /** * @brief Maximum depth bias value. */ float getDepthBiasClamp() const { return mData.depthBiasClamp; } /** * @brief Represents a dynamic depth bias that increases as the slope of the rendered polygons * surface increases. Resulting value offsets depth values of new pixels. This offset will * be added on top of the constant depth bias. * * @note This is useful if you want to avoid z fighting for objects at the same or similar depth. */ float getSlopeScaledDepthBias() const { return mData.slopeScaledDepthBias; } /** * @brief If true, clipping of polygons past the far Z plane is enabled. This ensures proper * Z ordering for polygons outside of valid depth range (otherwise they all have the same * depth). It can be useful to disable if you are performing stencil operations that count on * objects having a front and a back (like stencil shadow) and don't want to clip the back. */ bool getDepthClipEnable() const { return mData.depthClipEnable; } /** * @brief Scissor rectangle allows you to cull all pixels outside of the scissor rectangle. * * @see RenderAPICore::setScissorRect */ bool getScissorEnable() const { return mData.scissorEnable; } /** * @brief Determines how are samples in multi-sample render targets handled. * If disabled all samples in the render target will be written the same value, * and if enabled each sample will be generated separately. * * @note In order to get an antialiased image you need to both enable this option and use * a MSAA render target. */ bool getMultisampleEnable() const { return mData.multisampleEnable; } /** * @brief Determines should the lines be antialiased. This is separate from multi-sample * antialiasing setting as lines can be antialiased without multi-sampling. * * @note This setting is usually ignored if MSAA is used, as that provides sufficient antialiasing. */ bool getAntialiasedLineEnable() const { return mData.antialiasedLineEnable; } /** * @brief Returns the hash value generated from the rasterizer state properties. */ UINT64 getHash() const { return mHash; } protected: friend class RasterizerState; friend class RasterizerStateCore; friend class RasterizerStateRTTI; RASTERIZER_STATE_DESC mData; UINT64 mHash; }; /** * @brief Core thread version of RasterizerState. * * @note Core thread. */ class BS_CORE_EXPORT RasterizerStateCore : public CoreObjectCore { public: virtual ~RasterizerStateCore(); /** * @brief Returns information about the rasterizer state. */ const RasterizerProperties& getProperties() const; /** * @brief Returns a unique state ID. Only the lowest 10 bits are used. */ UINT32 getId() const { return mId; } /** * @brief Returns the default rasterizer state. */ static const SPtr& getDefault(); protected: friend class RenderStateCoreManager; RasterizerStateCore(const RASTERIZER_STATE_DESC& desc, UINT32 id); /** * @copydoc CoreObjectCore::initialize */ void initialize() override; /** * @brief Creates any API-specific state objects. */ virtual void createInternal() { } RasterizerProperties mProperties; UINT32 mId; }; /** * @brief Render system pipeline state that allows you to modify how an object is rasterized. * i.e. how are polygons converted to pixels. * * @note Rasterizer states are immutable. Sim thread only. */ class BS_CORE_EXPORT RasterizerState : public IReflectable, public CoreObject { public: virtual ~RasterizerState(); /** * @brief Returns information about the rasterizer state. */ const RasterizerProperties& getProperties() const; /** * @brief Retrieves a core implementation of the rasterizer state usable only from the * core thread. */ SPtr getCore() const; /** * @brief Creates a new rasterizer state using the specified rasterizer state descriptor structure. */ static RasterizerStatePtr create(const RASTERIZER_STATE_DESC& desc); /** * @brief Returns the default rasterizer state. */ static const RasterizerStatePtr& getDefault(); /** * @brief Generates a hash value from a rasterizer state descriptor. */ static UINT64 generateHash(const RASTERIZER_STATE_DESC& desc); protected: friend class RenderStateManager; RasterizerState(const RASTERIZER_STATE_DESC& desc); /** * @copydoc CoreObjectCore::createCore */ SPtr createCore() const override; RasterizerProperties mProperties; mutable UINT32 mId; /************************************************************************/ /* RTTI */ /************************************************************************/ public: friend class RasterizerStateRTTI; static RTTITypeBase* getRTTIStatic(); virtual RTTITypeBase* getRTTI() const override; }; } /** * @brief Hash value generator for RASTERIZER_STATE_DESC. */ template<> struct std::hash { size_t operator()(const BansheeEngine::RASTERIZER_STATE_DESC& value) const { return (size_t)BansheeEngine::RasterizerState::generateHash(value); } };