Suggestion for stock Vertex structs

I notice that the framework provides a few stock vertex structures like VertexPositionColor etc.

This is cool but it would be great if these could inherit from an interface which provides a mechanism to get the SizeInBytes and Element information abstractly.

These structs currently provide this information as static properties but this is no good if you are are trying to write a generic function that can deal with a number of different types of vertex structures seamlessly.

My suggestion is that in future something like an IVertexInfo is provided that lets you deal with these concrete vertex structures abstractly.  Perhaps something like this.

interface IVertexInfo
{
    VertexElement[] Elements { get; }
    int SizeInBytes { get; }
}

struct MyVertexPositionColor : IVertexInfo
{
    public static readonly VertexElement[] Elements = {
        new VertexElement(0, 0,  VertexElementFormat.Vector3, VertexElementMethod.Default, VertexElementUsage.Position, 0),
        new VertexElement(0, 12, VertexElementFormat.Vector4, VertexElementMethod.Default, VertexElementUsage.Color, 0)
    };
    public static readonly int SizeInBytes = 12;

    public Vector3 Position;
    public Color Color;

    #region IVertexInfo Members

    VertexElement[] IVertexInfo.Elements
    {
        get { return MyVertexPositionColor.Elements; }
    }

    int IVertexInfo.SizeInBytes
    {
        get { return MyVertexPositionColor.SizeInBytes; }
    }

    #endregion
}

Anyway something to think about.  Now I'll get back to having fun!



Answer this question

Suggestion for stock Vertex structs

  • JackHsueh

    You can't do that since the struct has to be exactly the size it's defined, and what you want would require a vtable pointer (or whatever C# has instead) which would make it a class. Unlike C++, C# classes and structs are different, in that structs are simple POD (Piece of Data) which is what you want to put in vertex buffers, while classes can inherit, implement interfaces, etc.

    EDIT: Yeah much of the above is wrong. I'm still pretty new to managed code and tend to think in terms of C++, forgetting that the runtime has a lot more type info so it can do some magic...

  • streetlightman

    Yes I reflect the fields. In the case of Direct3D 10 I don’t need to worry about the semantic because Direct3D 10 use strings.

    In the case of D3D9 an attribute can solve it or use fieldnames that are equal to the names that are used in HLSL



  • Anil Narayanan

    Actually I guess what you are saying is not to have any vertex declaration at all in the struct and then build the vertex declaration on the fly from reflecting the fields.

    In this case I guess you would have to deal with semantics, so I suppose for that you could define some custom attributes to mark up the fields of the struct. Is this what you are saying Ralf


  • Puntor

    It's not the size that is the interesting part, it's the vertex declaration
  • Lorry Craig

    I do the same thing for my managed Direct3D 10 wrapper. The input layout (nearly the same as a vertex declaration) class has a special constructor that takes a Type. Then it used reflection to build the description on the fly. The beauty with this solution is that it works with custom vertex structures too. I could even support multi stream with a constructor that takes an array of types. One per stream.



  • Saqib Shazhad

    You could always use reflection to do this - a 10 line helper function could get you the size of any of those vertex types, and as long as you cached the result and weren't calling it 4000 times per frame it wouldn't hurt performance at all.

  • Puffarbubbole

    To make sure suggestions get to the XNA team make sure to follow these instructions

    http://letskilldave.com/archive/2006/08/30/Did-you-find-a-bug-in-XNA_3F00_--Here_2700_s-what-you-do_2E002E002E00_.aspx



  • David Hanak

    Exactly, but are you saying there is a problem with my proposed solution of adding an interface

    As I said it is cheaper to use an interface rather than use reflection and I am almost 100% certain that it has zero cost if you never use the interface.


  • omar_rapid

    I'm pretty sure that adding an interface to a value type has no side effects on the layout of the struct.

    All that will happen is that the struct will get box'd prior to the callvirt on the interface method. While boxing isn't super cheap it's a heck of a lot cheaper than using reflection.


  • QuantumMischief

    No I don’t see a technical problem with your interface approach. The PackedVector classes use an interface too. It more a general problem with the question which vertex formats are qualified as standard formats and if this number justify an additional common way. Such things have the tendency to become “good praxis” and then everybody things every custom vertex structure needs to implement such an interface too.

    Creating the unmanaged DirectX object would be expensive anyway there I have no problem to lost some CPU cycles for the reflection.



  • RemcoJVG

    You don’t need reflection. Getting the size of a struct is exactly one instruction:

    int size = Marshal.SizeOf (typeof(SimpleVertex));

    Normally its part of the compact framework but I am not sure about the Xbox 360 version.

    But reflection could be useful too



  • Suggestion for stock Vertex structs