# Where can I find a good tutorial to replicate Game Maker's surfaces and blend modes in XNA?

I know Game Maker's surfaces exist in XNA (It's more the othe way around, XNA's surfaces exist in Game Maker), same thing for blend modes, since (I think) they both use DirectX.

This is the question: "Where can I find a good tutorial to replicate Game Maker's surfaces and blend modes in XNA?"

I'm using XNA 4.0 and Game Maker 8.1 Pro.

Background

I'm slowly moving from Game Maker to... Something else.

I've learned some good C++ but DirectX is hardcore and OpenGL needs some pretty good understanding of the language to be able to use it correctly.

XNA and C# together seemed like a good middle but the documentation is hard to understand for a newb like me.

In the end, I chose to focus on XNA.

• Which blend modes are you talking about? Also, to get something similar to surfaces in game maker, you should look at RenderTarget2D. – William Mariager Nov 24 '11 at 1:55
• draw_set_blend_mode(bm_subtract). After posting this question, I kept searching and found a tutorial on additive blend mode and I think I got it, but getting info from an outside source would definitely help. – Fred Dufresne Nov 24 '11 at 12:37

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 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;
}

{
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.
// 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.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.

• Well your answer is the best so far. It explains, in code, both RenderTarget2D and BlendState. From what I understand, I create a new field for BlendState and set its properties to what I need. RenderTarget2D is perfectly clear from the code you wrote. TYVM! – Fred Dufresne Nov 24 '11 at 17:22
• Did some research and you don't need to state the ALPHA properties because they start at One, One and Add, respectively. Though the color blend properties are not correct. They need to be One, One and Subtract. If you also want to subtract from the alpha, just change the Add to Subtract in the alpha blend function. – Fred Dufresne Nov 28 '11 at 15:09
• @FredDufresne, Thanks for the feedback, it's great seeing you take an example, and work with it. The values of the color blending was based purely on the post, which describes Game Makers bm_subtract, which apparently isn't like a normal subtract. You can see EyeGuy explaining it here: gmc.yoyogames.com/… – William Mariager Nov 28 '11 at 16:16

You can use the RenderTarget2D class to draw parts of your game to a bitmap, which you can then apply operations to to get the desired result

You might start here to learn the concepts: http://www.switchonthecode.com/tutorials/csharp-tutorial-convert-a-color-image-to-grayscale

• RenderTarget2D is perfect! The second link goes on by pixel and kinda works with the images at a high level. If you know Game Maker, I'm looking for "draw_set_blend_mode(bm_subtract)" to do some shadows and lighting in a top view 2D game. – Fred Dufresne Nov 24 '11 at 12:40