MD3DM Direct3D Texturing Bug
I have been playing around at home with coding for Windows Mobile 5, and while poking around, I was excited to see that there is an implementation of Direct3D. I haven't done any DirectX programming since 1998 or so and I thought it'd be fun to pick it up and see what they've done with it and to also see what my Cingular 8525 can do.
I downloaded sample code from Microsoft and immediately found out that the texturing demo crashes with an InvalidCallException in Surface.UnlockRectangle. This is a result of using the TextureLoader class, which is the only public API for turning images into textures. This is pretty bad, I think and very disappointing
as well, but I'm a stubborn cuss and I decided to see if I could construct a functioning Texture on my own. That turned out to be straight forward, except for one detail. I had to figure out which texture format is suitable for my device.
I wrote a little routine that tries them all out and only keeps the working ones. For the 8525, you can render textures from 32 bit bgra and 16 bit rgb (5-6-5). Just 2? That's disappointing too. Anyhow, once I figured that out, I was able to create a synthetic Texture and get the demo working. Nice.
Because that's possible, it means that I can write a converter to go from Bitmap objects into Texture objects. It involves some unsafe code (this is for performance reasons and ease of coding, really) and a lot of bit twiddling, but it works, and I'm offering to those who are interested in using it.
In the original Microsoft sample code, this is the line that fails:
texture = TextureLoader.FromStream(dev,
Assembly.GetExecutingAssembly().GetManifestResourceStream(
"Texture.Content.Banana.bmp"));
you can now replace it with this code:
ReliableTextureLoader loader = new ReliableTextureLoader(dev);
texture = loader.FromStream(loader.GetBestFormat(),
Assembly.GetExecutingAssembly().GetManifestResourceStream(
"Texture.Content.Banana.bmp"), PixelFormat.Format24bppRgb);
The entire class should be downloadable here. You can drop this file into your managed Direct3D application and use it pretty much wherever you'd use TextureLoader. I've written it for the sole purpose of getting textures working on my phone, but it's extensible and should be capable of growing into the future.
In reflection, this is a very empowering exercise because of the immediate problems I found in Direct3D. It's frustrating to have so much potential and to hit a roadblock right away, but it's great to be able to build a functioning workaround. It took me 4 hours while I rode the learning curve, but I'm still pretty happy with the outcome. Unfortunately, this experience is also all too familiar. 10 years ago I was working at a company that was writing a high speed 3D engine and we had a box of 3D cards that were basically bricks because the drivers made them unusable in any reasonable way, or our own software renderers were faster than the card (!!). I've read a little but about the D3D driver for this device and it hasn't been really complimentary.
Hopefully this post might turn a few heads and maybe Microsoft or HTC (the phone manufacturer) will publish an updated driver before the device goes obsolete.