#pragma once #include "Ires.hpp" #include "RcPtr.hpp" #include "Shader.hpp" #include "Texture.hpp" #include #include #include #include #include #include #include #include #include // Forward declarations class Material; class IresMaterial; class Material : public RefCounted { friend class IresMaterial; public: // NOTE: specialize between scalar vs matrix vs vector to save memory enum UniformType : uint16_t { UT_Scalar, UT_Vector, UT_Matrix, }; struct UniformIndex { UniformType type; uint16_t index; }; struct ScalarUniform { union { float floatValue; int32_t intValue; uint32_t uintValue; }; GLenum actualType; /* Transient */ int infoUniformIndex; /* Transient */ GLint location; }; struct VectorUniform { float value[4]; int actualLength; /* Transient */ int infoUniformIndex; /* Transient */ GLint location; }; struct MatrixUniform { float value[16]; int actualWidth; int actualHeight; /* Transient */ int infoUniformIndex; /* Transient */ GLint location; }; struct TextureUniform { RcPtr value; /* Transient */ int infoUniformIndex; /* Transient */ GLint location; }; IresMaterial* mIres = nullptr; RcPtr mShader; std::vector mBoundScalars; std::vector mBoundVectors; std::vector mBoundMatrices; std::vector mBoundTextures; public: Material(); void SetFloat(const char* name, float value); void SetInt(const char* name, int32_t value); void SetUInt(const char* name, uint32_t value); /// Instanciated for length == 1, 2, 3, 4 template void SetVector(const char* name, const glm::vec& vec); /// Instanciated for sizes (2,2) (3,3) (4,4) (2,3) (3,2) (2,4) (4,2) (3,4) (4,3) template void SetMatrix(const char* name, const glm::mat& mat); void SetTexture(const char* name, Texture* texture); std::span GetVectors() const; std::span GetMatrices() const; std::span GetTextures() const; Shader* GetShader() const; void SetShader(Shader* shader); IresMaterial* GetIres() const { return mIres; } bool IsValid() const; void UseUniforms() const; }; // Initialized in main() inline RcPtr gDefaultMaterial; class IresMaterial : public IresObject { private: RcPtr mInstance; public: IresMaterial(); Material* GetInstance() const; void InvalidateInstance(); void ShowEditor(EditorInstance& editor) override; void Write(IresWritingContext& ctx, rapidjson::Value& value, rapidjson::Document& root) const override; void Read(IresLoadingContext& ctx, const rapidjson::Value& value) override; };