1

I have read many articles saying to interleave vertex attributes by putting the data in a structure

struct Vertex
{
  XMFLOAT2A vertex;
  XMFLOAT3A color;
  .
  .
  .
 }

This works fine for tutorials but for real world models loaded from obj,colladae files, etc. It is impossible to know how many attributes a mesh contains in advance and you can't write every possible structure containing all possible combinations of attributes.

The only solution is to read all attributes first and then merge them into one large array.

The problem is I tried this approach and it doesn't work.

So how do I interleave an unknown number of attributes known only at run time? What should be the alignbyteoffset in the INPUT_LAYOUT_DESC? How do I interleave the data OpenGL style?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Sync it
  • 1,180
  • 2
  • 11
  • 29
  • 1
    For arbitrary models, you don't store them as strongly-typed structs. You just create an InputLayout that matches the binary layout of the vertex buffer(s) and use that. See *DirectX Tool Kit* [Model](https://github.com/microsoft/DirectXTK/blob/master/Inc/Model.h) for an example. The main issue with shader binding is that your shaders need the attributes in a consistent order. – Chuck Walbourn Nov 18 '20 at 04:26
  • Do I store the data as actual interleaved XMFLOAT data types or do I create an large float array and specify the byte offsets then? Will the later even work since data must be alligned in an 16 byte boundary? – Sync it Nov 18 '20 at 06:31
  • The VertexBuffer and IndexBuffer are usually just byte arrays for dynamic vertex layouts. – Chuck Walbourn Nov 18 '20 at 07:11
  • if i want to interleave lets say float and int[vertex joints] data into an byte array how would i do that? – Sync it Nov 18 '20 at 07:41

1 Answers1

0

After days of typed structs and error's i have finally found a way using memcpy

you can interleave pretty much any types of objects or primitive datatypes into an char array using this technique

DirectX::XMFLOAT2 vertices[4] =
 {
   DirectX::XMFLOAT2(0.5f,0.5f)
  ,DirectX::XMFLOAT2(-0.5f,0.5f)
  ,DirectX::XMFLOAT2(-0.5f,-0.5f)
  ,DirectX::XMFLOAT2(0.5f,-0.5f)
 };

 DirectX::XMINT3 colors[4] =
 {
   DirectX::XMINT3(1,0,0)
  ,DirectX::XMINT3(0,1,0)
  ,DirectX::XMINT3(1,0,1)
  ,DirectX::XMINT3(1,1,0)
 };

 char data[sizeof(DirectX::XMFLOAT2) * 4 + sizeof(DirectX::XMINT3) * 4];
 char* ptr = data;
 DirectX::XMFLOAT2* vertex = vertices;
 DirectX::XMINT3* color = colors;

 for (int i = 0; i < 4; i++)
 {
   memcpy(ptr, vertex, sizeof(DirectX::XMFLOAT2)); //Copy & increment char pointer and vertex pointer
   ptr += sizeof(DirectX::XMFLOAT2);
   vertex += 1;

   memcpy(ptr, color, sizeof(DirectX::XMINT3)); //Copy & increment char pointer and color pointer
   ptr += sizeof(DirectX::XMINT3);
   color += 1;
 }

Any suggestions or edit's to this solution are greatfully accepted

and as for the alignbyteOffset we can use D3D11_APPEND_ALIGNED_ELEMENT and not worry about that

Sync it
  • 1,180
  • 2
  • 11
  • 29