#pragma once #include "GfxCore/Shader.h" #include #include #include #include struct ID3D11VertexShader; struct ID3D11PixelShader; struct ID3D11Buffer; struct ID3D11Device; struct ID3D11InputLayout; namespace RBX { namespace Graphics { class VertexLayoutD3D11; class DeviceD3D11; struct UniformD3D11 { std::string name; unsigned offset; unsigned size; }; class CBufferD3D11 : public Resource { public: CBufferD3D11(Device* device, int registerId, const std::string& name, unsigned sizeIn, const std::vector& uniformsIn); ~CBufferD3D11(); const std::vector& getUniforms () const { return uniforms; } const std::string& getName() const { return name; } int getRegisterId() { return registerId; } ID3D11Buffer* getObject() { return object; } const UniformD3D11& getUniform(int id) const; void updateUniform(int uniformId, const float* uniformData, unsigned vectorCount); void updateBuffer(); int findUniform(const std::string& uniformName); private: int registerId; std::vector uniforms; std::string name; ID3D11Buffer* object; bool dirty; size_t size; char* data; }; class BaseShaderD3D11 { public: BaseShaderD3D11(const std::vector& bytecode); const std::vector& getByteCode() const { return bytecode; } int findUniform(const std::string& name); void setConstant(int handle, const float* data, size_t vectorCount); void updateConstantBuffers(); typedef std::vector> CBufferList; const CBufferList& getCBuffers() const { return cBuffers; } protected: typedef CBufferList CBufferList; std::vector> cBuffers; int uniformsBufferId; std::vector bytecode; }; class VertexShaderD3D11: public VertexShader, public BaseShaderD3D11, public boost::enable_shared_from_this { public: VertexShaderD3D11(Device* device, const std::vector& bytecode); ~VertexShaderD3D11(); virtual void reloadBytecode(const std::vector& bytecode); ID3D11VertexShader* getObject() const { return object; } ID3D11InputLayout* getInputLayout11(VertexLayoutD3D11* vertexLayout); void removeLayout(VertexLayoutD3D11* vertexLayout); void setWorldTransforms4x3(const float* data, size_t matrixCount); unsigned int getMaxWorldTransforms() const { return maxWorldTransforms; } private: ID3D11VertexShader* object; int worldMatrixArray; int worldMatrix; int worldMatrixCbuffer; unsigned int maxWorldTransforms; typedef boost::unordered_map InputLayoutMap; InputLayoutMap inputLayoutMap; shared_ptr sharedThis; }; class FragmentShaderD3D11: public FragmentShader, public BaseShaderD3D11 { public: FragmentShaderD3D11(Device* device, const std::vector& bytecode); ~FragmentShaderD3D11(); virtual void reloadBytecode(const std::vector& bytecode); ID3D11PixelShader* getObject() const { return object; } const std::vector>& getCBuffers() const { return cBuffers; } unsigned int getSamplerMask() { return samplerMask; } private: ID3D11PixelShader* object; unsigned int samplerMask; }; class ShaderProgramD3D11: public ShaderProgram { public: ShaderProgramD3D11(Device* device, const shared_ptr& vertexShader, const shared_ptr& fragmentShader); ~ShaderProgramD3D11(); virtual int getConstantHandle(const char* name) const; virtual unsigned int getMaxWorldTransforms() const; virtual unsigned int getSamplerMask() const; ID3D11InputLayout* getInputLayout11(VertexLayoutD3D11* vertexLayout); void bind(); void setWorldTransforms4x3(const float* data, size_t matrixCount); void setConstant(int handle, const float* data, size_t vectorCount); void uploadConstantBuffers(); static std::string createShaderSource(const std::string& path, const std::string& defines, const DeviceD3D11* device11, boost::function fileCallback); static std::vector createShaderBytecode(const std::string& source, const std::string& target, const DeviceD3D11* device, const std::string& entrypoint); static HMODULE loadShaderCompilerDLL(); }; } }