| 221 | } |
| 222 | |
| 223 | GPUVertexLayout* GPUVertexLayout::Merge(GPUVertexLayout* base, GPUVertexLayout* reference, bool removeUnused, bool addMissing, int32 missingSlotOverride, bool referenceOrder) |
| 224 | { |
| 225 | GPUVertexLayout* result = base ? base : reference; |
| 226 | if (base && reference && base != reference) |
| 227 | { |
| 228 | bool elementsModified = false; |
| 229 | Elements newElements = base->GetElements(); |
| 230 | const Elements& refElements = reference->GetElements(); |
| 231 | if (removeUnused) |
| 232 | { |
| 233 | for (int32 i = newElements.Count() - 1; i >= 0; i--) |
| 234 | { |
| 235 | bool missing = true; |
| 236 | const VertexElement& e = newElements.Get()[i]; |
| 237 | for (const VertexElement& ee : refElements) |
| 238 | { |
| 239 | if (ee.Type == e.Type) |
| 240 | { |
| 241 | missing = false; |
| 242 | break; |
| 243 | } |
| 244 | } |
| 245 | if (missing) |
| 246 | { |
| 247 | // Remove unused element |
| 248 | newElements.RemoveAtKeepOrder(i); |
| 249 | elementsModified = true; |
| 250 | } |
| 251 | } |
| 252 | } |
| 253 | if (addMissing) |
| 254 | { |
| 255 | for (const VertexElement& e : refElements) |
| 256 | { |
| 257 | bool missing = true; |
| 258 | for (const VertexElement& ee : base->GetElements()) |
| 259 | { |
| 260 | if (ee.Type == e.Type) |
| 261 | { |
| 262 | missing = false; |
| 263 | break; |
| 264 | } |
| 265 | } |
| 266 | if (missing) |
| 267 | { |
| 268 | // Insert any missing elements |
| 269 | VertexElement ne = { e.Type, missingSlotOverride != -1 ? (byte)missingSlotOverride : e.Slot, 0, e.PerInstance, e.Format }; |
| 270 | if (e.Type == VertexElement::Types::TexCoord1 || |
| 271 | e.Type == VertexElement::Types::TexCoord2 || |
| 272 | e.Type == VertexElement::Types::TexCoord3) |
| 273 | { |
| 274 | // Alias missing texcoords with existing texcoords |
| 275 | for (const VertexElement& ee : newElements) |
| 276 | { |
| 277 | if (ee.Type == VertexElement::Types::TexCoord0) |
| 278 | { |
| 279 | ne = ee; |
| 280 | ne.Type = e.Type; |