# [XNA] Manual "Premultiply Alpha" rendering issue

This topic is 2613 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm using XNA4, and I was rendering everything perfectly to screen using spritebatches on premultiplied alpha PNG's.
Decided to forego the Content.Load that XNA provides and use Texture2D.FromStream in order to dynamically load PNGs, in order for the artist to test graphical changes quicker without recompiling.

In doing so I had to find some code in order to convert the Texture2D to a "premultiplied alpha" format, which is what XNA4 defaults to normally.

This is the code I found from: http://jakepoz.com/jake_poznanski__speeding_up_xna.html
 // Blah blah Texture2D t = Texture2D.FromStream(graphicsDevice, titleStream); // Blah blah blendColor = new BlendState(); blendColor.ColorWriteChannels = ColorWriteChannels.Red | ColorWriteChannels.Green | ColorWriteChannels.Blue; blendColor.AlphaDestinationBlend = Blend.Zero; blendColor.ColorDestinationBlend = Blend.Zero; blendColor.AlphaSourceBlend = Blend.SourceAlpha; blendColor.ColorSourceBlend = Blend.SourceAlpha; blendAlpha = new BlendState(); blendAlpha.ColorWriteChannels = ColorWriteChannels.Alpha; blendAlpha.AlphaDestinationBlend = Blend.Zero; blendAlpha.ColorDestinationBlend = Blend.Zero; blendAlpha.AlphaSourceBlend = Blend.One; blendAlpha.ColorSourceBlend = Blend.One; RenderTarget2D target = new RenderTarget2D(graphicsDevice, t.Width, t.Height); graphicsDevice.SetRenderTarget(target); { graphicsDevice.Clear(Color.Black); SpriteBatch spriteBatch = new SpriteBatch(graphicsDevice); // Multiply each color by the source alpha, and write in just the color values into the final texture spriteBatch.Begin(SpriteSortMode.Immediate, blendColor); spriteBatch.Draw(t, t.Bounds, Color.White); spriteBatch.End(); // Now copy over the alpha values from the PNG source texture to the final one, without multiplying them spriteBatch.Begin(SpriteSortMode.Immediate, blendAlpha); spriteBatch.Draw(t, t.Bounds, Color.White); spriteBatch.End(); } graphicsDevice.SetRenderTarget(null); t = target as Texture2D;

Using this code, everything renders correctly just as it did before the switch-over.
However, now when I resize the game window (or maximize/restore the window) the rendering breaks, and all textures end up black. The only thing that still renders is the HUD, where I used DrawString().
This did not happen previously.
Infact, I can comment out all of the Premultiply Alpha code from above, and the issue goes away, except now that I'm not using a "premultiplied alpha" texture, the rendering is funky.

What is the issue that is going on, here? I have a feeling it has to do with changing the RenderTarget, but I'm not entirely sure.

##### Share on other sites
Doing some more investigating.. I found this post
http://stackoverflow.com/questions/5509265/after-writing-to-a-rendertarget-how-to-efficiently-clone-the-output

It looks like RenderTarget2D is volatile and can lose its contents when the backbuffer resizes. This makes sense.
I've noticed there is a RenderTargetUsage.PreserveContents that can be passed in via constructor.. I've tried this and it makes no difference at all. (This doesn't make sense.)

I see there was no "real solution" to the guy's problem...
For now I'm going to use his solution and copy the texture data from the RenderTarget2D into a new Texture2D.

I'm still wondering if anybody has any better ideas?

##### Share on other sites
It's my understanding that rendertarget contents are lost when the graphicsdevice is lost/reset. If the device is reset, you have to handle re-creating the texture data again. Do not use RednerTarget2D to store data between frames*, since they may not persist (I think some dynamic vertex buffers are the same way).

For what you are describing, it seems much simpler to just use GetData<Color> and SetData<Color> and multiply the alpha for every pixel in a Texture2d. Or, you can use your drawing method above, and then copy the data over to a Target2D.

EDIT: *that is, data that you don't want to have to regenerate after a device lost event

1. 1
2. 2
Rutin
19
3. 3
khawk
19
4. 4
5. 5
A4L
11

• 9
• 12
• 16
• 26
• 10
• ### Forum Statistics

• Total Topics
633771
• Total Posts
3013761
×