// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "IMaterial.h" #include "Engine/Core/Collections/Array.h" #include "Engine/Graphics/GPUPipelineState.h" #include "Engine/Renderer/Config.h" /// /// Current materials shader version. /// #define MATERIAL_GRAPH_VERSION 165 class Material; class GPUShader; class GPUConstantBuffer; class MemoryReadStream; /// /// Represents material shader that can be used to render objects, visuals or effects. Contains a dedicated shader. /// class MaterialShader : public IMaterial { protected: struct PipelineStateCache { GPUPipelineState* PS[6]; GPUPipelineState::Description Desc; PipelineStateCache() { Platform::MemoryClear(PS, sizeof(PS)); } void Init(GPUPipelineState::Description& desc) { Desc = desc; } GPUPipelineState* GetPS(CullMode mode, bool wireframe) { const int32 index = static_cast(mode) + (wireframe ? 3 : 0); auto ps = PS[index]; if (!ps) PS[index] = ps = InitPS(mode, wireframe); return ps; } GPUPipelineState* InitPS(CullMode mode, bool wireframe); void Release() { SAFE_DELETE_GPU_RESOURCES(PS); } }; protected: bool _isLoaded; GPUShader* _shader; GPUConstantBuffer* _cb; Array _cbData; MaterialInfo _info; protected: /// /// Init /// /// Material resource name MaterialShader(const StringView& name); public: /// /// Finalizes an instance of the class. /// virtual ~MaterialShader(); public: /// /// Creates and loads the material from the data. /// /// Material resource name /// Stream with compiled shader data /// Loaded material info structure /// The created and loaded material or null if failed. static MaterialShader* Create(const StringView& name, MemoryReadStream& shaderCacheStream, const MaterialInfo& info); /// /// Creates the dummy material used by the Null rendering backend to mock object but not perform any rendering. /// /// The shader cache stream. /// The material information. /// The created and loaded material or null if failed. static MaterialShader* CreateDummy(MemoryReadStream& shaderCacheStream, const MaterialInfo& info); /// /// Clears the loaded data. /// virtual void Unload(); protected: bool Load(MemoryReadStream& shaderCacheStream, const MaterialInfo& info); virtual bool Load() = 0; public: // [IMaterial] const MaterialInfo& GetInfo() const override; GPUShader* GetShader() const override; bool IsReady() const override; };