One example of this that I ran into recently while writing my Asteroids game for SlimDX was vertex declarations. Every time you need a new type of vertex in any DirectX application, you need a new vertex declaration (assuming you aren't using the FFP). The process of creating a vertex declaration is tedious at best, and it's annoying to find a spot to stick it. So I set about writing a nice reflection based approach to make things easier.
Basically, in the new system you mark up your vertex structure with some attributes describing each piece of vertex data. The system will automatically calculate the offset for each piece of data, and build the vertex declaration appropriately. Here's an example of a vertex structure used by Asteroids:
struct VectorModelVertex{ [VertexElement(DeclarationType.Float2, DeclarationUsage.Position)] public Vector2 Position { get; set; } [VertexElement(DeclarationType.Color, DeclarationUsage.Color)] public int Color { get; set; } [VertexElement(DeclarationType.Float1, DeclarationUsage.TextureCoordinate)] public float Padding { get; set; } public VectorModelVertex(Vector2 position, int color) : this() { Position = position; Color = color; } public static int SizeInBytes { get { return Marshal.SizeOf(typeof(VectorModelVertex)); } }}declaration = GraphicsDeviceManager.Direct3D9.CreateVertexDeclaration(typeof(VectorModelVertex));
As you can see, it's easy to declare new pieces of vertex data without worrying about adjusting all the offsets and making sure you got the size of each entry just right. It's a rather simple improvement, but it makes life easier, the code more intuitive, and it's a pretty damn cool use of reflection to boot. I'm happy with it, so I stuck it into the SampleFramework. What do you guys think?
While most modern cards should be able to handle this, what about element (re)ordering? If I recall, there needs to be a specific order for the elements on some older cards. I'm pretty sure you need to guarantee that Position is the first element in any case.
Also, what about streams? If I want to assign the texture coordinates to stream 1 can I do something like: [VertexElement(DeclarationType.Float2, DeclarationUsage.TextureCoordinates, 1)]?
There's also a context flag (UsageIndex) too, for example, if I want to embed the specular color into the vertex format I can do a DeclarationType.Color and DeclarationUsage.Color but specify 1 for its UsageIndex.
Those things would be super duper handy.