// 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;
}
};