chronosifter's picture

Struct alignment for vertex attribs

I'm having trouble getting C# structs to align with vertex attribs whenever I use any types which aren't 4-components in size. I first noticed the problem when I was passing position as a 3-component vector, dismissed it as OpenGL requiring a w-component on position, but it's reappeared after I switch out a struct that only passed position and color for one that passes position, color, and texture coordinate.

This struct works just fine, because both elements in the struct are 4-component vectors, the floatN types you see are structs in XYZW order:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct VertexPositionColor
{
    [VertexElement("Position", VertexAttribPointerType.Float, 4)]
    public float4 Position;
    [VertexElement("Color", VertexAttribPointerType.Float, 4)]
    public float4 Color;
}

This one however has components from Color and TexCoord mixed up:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct VertexPositionTextureColor
{
    [VertexElement("Position", VertexAttribPointerType.Float, 4)]
    public float4 Position;
    [VertexElement("TexCoord", VertexAttribPointerType.Float, 2)]
    public float2 TexCoord;
    [VertexElement("Color", VertexAttribPointerType.Float, 4)]
    public float4 Color;
}

As far as the attributes and how the vertex attribs are set up, the following two objects are used to handle that.
VertexElementAttribute
VertexElement

When it comes to setting data into the buffer objects, I'm using MapBufferRange (or MapBuffer when not supported) for OpenGL and BufferSubData for OpenGL ES 2.0. For managing buffers I use a generic BufferObject, with a generic parameter DataType specifying what type of data is stored in the buffer (restricted to structure types with additional checks in the constructor to verify the type can be used for the specified buffer type). SetData is used to set data into the buffer.

I'm not at all interested in using fixed function pipeline methods to set the vertex data. I'm primarily a graphics programmer so I need to be able to set arbitrary data into the vertex buffers. I really don't like the idea of passing 4-component vectors for every vertex element, that would be very wasteful for some of the things I want to bring over from my Direct3D engine.