Add option to merge vertex layout with reference order maintained
This commit is contained in:
@@ -216,20 +216,21 @@ GPUVertexLayout* GPUVertexLayout::Get(const Span<GPUVertexLayout*>& layouts)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
GPUVertexLayout* GPUVertexLayout::Merge(GPUVertexLayout* base, GPUVertexLayout* reference, bool removeUnused, bool addMissing, int32 missingSlotOverride)
|
GPUVertexLayout* GPUVertexLayout::Merge(GPUVertexLayout* base, GPUVertexLayout* reference, bool removeUnused, bool addMissing, int32 missingSlotOverride, bool referenceOrder)
|
||||||
{
|
{
|
||||||
GPUVertexLayout* result = base ? base : reference;
|
GPUVertexLayout* result = base ? base : reference;
|
||||||
if (base && reference && base != reference)
|
if (base && reference && base != reference)
|
||||||
{
|
{
|
||||||
bool elementsModified = false;
|
bool elementsModified = false;
|
||||||
Elements newElements = base->GetElements();
|
Elements newElements = base->GetElements();
|
||||||
|
const Elements& refElements = reference->GetElements();
|
||||||
if (removeUnused)
|
if (removeUnused)
|
||||||
{
|
{
|
||||||
for (int32 i = newElements.Count() - 1; i >= 0; i--)
|
for (int32 i = newElements.Count() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
bool missing = true;
|
bool missing = true;
|
||||||
const VertexElement& e = newElements.Get()[i];
|
const VertexElement& e = newElements.Get()[i];
|
||||||
for (const VertexElement& ee : reference->GetElements())
|
for (const VertexElement& ee : refElements)
|
||||||
{
|
{
|
||||||
if (ee.Type == e.Type)
|
if (ee.Type == e.Type)
|
||||||
{
|
{
|
||||||
@@ -247,7 +248,7 @@ GPUVertexLayout* GPUVertexLayout::Merge(GPUVertexLayout* base, GPUVertexLayout*
|
|||||||
}
|
}
|
||||||
if (addMissing)
|
if (addMissing)
|
||||||
{
|
{
|
||||||
for (const VertexElement& e : reference->GetElements())
|
for (const VertexElement& e : refElements)
|
||||||
{
|
{
|
||||||
bool missing = true;
|
bool missing = true;
|
||||||
for (const VertexElement& ee : base->GetElements())
|
for (const VertexElement& ee : base->GetElements())
|
||||||
@@ -282,6 +283,32 @@ GPUVertexLayout* GPUVertexLayout::Merge(GPUVertexLayout* base, GPUVertexLayout*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (referenceOrder)
|
||||||
|
{
|
||||||
|
for (int32 i = 0, j = 0; i < newElements.Count() && j < refElements.Count(); j++)
|
||||||
|
{
|
||||||
|
if (newElements[i].Type == refElements[j].Type)
|
||||||
|
{
|
||||||
|
// Elements match so move forward
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find reference element in a new list
|
||||||
|
for (int32 k = i + 1; k < newElements.Count(); k++)
|
||||||
|
{
|
||||||
|
if (newElements[k].Type == refElements[j].Type)
|
||||||
|
{
|
||||||
|
// Move matching element to the reference position
|
||||||
|
VertexElement e = newElements[k];
|
||||||
|
newElements.RemoveAt(k);
|
||||||
|
newElements.Insert(i, e);
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (elementsModified)
|
if (elementsModified)
|
||||||
result = Get(newElements, true);
|
result = Get(newElements, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,8 +84,9 @@ public:
|
|||||||
/// <param name="removeUnused">True to remove elements from base layout that don't exist in a reference layout.</param>
|
/// <param name="removeUnused">True to remove elements from base layout that don't exist in a reference layout.</param>
|
||||||
/// <param name="addMissing">True to add missing elements to base layout that exist in a reference layout.</param>
|
/// <param name="addMissing">True to add missing elements to base layout that exist in a reference layout.</param>
|
||||||
/// <param name="missingSlotOverride">Allows to override the input slot for missing elements. Use value -1 to inherit slot from the reference layout.</param>
|
/// <param name="missingSlotOverride">Allows to override the input slot for missing elements. Use value -1 to inherit slot from the reference layout.</param>
|
||||||
|
/// <param name="referenceOrder">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.</param>
|
||||||
/// <returns>Vertex layout object. Doesn't need to be cleared as it's cached for an application lifetime.</returns>
|
/// <returns>Vertex layout object. Doesn't need to be cleared as it's cached for an application lifetime.</returns>
|
||||||
static GPUVertexLayout* Merge(GPUVertexLayout* base, GPUVertexLayout* reference, bool removeUnused = false, bool addMissing = true, int32 missingSlotOverride = -1);
|
static GPUVertexLayout* Merge(GPUVertexLayout* base, GPUVertexLayout* reference, bool removeUnused = false, bool addMissing = true, int32 missingSlotOverride = -1, bool referenceOrder = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// [GPUResource]
|
// [GPUResource]
|
||||||
|
|||||||
Reference in New Issue
Block a user