How To: SpriteBatch and 2D Rendering

SpriteBatch is MonoGame's primary 2D rendering API. It batches texture draw calls into efficient GPU uploads and is the standard way to draw textures, text, and coloured rectangles.

Reference file: Advanced/SampleGame.cs


Setup in LoadContent

SpriteBatch requires a GraphicsDevice, which is not available until after Initialize() runs. Always create it in LoadContent(), not the constructor:

private SpriteBatch? _spriteBatch;

protected override void LoadContent()
{
    _spriteBatch = new SpriteBatch(GraphicsDevice);
}

Basic draw loop

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);

    _spriteBatch!.Begin();
    // ... draw calls here ...
    _spriteBatch.End();

    base.Draw(gameTime);
}

Begin() starts batching; End() flushes all queued draws to the GPU. Do not call any draw operations outside a Begin / End pair.


Drawing a Texture2D

// Draw at a position
_spriteBatch.Draw(_texture, new Vector2(100, 50), Color.White);

// Draw into a destination rectangle (scales the texture to fit)
_spriteBatch.Draw(_texture, new Rectangle(0, 0, 200, 150), Color.White);

// Draw with tinting
_spriteBatch.Draw(_texture, new Vector2(100, 50), Color.Red);

Drawing text with SpriteFont

// Load in LoadContent:
_font = Content.Load<SpriteFont>("font");

// Draw in Draw:
_spriteBatch.DrawString(_font, "FPS: 60", new Vector2(10, 10), Color.White);

See 03 — Content Pipeline for how to compile a .spritefont definition into a .xnb atlas.


Coloured rectangles — the 1×1 pixel trick

MonoGame has no built-in solid-colour rectangle draw call. The standard pattern is to create a 1×1 white pixel texture and scale it to any size via the destination rectangle, tinting it to the desired colour:

// In LoadContent:
_pixel = new Texture2D(GraphicsDevice, 1, 1);
_pixel.SetData([Color.White]);

// In Draw — draw a 200×100 orange rectangle at (50, 30):
_spriteBatch.Draw(
    _pixel,
    new Rectangle(50, 30, 200, 100),
    new Color(255, 140, 0));

This avoids the need for a solid-colour shader or a glClear call and integrates cleanly into the SpriteBatch batching model. The Minimal and Advanced samples both use this pattern.


Clearing the background

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.CornflowerBlue);  // or any Color
    // ...
}

Call GraphicsDevice.Clear() once per frame before any SpriteBatch draws. In sub-viewport mode, use the 1×1 pixel trick instead to avoid clearing the shared framebuffer (see 08 — Multi-Screen and Sub-Viewports).


SpriteBatch.Begin options

_spriteBatch.Begin(
    sortMode:        SpriteSortMode.Deferred,   // default: batches in order
    blendState:      BlendState.AlphaBlend,     // default: alpha blending
    samplerState:    SamplerState.PointClamp,   // pixel-perfect for low-res art
    rasterizerState: new RasterizerState { ScissorTestEnable = true }  // enables GL scissor
);

The Advanced sample passes a custom RasterizerState with ScissorTestEnable = true so that sub-viewport draws are clipped to the viewport bounds via GraphicsDevice.ScissorRectangle.

latest ▼