Here's a custom BlendState that should do the same as Game Maker's bm_subtract
does, based on the post found here. Here's a complete example with combining two RenderTarget2Ds, so you also see how they work in practice.
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
private RenderTarget2D sprites;
private RenderTarget2D shadows;
private readonly BlendState blendStateSutractive = new BlendState
{
ColorSourceBlend = Blend.Zero,
ColorDestinationBlend = Blend.InverseSourceColor,
ColorBlendFunction = BlendFunction.Subtract,
AlphaSourceBlend = Blend.Zero, // Not sure if these are needed.
AlphaDestinationBlend = Blend.InverseSourceColor, // Not sure if these are needed.
AlphaBlendFunction = BlendFunction.Subtract // Not sure if these are needed.
};
public Game1()
{
this.graphics = new GraphicsDeviceManager(this);
this.graphics.PreferredBackBufferWidth = 1280;
this.graphics.PreferredBackBufferHeight = 720;
}
protected override void LoadContent()
{
this.spriteBatch = new SpriteBatch(this.GraphicsDevice);
this.sprites = new RenderTarget2D(this.GraphicsDevice, this.graphics.PreferredBackBufferWidth, this.graphics.PreferredBackBufferHeight);
this.shadows = new RenderTarget2D(this.GraphicsDevice, this.graphics.PreferredBackBufferWidth, this.graphics.PreferredBackBufferHeight);
}
protected override void Draw(GameTime gameTime)
{
// We make it so future drawing is done to the sprites RenderTarget2D.
this.GraphicsDevice.SetRenderTarget(this.sprites);
// Then we clear it to one color.
this.GraphicsDevice.Clear(Color.Black);
this.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
// Here you draw your main sprites/textures/whatever.
this.spriteBatch.End();
// We make it so future drawing is done to the shadows RenderTarget2D.
this.GraphicsDevice.SetRenderTarget(this.shadows);
// Then we clear it to one color, don't know if this should be black or white.
this.GraphicsDevice.Clear(Color.Black);
this.spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
// And here you draw whatever you need drawn subtractively.
this.spriteBatch.End();
// We then reset to the main RenderTarget2D.
this.GraphicsDevice.SetRenderTarget(null);
// No need to clear, as the other two RenderTarget2Ds will cover it completely.
this.spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);
this.spriteBatch.Draw(this.sprites, Vector2.Zero, Color.White);
this.spriteBatch.End();
this.spriteBatch.Begin(SpriteSortMode.Deferred, this.blendStateSubtractive);
this.spriteBatch.Draw(this.shadows, Vector2.Zero, Color.White);
this.spriteBatch.End();
}
If you have any questions, fire away in the comments section below this answer. And remember to mark whatever answer your satisfied with correct, so future visitors know which answer to look at.