Mark Flamer

I am trying to create some methods to manipulate various parts of the XNA vertex structs. I want to be able to pass all the different vertex types as arguments to these methods. Because they are structs they don't derive from a base class other than ValueType. If I use ValueType as the parameter I don't have access to the propertys of the vertex. Is this a case where refelection would be usefull Can anyone help me find a way to write a method that can access the position property of any type of vertex. I hope I have been clear enough. Thanks.

Re: XNA Framework general use of XNA vertex types?

Brandon Bloom

If at all possible, can you move your processing to build time

At build time, you can make use of Microsoft.Xna.Framework.Content.Pipeline.Graphics.VertexContent and the various channel properties and such.





Re: XNA Framework general use of XNA vertex types?

Mark Flamer

I'm using my own model classes that all derive from my base Geometry class which uses generics for a vertex array because I don't want to write different classes to support each possible type of vertex. I am looking for a way to use the common elements of all vertex types. It would be easy if the vertex types all inherited from a base vertex class that had a position field but they are structs, of course. If all else fails I guess I can use a switch to check for each type but that just seems like code bloat and I may want to implement custom vertex types in the future. Thanks alot for the reply.



Re: XNA Framework general use of XNA vertex types?

Derek Nedelman

This is one of the unfortunate aspects of using C#. It's simply not possible to do what you want to do with structs without coming up with a lot of workarounds. Reflection won't help you either since, as you've noted, you're using a value type (you can call the reflection methods without errors but the values won't stay).

One thing you can try is keeping your model components (normals, vertices, and so on) in separate vertex buffer streams. Then, when you set your vertex buffers into the device, you'll do something like

device.Vertices[0].SetSource(positionVertexBuffer, ...)
device.Vertices[1].SetSource(normalVertexBuffer, ...)

and so on.





Re: XNA Framework general use of XNA vertex types?

Shawn Hargreaves - MSFT

You could do this using reflection. That is very slow compared to regular code, but also incredibly powerful. Whether it will be too slow or not really depends on where you are running this code: if it's part of the build process, reflection might be fine, but you probably don't want to be doing that inside your main game loop.

Try something like:

FieldInfo field = typeof(MyVertexType).GetField("Position");

field.SetValue(myVertexObject, newPositionValue);

But beware: to make this sort of code work correctly for structs you will have to explicitly box them first. The SetValue method takes the instance as type object, which will box it: if your original data wasn't already boxed, that will end up setting a new value onto a copy of the instance, which isn't what you want. Takes some care, and a good understanding of the CLR type system, to make this work.

Alternatively, you could use an interface:

interface IMyVertex
{
Vector3 Position { get; set; }
}

Implement that in each of your different vertex types, and then you can put a "where T : IMyVertex" constraint on your generics that will let you access the Position property through the interface.

This only works for properties, not raw fields, and you obviously can't use it with the builtin XNA vertex types (you'll have to make your own structs in order to implement the interface).




Re: XNA Framework general use of XNA vertex types?

Mark Flamer

I've decided reflection is not the way to go. I thought about the interface method also, may use that. This seems like an issue that others have or will encounter. It's hard to imagine only using one vertex type in a graphics engine. Thanks again for the imput!



Re: XNA Framework general use of XNA vertex types?

Shawn Hargreaves - MSFT

I'm curious: what are you doing that requires you to modify the position data in vertices of unknown types





Re: XNA Framework general use of XNA vertex types?

Leaf.

One other option is to parse the VertexElement[] for the vertex structure and then treat the vertex array as a byte[] and use pointers and the offsets and size that you've parsed from the VertexElement[]. The initial parsing of the VertexElement[] takes a little effort but then you could wrap that in adaptor classes that make accessing the elements easy.

Cheers,
Leaf.






Re: XNA Framework general use of XNA vertex types?

Mark Flamer

I may be overlooking something basic. I have only been programing for 6mo (noob). I have a base geometry class that all my geometry types inherit from. I diddn't want to restrict these classes to using a paticular vertex type. So I used generics to store my vertices. I am also working on a system for batching draw calls based on texture, effect, primative type ect. I want this class to be able to use any type of vertex for sorting. Does that make sense



Re: XNA Framework general use of XNA vertex types?

Shawn Hargreaves - MSFT

Mark Flamer wrote:
I may be overlooking something basic. I have only been programing for 6mo (noob). I have a base geometry class that all my geometry types inherit from. I diddn't want to restrict these classes to using a paticular vertex type. So I used generics to store my vertices. I am also working on a system for batching draw calls based on texture, effect, primative type ect. I want this class to be able to use any type of vertex for sorting. Does that make sense


Sure. But why does any of this code need to modify the position values in these vertices





Re: XNA Framework general use of XNA vertex types?

Lord Asriel

You can do something like that :

/// <summary>

/// <para>Custom vertex typesfor ground.</para>

/// </summary>

[StructLayout(LayoutKind.Sequential)]

public struct ObjectVertex

{

/// <summary>

/// <para>Vertex position on X-axis.</para>

/// </summary>

[VertexProperty(VertexPropertyType.X)]

public float X;

/// <summary>

/// <para>Vertex position on Y-axis.</para>

/// </summary>

[VertexProperty(VertexPropertyType.Y)]

public float Y;

/// <summary>

/// <para>Vertex position on Z-axis.</para>

/// </summary>

[VertexProperty(VertexPropertyType.Z)]

public float Z;

[...]

}

The attribute specifie the description of the propertie. Then explore your vertex type to find wich kind of member you want.

Type type = typeof(T);

for(int i = 0 ; i < type.GetFields().Length ; i++)

{

FieldInfo fi = type.GetFields()Idea;

if (fi.GetCustomAttributes(typeof(VertexProperty), false).Length == 0)

continue;

VertexProperty attr = (VertexProperty)fi.GetCustomAttributes(typeof(VertexProperty), false)[0];

if (attr.PropertyType == VertexPropertyType.X)

indexX = i;

if (attr.PropertyType == VertexPropertyType.Y)

indexY = i;

if (attr.PropertyType == VertexPropertyType.Z)

indexZ = i;

if (attr.PropertyType == VertexPropertyType.Format)

indexFormat = i;

}

I have a code that run on it here. I juste make 3 instruction to create a MRM :

ProgressiveMesh<ObjectVertex> mesh = new ProgressiveMesh<ObjectVertex>(vertices, ints, null);

mesh.Load(this._device);

this.mesh.Render();

Even if i dont know the type of the vertices array i gived to the constructor my render method know that Format, and my compurtings method can extract position from each vertices to build a ProgressiveMesh. How with Attributes :)





Re: XNA Framework general use of XNA vertex types?

Mark Flamer

Sure. But why does any of this code need to modify the position values in these vertices

I was hoping to avoid making seperate draw calls for each object that has a different WVP matrix when they are static and don't change from frame to frame. My solution (hopefully) is to seperate my static geometry and pre-transform the vertices before combining into one static vertex buffer. Then I only have to make a few calls. The pre-transformation of the vertices is where this question came from.





Re: XNA Framework general use of XNA vertex types?

Mark Flamer

I have run into this situation again. Your solution seemed promising but I am having a little trouble understanding it. I went to your website but it is in french (I think). Can you explain any further Thanks!