Converting .dds to .png: is XNA really this convoluted?
-
27-09-2019 - |
Question
I have a .dds file and I want a .png file. Although I already found out about the DevIL.NET library, the API design there of one static class does not parallelize, so I am hoping to find another method. This led me to XNA.
But, here's how far I got with that idea...
- OK, it looks like I want this
Texture2D
class; then I can callmyTexture2D.SaveAsPng
. - But how do I get one of those from my .dds file? Well the documentation seems to indicate I want to use
myContentManager.Load<Texture2D>
. - Oh crap, that wasn't it, that's some kind of game content management system. Well, my searching seems to have turned up a lot of uses of
myTexture2D.LoadFile
; I'll go for that. - Uh am I missing an assembly reference or something? Oh no, I get it, they removed that method between 3.1 and 4.0, awesome. OK, well, it's a bit more annoying, but
myTexture2D.LoadStream
isn't really a problem. - Wait what's this now? It wants a
GraphicsDevice
? Hmm it looks like one usually gets one of those via aGraphicsDeviceManager
... oh wait, I'm not going down that path again, no moreManager
s for me. - I guess I'm supposed to instantiate this thing manually. OK well this isn't too hard...
var myGraphicsDevice = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, GraphicsProfile.HiDef,
(uh oh what is thisPresentationParameters
thing well OK I'll just trynew PresentationParameters());
. - Well that threw an exception. They want... a
DeviceWindowHandle
in myPresentationParameters
? BUT I'M RUNNING A CONSOLE APP!!
So I'm really hoping there's a less convoluted way of doing this; perhaps some kind of default GraphicsDevice
I could use. It feels pretty silly to create a whole window just to convert .dds to .png.
Alternative suggestions for my conversion problem welcome, I guess, although it would probably be worthwhile to understand how to use XNA from non-XNA code in general.
Solution
If you have a command line app that needs to create an XNA graphics device, the code in this answer should be of some assistance.
In a nutshell, you need some of the classes from the WinForms sample to avoid having to mess around creating a graphics device services and so on (specifically the classes ServiceContainer
and GraphicsDeviceService
).
Then you can do this:
Form form = new Form(); // Dummy form for creating a graphics device
GraphicsDeviceService gds = GraphicsDeviceService.AddRef(form.Handle,
form.ClientSize.Width, form.ClientSize.Height);
ServiceContainer services = new ServiceContainer();
services.AddService<IGraphicsDeviceService>(gds);
content = new ContentManager(services, "Content");
Tada - now you have a working ContentManager
that you can use to load stuff. I believe you should be able to get the actual GraphicsDevice
from the GraphicsDeviceService
, too.
The form you create is never displayed. Remember to reference System.Windows.Forms.dll
in your project.
Disclaimer: This was written for XNA 3.1. I haven't tested it in 4.0, but I suspect it will work with little or no modification.
OTHER TIPS
From the top of my head (haven't used XNA for a while):
- Conversion of datatypes is not a common scenario for XNA. It expects to get all assets preprocessed by the content pipeline.
- XNA expects the graphics device quite often, windowless applications are out of XNAs scope.
It seems to me that you are using the wrong tool for the job, although I couldn't tell another one except DevIL, which you already dismissed.