Saturday, March 01, 2008

XNA Line Thickness

I've been searching for a method to display a thick line in XNA. There isn't a method in XNA as OpenGL's glLineWidth. So you have to construct you own line from triangles. I've found and tried this method. The line were rounded at each edge, and the whole scene looked pretty impressive. The problem was that my application had to render thousands of lines, and doing rounded edges and indexed triangles wasn't very performant. I wanted something much more simple, without rounded edges, but considering line joints. I developed a really simple and performant method to do this. The idea was to take a line strip (the array of Vector3[]) and build a triangle strip, which is the most performant method for rendering, and store it in a vertex buffer. This method is almost as performant as drawing simple lines!
I think that the code is pretty self explaining:

triangleCount =-2;
private List<VertexPositionColor> GetTriangleStrip(Vector3[] points, float thickness)
{
Vector3 lastPoint = Vector3.Zero;
List<VertexPositionColor> list = new List&ltVertexPositionColor>();
for (int i=0;i<points.Length;i++)
{
if (i == 0) { lastPoint = points[i]; continue; }
//the direction of the current line
Vector3 direction = lastPoint - points[i];
direction.Normalize();
//the perpendiculat to the current line
Vector3 normal = Vector3.Cross(direction, Vector3.UnitZ);
normal.Normalize();
Vector3 p1 = lastPoint + normal * thickness; triangleCount++;
Vector3 p2 = lastPoint - normal * thickness; triangleCount++;
Vector3 p3 = points[i] + normal * thickness; triangleCount++;
Vector3 p4 = points[i] - normal * thickness; triangleCount++;
list.Add(new VertexPositionColor(p1, Color.Black));
list.Add(new VertexPositionColor(p2, Color.Black));
list.Add(new VertexPositionColor(p3, Color.Black));
list.Add(new VertexPositionColor(p4, Color.Black));
lastPoint = points[i];
}
return list;
}
Then you just have to store the list in a vertex buffer and render it as a triangle strip with "triangleCount" primirives.

Friday, February 29, 2008

Localizing Domain Driven Design?

I've recently read "Domain-Driven Design: Tackling Complexity in the Heart of Software" - Eric Evans, and was pretty excited by the ubiquitous language which everybody should use, the developers, the analysts, the domain experts, etc...

There is a problem though: we - developers tend to use the english language in our code, and the clients and analysts use Romanian language (I'm from Romania). So would there be two ubiquitous languages, should the developers switch to using Romanian in their code (class names, methods...), or should the analytsts switch to english terms?

For example, we are developing a GIS application, so we (the developers) use terms like "feature", "feature type", "feature attribute", "feature store", "layer", "map context", and other words used by all GIS applications and by OGC. I can't imagine
how we should understand each other if we were using the Romaning translations of these words. So, we can't switch the ubiquitous language to Romanian, but I believe that we can't use english terms with our clients either. There is an important thing to mention: there are no domain experts for GIS involved in our project; there are only clients who want to see a map, so we have to define our own ubiquitous language. So what to do?

I'm e developer, so I tend to use english for the ubiquitous language...

Thursday, February 28, 2008

XNA application on NVidia Quadro FX 370

I tested today my application, which uses a lot of textured quads to display a GIS map on a NVidia Quadro FX 370. I expected good results, knowing this is a professional graphic card (although it is entry level), and because it had 256 MBytes RAM - a lot of space for my textures. But surprise - the application performance was actually worse than on my onboard Intel 82945G Express!

I didn't know almost nothing about NVidia Quadro, except it is expensive and it is a "professional" card. After some research, I found that NVidia Quadro it has some improvements for CAD applications, like hardware antialiased lines, and stuff like that. So it isn't very good for gaming - and my XNA application could be compared to a game.

I'm not sure what to do next. Maybe move to a vectorial rendering to make use of the Quadro skills, although I have no ideea if XNA has anything to do with these "skills"...

I just wish I had known earlier that our customers would use this graphic board, so they didn't spend their money in vain, when they could have bought a cheap GeForce and have better performance.

XNA Texture2D.FromFile too slow for background texture loading?

I've been working for some time on rendering with XNA GIS data, especialy WMS tiles. I tried to do something like NASA World Wind or Virtual Earth. I downloaded png files from the WMS server and loaded them using Texture2D.FromFile method. Because there were so many textures, I had to develop a method to load/unload them at runtime.

The problem was that Texture2D.FromFile performance was very poor. I did some research, and saw that NASA World Wind caches the textures in a .dds file. Direct Draw Surface format.It had to work better with dds files than with png (which is a compressed format by the way, and of course we expect the decoding to take some time...).

So I tried to convert the received png file into a dds format, in order to increase tile cache access speed when loading/unloading images. I did something like this:

Texture = Texture2D.FromFile(device, "image.png");
Texture.Save("image.dds", ImageFileFormat.Dds);

When calling Texture2D.FromFile(XnaFactory.Device, "image.Dds"), the performance was greatly improved. When you load the texture at first, from the png file, or whatever other format, you can also specify TextureCreationParameters. For example I use
TextureCreationParameters.SurfaceFormat = SurfaceFormat.Dxt1 so the textures will be compressed.

Also, the resulting dds file would give you a good approximation about how much memory would be used in the graphic card for the texture.