Question

I am using DirectX 9 in C#
I store all my vertices in a list (not an array) because I use a dynamic LOD algorithm, so everything is calculated per frame, so my vertices could potentially be different every frame.

Everything works fine until I tried to add normals and lighting.
I found out that you can't edit the normal once you add a vertex to a list, because it is a list of structs rather than classes. So it just gives an error like "can't modify the return value of blablaba because it is not a variable"
For example if I tried to do this it won't work -

vertices[i].Normal = new Vector3(0, 1, 0);

Normals have to be added when the vertex is put in the list, but you can't calculate normals until you have a full mesh.

So I made a new custom vertex type, and instead of making it a struct I made it a class. This doesn't work either because directx won't accept it unless it is a struct...

So then I tried to make it work with arrays instead of a list of vertices. This resulted in having less than one frame per second. I had to use Array.Resize to change the size of my array a few hundred times per frame and I guess it didn't like that.

You are probably thinking I should turn the final list into an array, and then calculate the normals from there. This won't work because the vertices aren't added in any particular order, so I can't know which vertices are near a given vertex to be able to calculate a normal.

So how can I store my vertices in a way where I can give them normals after I have my mesh built?

Was it helpful?

Solution

C# prevents you from writing vertices[i].Normal = new Vector3(0, 1, 0) because that expression wouldn't do what you wanted. Unlike an array indexer, the List<T> indexer returns a copy of the specified element, and because the vertex is a struct, the whole vertex is copied, Normal and all. You would be updating a temporary copy of the vertex, not the actual vertex that's inside the list.

The workaround is to get (a copy of) the vertex from the list, update it, and put (a copy of) it back:

var vertex = vertices[i];
vertex.Normal = new Vector3(0, 1, 0); 
vertices[i] = vertex;

It's unfortunate that there's no simple way to avoid this repeated copying.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top