//********************************** Banshee Engine (www.banshee3d.com) **************************************************// //**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************// #pragma once #include "BsCorePrerequisites.h" #include "Math/BsVector2.h" #include "Math/BsVector3.h" #include "Math/BsVector4.h" #include "Math/BsMatrix3.h" #include "Math/BsMatrix4.h" #include "Math/BsMatrixNxM.h" #include "Math/BsVector3I.h" #include "Math/BsVector4I.h" #include "Image/BsColor.h" namespace bs { /** @addtogroup Implementation * @{ */ template struct TGpuParamsPtrType { }; template<> struct TGpuParamsPtrType { typedef SPtr Type; }; template<> struct TGpuParamsPtrType { typedef SPtr Type; }; template struct TGpuParamTextureType { }; template<> struct TGpuParamTextureType < false > { typedef HTexture Type; }; template<> struct TGpuParamTextureType < true > { typedef SPtr Type; }; template struct TGpuParamSamplerStateType { }; template<> struct TGpuParamSamplerStateType < false > { typedef SPtr Type; }; template<> struct TGpuParamSamplerStateType < true > { typedef SPtr Type; }; template struct TGpuParamBufferType { }; template<> struct TGpuParamBufferType < false > { typedef SPtr Type; }; template<> struct TGpuParamBufferType < true > { typedef SPtr Type; }; template struct TGpuBufferType { }; template<> struct TGpuBufferType < false > { typedef SPtr Type; }; template<> struct TGpuBufferType < true > { typedef SPtr Type; }; /** * Policy class that allows us to re-use this template class for matrices which might need transposing, and other * types which do not. Matrix needs to be transposed for certain render systems depending on how they store them * in memory. */ template struct TransposePolicy { static Type transpose(const Type& value) { return value; } static bool transposeEnabled(bool enabled) { return false; } }; /** Transpose policy for 3x3 matrix. */ template<> struct TransposePolicy { static Matrix3 transpose(const Matrix3& value) { return value.transpose(); } static bool transposeEnabled(bool enabled) { return enabled; } }; /** Transpose policy for 4x4 matrix. */ template<> struct TransposePolicy { static Matrix4 transpose(const Matrix4& value) { return value.transpose(); } static bool transposeEnabled(bool enabled) { return enabled; } }; /** Transpose policy for NxM matrix. */ template struct TransposePolicy> { static MatrixNxM transpose(const MatrixNxM& value) { return value.transpose(); } static bool transposeEnabled(bool enabled) { return enabled; } }; /** * A handle that allows you to set a GpuProgram parameter. Internally keeps a reference to the GPU parameter buffer and * the necessary offsets. You should specialize this type for specific parameter types. * * Object of this type must be returned by a Material. Setting/Getting parameter values will internally access a GPU * parameter buffer attached to the Material this parameter was created from. Anything rendered with that material will * then use those set values. * * @note * Normally you can set a GpuProgram parameter by calling various set/get methods on a Material. This class primarily * used an as optimization in performance critical bits of code where it is important to locate and set parameters * quickly without any lookups (Mentioned set/get methods expect a parameter name). You just retrieve the handle once * and then set the parameter value many times with minimal performance impact. * * @see Material */ template class BS_CORE_EXPORT TGpuDataParam { private: typedef typename TGpuParamBufferType::Type GpuParamBufferType; typedef typename TGpuParamsPtrType::Type GpuParamsType; public: TGpuDataParam(); TGpuDataParam(GpuParamDataDesc* paramDesc, const GpuParamsType& parent); /** * Sets a parameter value at the specified array index. If parameter does not contain an array leave the index at 0. * * @note * Like with all GPU parameters, the actual GPU buffer will not be updated until rendering with material this * parameter was created from starts on the core thread. */ void set(const T& value, UINT32 arrayIdx = 0) const; /** * Returns a value of a parameter at the specified array index. If parameter does not contain an array leave the * index at 0. * * @note No GPU reads are done. Data returned was cached when it was written. */ T get(UINT32 arrayIdx = 0) const; /** Returns meta-data about the parameter. */ const GpuParamDataDesc& getDesc() const { return *mParamDesc; } /** Checks if param is initialized. */ bool operator==(const std::nullptr_t& nullval) const { return mParamDesc == nullptr; } protected: GpuParamsType mParent; GpuParamDataDesc* mParamDesc; }; /** @copydoc TGpuDataParam */ template class BS_CORE_EXPORT TGpuParamStruct { public: typedef typename TGpuParamBufferType::Type GpuParamBufferType; typedef typename TGpuParamsPtrType::Type GpuParamsType; TGpuParamStruct(); TGpuParamStruct(GpuParamDataDesc* paramDesc, const GpuParamsType& parent); /** @copydoc TGpuDataParam::set */ void set(const void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0) const; /** @copydoc TGpuDataParam::get */ void get(void* value, UINT32 sizeBytes, UINT32 arrayIdx = 0) const; /** Returns the size of the struct in bytes. */ UINT32 getElementSize() const; /** Returns meta-data about the parameter. */ const GpuParamDataDesc& getDesc() const { return *mParamDesc; } /** Checks if param is initialized. */ bool operator==(const std::nullptr_t& nullval) const { return mParamDesc == nullptr; } protected: GpuParamsType mParent; GpuParamDataDesc* mParamDesc; }; /** @copydoc TGpuDataParam */ template class BS_CORE_EXPORT TGpuParamTexture { private: friend class GpuParams; friend class ct::GpuParams; typedef typename TGpuParamsPtrType::Type GpuParamsType; typedef typename TGpuParamTextureType::Type TextureType; public: TGpuParamTexture(); TGpuParamTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent); /** @copydoc TGpuDataParam::set */ void set(const TextureType& texture, const TextureSurface& surface = TextureSurface::COMPLETE) const; /** @copydoc TGpuDataParam::get */ TextureType get() const; /** @copydoc TGpuDataParam::getDesc */ const GpuParamObjectDesc& getDesc() const { return *mParamDesc; } /** Checks if param is initialized. */ bool operator==(const std::nullptr_t& nullval) const { return mParamDesc == nullptr; } protected: GpuParamsType mParent; GpuParamObjectDesc* mParamDesc; }; /** @copydoc TGpuDataParam */ template class BS_CORE_EXPORT TGpuParamLoadStoreTexture { private: friend class GpuParams; friend class ct::GpuParams; typedef typename TGpuParamsPtrType::Type GpuParamsType; typedef typename TGpuParamTextureType::Type TextureType; public: TGpuParamLoadStoreTexture(); TGpuParamLoadStoreTexture(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent); /** @copydoc TGpuDataParam::set */ void set(const TextureType& texture, const TextureSurface& surface = TextureSurface()) const; /** @copydoc TGpuDataParam::get */ TextureType get() const; /** @copydoc TGpuDataParam::getDesc */ const GpuParamObjectDesc& getDesc() const { return *mParamDesc; } /** Checks if param is initialized. */ bool operator==(const std::nullptr_t& nullval) const { return mParamDesc == nullptr; } protected: GpuParamsType mParent; GpuParamObjectDesc* mParamDesc; }; /** @copydoc TGpuDataParam */ template class BS_CORE_EXPORT TGpuParamBuffer { private: friend class GpuParams; friend class ct::GpuParams; typedef typename TGpuParamsPtrType::Type GpuParamsType; typedef typename TGpuBufferType::Type BufferType; public: TGpuParamBuffer(); TGpuParamBuffer(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent); /** @copydoc TGpuDataParam::set */ void set(const BufferType& buffer) const; /** @copydoc TGpuDataParam::get */ BufferType get() const; /** @copydoc TGpuDataParam::getDesc */ const GpuParamObjectDesc& getDesc() const { return *mParamDesc; } /** Checks if param is initialized. */ bool operator==(const std::nullptr_t& nullval) const { return mParamDesc == nullptr; } protected: GpuParamsType mParent; GpuParamObjectDesc* mParamDesc; }; /** @copydoc TGpuDataParam */ template class BS_CORE_EXPORT TGpuParamSampState { private: friend class GpuParams; friend class ct::GpuParams; typedef typename TGpuParamsPtrType::Type GpuParamsType; typedef typename TGpuParamSamplerStateType::Type SamplerStateType; public: TGpuParamSampState(); TGpuParamSampState(GpuParamObjectDesc* paramDesc, const GpuParamsType& parent); /** @copydoc TGpuDataParam::set */ void set(const SamplerStateType& samplerState) const; /** @copydoc TGpuDataParam::get */ SamplerStateType get() const; /** @copydoc TGpuDataParam::getDesc */ const GpuParamObjectDesc& getDesc() const { return *mParamDesc; } /** Checks if param is initialized. */ bool operator==(const std::nullptr_t& nullval) const { return mParamDesc == nullptr; } protected: GpuParamsType mParent; GpuParamObjectDesc* mParamDesc; }; /** @} */ /** @addtogroup RenderAPI * @{ */ typedef TGpuDataParam GpuParamFloat; typedef TGpuDataParam GpuParamVec2; typedef TGpuDataParam GpuParamVec3; typedef TGpuDataParam GpuParamVec4; typedef TGpuDataParam GpuParamInt; typedef TGpuDataParam GpuParamVec2I; typedef TGpuDataParam GpuParamVec3I; typedef TGpuDataParam GpuParamVec4I; typedef TGpuDataParam GpuParamMat3; typedef TGpuDataParam GpuParamMat4; typedef TGpuDataParam GpuParamColor; typedef TGpuParamStruct GpuParamStruct; typedef TGpuParamTexture GpuParamTexture; typedef TGpuParamBuffer GpuParamBuffer; typedef TGpuParamSampState GpuParamSampState; typedef TGpuParamLoadStoreTexture GpuParamLoadStoreTexture; namespace ct { typedef TGpuDataParam GpuParamFloat; typedef TGpuDataParam GpuParamVec2; typedef TGpuDataParam GpuParamVec3; typedef TGpuDataParam GpuParamVec4; typedef TGpuDataParam GpuParamInt; typedef TGpuDataParam GpuParamVec2I; typedef TGpuDataParam GpuParamVec3I; typedef TGpuDataParam GpuParamVec4I; typedef TGpuDataParam GpuParamMat3; typedef TGpuDataParam GpuParamMat4; typedef TGpuDataParam GpuParamColor; typedef TGpuParamStruct GpuParamStruct; typedef TGpuParamTexture GpuParamTexture; typedef TGpuParamBuffer GpuParamBuffer; typedef TGpuParamSampState GpuParamSampState; typedef TGpuParamLoadStoreTexture GpuParamLoadStoreTexture; } /** @} */ }