Usability Helpers

Published July 24, 2008
Advertisement
Whenever I'm writing code I'm always thinking of ways to improve what I'm writing. Every once in a while I run across a bit of code that I know could be easier or look nicer or be more performant (which, incidentally, isn't even a real word), so I usually take a little time to clean it up and make it look nice.

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?
Previous Entry Sample Game
Next Entry Sexy Code
0 likes 2 comments

Comments

Tape_Worm
That's pretty awesome.

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.
July 24, 2008 11:59 PM
Mike.Popoloski
Quote:Original post by Tape_Worm
That's pretty awesome.

Thanks :)

Quote: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.

If that's the case, simply ensure that your Position element is the first in the vertex structure, and probably put a StructLayout attribute on it for good measure as well. Otherwise, you don't need to worry.

Quote: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)]?

Yes, the DeclarationMethod and the Stream index are named properties of the attribute. They just don't have a constructor parameter because they are much more rarely used.

Quote: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.

The system will automatically determine the correct usage for each element. If you declare two texture coordinates, for example, the first will have a usage of 0, the next 1, etc.

July 25, 2008 06:24 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement

Latest Entries

New Blog

2051 views

Progress Update

1565 views

Start of Project

1527 views

New Job

2262 views

The Downward Spiral

2911 views

Job Interviews

1511 views
Advertisement