This question is from someone who has not written a line of code for games, but several Game Save editors and other game tools.
I'm working on a Save Editor and would like to display icons of some of the game assets in C# WPF .NET 4.0, or at least convert them to PNG in memory, so I can display them without having to make copies of them. The assets are stored as .dds
texture files in BC3_UNorm
.
I've trawled Google results that either use SharpDX or XNA, but all the ones I've found either do not work (as the sample code is for an old version of the library), or I just plain don't understand (in the case of XNA).
How can I load a BC3_UNorm
Texture file, either in SharpDX, or XNA for conversion? Sample code would be very welcome.
Here's a sample input file.
This is the only code I could get running, but it's missing some of the RGBA channels and the output looks nothing like the original:
public static System.Windows.Media.Imaging.BitmapSource ConvertTK(string filename)
{
try
{
// Create the graphics device
using (var graphicsDevice = SharpDX.Toolkit.Graphics.GraphicsDevice.New(SharpDX.Toolkit.Graphics.GraphicsAdapter.Default, SharpDX.Direct3D11.DeviceCreationFlags.SingleThreaded))
{
// Load the texture
using (var texture = SharpDX.Toolkit.Graphics.Texture2D.Load(graphicsDevice, filename))
{
// Copy the pixel colors into a byte array
var bytesPerPixel = 3;
var pixelChannel = texture.GetData<byte>();
var pixelData = new byte[pixelChannel.Length * bytesPerPixel];
// Where are the RGBA channels? It only has 1 byte per pixel!
for (var i = 0; i < pixelChannel.Length; i++)
{
pixelData[i * bytesPerPixel + 0] = pixelChannel[i];
pixelData[i * bytesPerPixel + 1] = pixelChannel[i];
pixelData[i * bytesPerPixel + 2] = pixelChannel[i];
}
// Result Image is garbage, looks nothing like original .DDS BC3_UNorm file.
// Create a bitmap source
var stride = texture.Width * bytesPerPixel;
return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Rgb24, null, pixelData, stride);
}
}
}
catch (Exception ex)
{
}
return null;
}