Language: C#
Extension method to use PMA with textures loaded from filesystem
public static class ExtensionMethods
{
public static Texture2D PreMultiplyAlpha(this Texture2D tex)
{
Color[] data = new Color[tex.Width * tex.Height];
tex.GetData<Color>(data);
for (int i = 0; i < data.Length; i++)
{
Color c = data[i];
data[i] = new Color(c.R, c.G, c.B) * (c.A / 255f);
}
tex.SetData<Color>(data);
return tex;
}
}
-----
public Texture2D LoadTexture(GraphicsDevice graphicsDevice, string file)
{
return Texture2D.FromStream(graphicsDevice,
new FileStream(file, FileMode.Open)).PreMultiplyAlpha();
}
Description:
If you want to use pre-multiplied alpha in XNA 4.0 but don't want to load your textures from the Content pipeline, this provides an extension method to convert your textures to PMA-format at load-time.
Report Abuse
Subscribe
Discuss
News
About
New Snippet
Recent Snippets
My Snippets
Favorites
Web Code
Search
Copy
Line#
Thanks!
This worked great for me. Actually, since I had to generate my own mipmaps from a dynamic content pipeline for PNGs, via a TextureImporter -> TextureContent -> MipmapChainCollection step, I had to pass in the rect, level, and count into PreMultiplyAlpha and call it once per level. This fixed my problem with only the top level mipmap having premultiplier alpha whereas I needed each level to have this step.
Works great though. Cheers!
public static Texture2D PreMultiplyAlpha(this Texture2D tex, int level, Microsoft.Xna.Framework.Rectangle? rect, int count)
{
Microsoft.Xna.Framework.Color[] data = new Microsoft.Xna.Framework.Color[tex.Width * tex.Height];
tex.GetData<Microsoft.Xna.Framework.Color>(level, rect, data, 0, count);
for (int i = 0; i < data.Length; i++)
{
Microsoft.Xna.Framework.Color c = data[i];
data[i] = new Microsoft.Xna.Framework.Color(c.R, c.G, c.B) * (c.A / 255f);
}
tex.SetData<Microsoft.Xna.Framework.Color>(level, rect, data, 0, count);
return tex;
}
Calling function :
public Texture2D LoadAlphaTexture(string path, GraphicsDevice graphicsDevice)
{
TextureContent content = importer.Import(path, null);
content.GenerateMipmaps(true);
MipmapChainCollection chainCol = content.Faces;
MipmapChain chain = chainCol[0];
int level = 0;
Texture2D tex = null;
try
{
foreach (BitmapContent pixels in chain)
{
if (tex == null)
tex = new Texture2D(graphicsDevice, pixels.Width, pixels.Height, true, SurfaceFormat.Color);
//copy mipmapped pixels
Microsoft.Xna.Framework.Rectangle? rect = new Microsoft.Xna.Framework.Rectangle(0, 0, pixels.Width, pixels.Height);
byte[] data = PremultiplyAlpha(pixels.GetPixelData());
int count = pixels.Height * pixels.Width;
tex.SetData<byte>(level, rect, pixels.GetPixelData(), 0, count * 4);
tex.PreMultiplyAlpha(level, rect, count);
level++;
}
}
catch (Exception e)
{
return null;
}
return tex;
}
Works great though. Cheers!