Skip to content

Instantly share code, notes, and snippets.

@soywiz
Created September 2, 2012 12:16
Show Gist options
  • Save soywiz/3597910 to your computer and use it in GitHub Desktop.
Save soywiz/3597910 to your computer and use it in GitHub Desktop.
public class TransitionBlendGpu
{
GraphicsDevice GraphicsDevice;
SpriteBatch SpriteBatch;
BlendState BlendAlpha1;
BlendState BlendAlphaAdd;
BlendState BlendAlphaSub;
Texture2D DummyTexture;
public TransitionBlendGpu(GraphicsDevice GraphicsDevice)
{
this.GraphicsDevice = GraphicsDevice;
this.SpriteBatch = new SpriteBatch(GraphicsDevice);
this.DummyTexture = new Texture2D(GraphicsDevice, 1, 1);
this.DummyTexture.SetData(new Color[] { Color.White });
BlendAlpha1 = new BlendState();
BlendAlpha1.ColorWriteChannels = ColorWriteChannels.Alpha;
BlendAlpha1.AlphaDestinationBlend = BlendAlpha1.ColorDestinationBlend = Blend.Zero;
BlendAlpha1.AlphaSourceBlend = BlendAlpha1.ColorSourceBlend = Blend.One;
BlendAlpha1.AlphaBlendFunction = BlendAlpha1.ColorBlendFunction = BlendFunction.Add;
BlendAlphaSub = new BlendState();
BlendAlphaSub.ColorWriteChannels = ColorWriteChannels.Alpha;
BlendAlphaSub.AlphaDestinationBlend = BlendAlphaSub.ColorDestinationBlend = Blend.DestinationAlpha;
BlendAlphaSub.AlphaSourceBlend = BlendAlphaSub.ColorSourceBlend = Blend.SourceAlpha;
BlendAlphaSub.AlphaBlendFunction = BlendAlphaSub.ColorBlendFunction = BlendFunction.ReverseSubtract;
BlendAlphaAdd = new BlendState();
BlendAlphaAdd.ColorWriteChannels = ColorWriteChannels.Alpha;
BlendAlphaAdd.AlphaDestinationBlend = BlendAlphaAdd.ColorDestinationBlend = Blend.DestinationAlpha;
BlendAlphaAdd.AlphaSourceBlend = BlendAlphaAdd.ColorSourceBlend = Blend.SourceAlpha;
BlendAlphaAdd.AlphaBlendFunction = BlendAlphaAdd.ColorBlendFunction = BlendFunction.Add;
}
public Texture2D GenerateAlpha(int Width, int Height)
{
var AlphaTexture = new Texture2D(GraphicsDevice, Width, Height);
var WidthHeight = Width * Height;
var Data = new RGBA[WidthHeight];
for (int n = 0, y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
Data[n].A = (byte)(x * 255 / Width);
n++;
}
}
AlphaTexture.SetData(Data);
return AlphaTexture;
}
public Texture2D GenerateAlphaFromRedChannel(Texture2D BaseImage)
{
return GenerateAlphaFromRedChannel(BaseImage, false);
}
public Texture2D GenerateAlphaFromRedChannel(Texture2D BaseImage, bool DisposeBaseImage)
{
var Width = BaseImage.Width;
var Height = BaseImage.Height;
var AlphaTexture = new Texture2D(GraphicsDevice, Width, Height);
var WidthHeight = Width * Height;
var Data = new RGBA[WidthHeight];
BaseImage.GetData(Data);
{
for (int n = 0, y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
Data[n].A = Data[n].R;
Data[n].R = 0;
Data[n].G = 0;
Data[n].B = 0;
n++;
}
}
}
AlphaTexture.SetData(Data);
if (DisposeBaseImage) BaseImage.Dispose();
return AlphaTexture;
}
public void CombineAlpha(RenderTarget2D RenderTarget, Texture2D TextureColor, Texture2D TextureAlpha, float Step)
{
int Width = TextureColor.Width;
int Height = TextureColor.Height;
var GraphicsDevice = RenderTarget.GraphicsDevice;
var OldRenderTargets = GraphicsDevice.GetRenderTargets();
GraphicsDevice.SetRenderTarget(RenderTarget);
{
SpriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);
{
SpriteBatch.Draw(TextureColor, new Vector2(0, 0), Color.White);
}
SpriteBatch.End();
}
{
float AlphaSub = MathHelper.Clamp(1.0f - Step * 2.0f, 0.0f, 1.0f);
float AlphaAdd = MathHelper.Clamp(Step * 2.0f - 1.0f, 0.0f, 1.0f);
{
SpriteBatch.Begin(SpriteSortMode.Immediate, BlendAlpha1);
{
SpriteBatch.Draw(
TextureAlpha,
Vector2.Zero,
Color.White
);
}
SpriteBatch.End();
}
if (AlphaSub > 0)
{
SpriteBatch.Begin(SpriteSortMode.Immediate, BlendAlphaSub);
{
SpriteBatch.Draw(DummyTexture, new Rectangle(0, 0, Width, Height), new Color(AlphaSub, AlphaSub, AlphaSub, AlphaSub));
}
SpriteBatch.End();
}
if (AlphaAdd > 0)
{
SpriteBatch.Begin(SpriteSortMode.Immediate, BlendAlphaAdd);
{
SpriteBatch.Draw(DummyTexture, new Rectangle(0, 0, Width, Height), new Color(AlphaAdd, AlphaAdd, AlphaAdd, AlphaAdd));
}
SpriteBatch.End();
}
}
GraphicsDevice.SetRenderTargets(OldRenderTargets);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment