views:

1078

answers:

4

I am writing a c# control that wraps DirectX 9 and provides a simplified interface to perform 2d pixel level drawing. .NET requires that I wrap this code in an unsafe code block and compile with the allow unsafe code option.

I'm locking the entire surface which then returns a pointer to the locked area of memory. I can then write pixel data directly using "simple" pointer arithmetic. I have performance tested this and found a substantial speed improvement over other "safe" methods I know of.

Is this the fastest way to manipulate individual pixels in a C# .NET application? Is there a better, safer way? If there was an equally fast approach that does not require pointer manipulation it would be my preference to use that.

(I know this is 2008 and we should all be using directx 3d, opengl etc, however this control is to be used exclusively for 2d pixel rendering and simply does not require 3d rendering.)

+1  A: 

I recently was tasked with creating a simple histogram control for one of our thin client apps (C#). The images that I was analyzing were about 1200x1200 and I had to go the same route. I could make the thing draw itself once with no problem, but the control needed to be re-sizable. I tried to avoid it, but I had to get at the raw memory itself.

I'm not saying it is impossible using the standard .NET classes, but I couldn't get it too work in the end.

Ed Swangren
+1  A: 

Using unsafe pointers is the fastest way to do direct memory manipulation in C# (definitely faster than using the Marshal wrapper functions).

Just out of curiosity, what sort of 2d drawing operations are you trying to perform?

I ask because locking a DirectX surface to do pixel level manipulations will defeat most of the hardware acceleration benefits that you would hope to gain from using DirectX. Also, the DirectX device will fail to initialize when used over terminal services (remote desktop), so the control will be unusable in that scenario (this may not matter to you).

DirectX will be a big win when drawing large triangles and transforming images (texture mapped onto a quad), but won't really perform that great with single pixel manipulation.

Staying in .Net land, one alternative is to keep around a Bitmap object to act as your surface, using LockBits and directly accessing the pixels through the unsafe pointer in the returned BitmapData object.

Corey Ross
+1  A: 

yes that is probably the fastest way

a few years ago i had to compare two 1024x1024 images at the pixel level; the get-pixel methods took 2 minutes, the unsafe scan took 0.01 seconds.

Steven A. Lowe
+1  A: 

I have also used unsafe to speed up things of that nature. The performance improvemets are dramatic, to say the least. The point here is that unsafe turns off a bunch of things that you might not need as long as you know what you're doing.

Also, check out DirectDraw. It is the 2D graphics component of DirectX. It is really fast.

Guge