// Copyright (c) Wojciech Figat. All rights reserved. #pragma once #include "VertexElement.h" #include "Engine/Graphics/GPUResource.h" #include "Engine/Core/Collections/Array.h" class GPUBuffer; /// /// Defines input layout of vertex buffer data passed to the Vertex Shader. /// API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API GPUVertexLayout : public GPUResource { DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUVertexLayout); typedef Array> Elements; private: Elements _elements; uint32 _stride; protected: GPUVertexLayout(); void SetElements(const Elements& elements, bool explicitOffsets); public: /// /// Gets the list of elements used by this layout. /// API_PROPERTY() FORCE_INLINE const Array>& GetElements() const { return _elements; } /// /// Gets the list of elements used by this layout as a text (each element in a new line). /// API_PROPERTY() String GetElementsString() const; /// /// Gets the size in bytes of all elements in the layout structure (including their offsets). /// API_PROPERTY() FORCE_INLINE uint32 GetStride() const { return _stride; } /// /// Searches for a given element type in a layout. /// /// The type of element to find. /// Found element with properties or empty if missing. API_FUNCTION() VertexElement FindElement(VertexElement::Types type) const; /// /// Gets the vertex layout for a given list of elements. Uses internal cache to skip creating layout if it's already exists for a given list. /// /// The list of elements for the layout. /// If set to true, input elements offsets will be used without automatic calculations (offsets with value 0). /// Vertex layout object. Doesn't need to be cleared as it's cached for an application lifetime. API_FUNCTION() static GPUVertexLayout* Get(const Array>& elements, bool explicitOffsets = false); /// /// Gets the vertex layout for a given list of vertex buffers (sequence of binding slots based on layouts set on those buffers). Uses internal cache to skip creating layout if it's already exists for a given list. /// /// The list of vertex buffers for the layout. /// Vertex layout object. Doesn't need to be cleared as it's cached for an application lifetime. API_FUNCTION() static GPUVertexLayout* Get(const Span& vertexBuffers); /// /// Merges list of layouts in a single one. Uses internal cache to skip creating layout if it's already exists for a given list. /// /// The list of layouts to merge. /// Vertex layout object. Doesn't need to be cleared as it's cached for an application lifetime. API_FUNCTION() static GPUVertexLayout* Get(const Span& layouts); /// /// Merges reference vertex elements into the given set of elements to ensure the reference list is satisfied (vertex shader input requirement). Returns base layout if it's valid. /// /// The list of vertex buffers for the layout. /// The list of reference inputs. /// True to remove elements from base layout that don't exist in a reference layout. /// True to add missing elements to base layout that exist in a reference layout. /// Allows to override the input slot for missing elements. Use value -1 to inherit slot from the reference layout. /// True to reorder result elements to match the reference layout. For example, if input vertex buffer layout is different than vertex shader then it can match those. /// Vertex layout object. Doesn't need to be cleared as it's cached for an application lifetime. static GPUVertexLayout* Merge(GPUVertexLayout* base, GPUVertexLayout* reference, bool removeUnused = false, bool addMissing = true, int32 missingSlotOverride = -1, bool referenceOrder = false); public: // [GPUResource] GPUResourceType GetResourceType() const override { return GPUResourceType::Descriptor; } };