C# SDL Tutorial – Part 3 Drawing Shapes

In this tutorial we will be using the provided shape functions of SDL to start drawing to the screen. If you haven’t already, head on over to https://jsayers.dev/tutorials/ to get caught up on the setup tutorials. As always source code for this tutorial can be found at https://github.com/JeremySayers/SDL2-CS-Tutorial.

From our previous tutorial, Creating a Window, we created a Render() function that currently looks like:

/// <summary>
/// Renders to the window.
/// </summary>
void Render()
{
    // Sets the color that the screen will be cleared with.
    SDL.SDL_SetRenderDrawColor(renderer, 135, 206, 235, 255);

    // Clears the current render surface.
    SDL.SDL_RenderClear(renderer);

    /* This is where we will be drawing */

    // Switches out the currently presented render surface with the one we just did work on.
    SDL.SDL_RenderPresent(renderer);
}

The first call to SDL_SetRenderDrawColor() sets the color that SDL will use for rendering functions, and then we immediately clear the screen with that color using SDL_RenderClear(). After we clear the screen, but before we actually present the new buffer to the screen with SDL_RenderPreset() we want to draw our shapes. If we just start drawing though, we won’t be able to see anything since SDL will be using the same color, so first let’s change the color to red after we clear the screen.

// Set the color to red before drawing our shape
SDL.SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);

Now that we’ve got the color set to something we can see on the background, we can get our first shape drawn! We’ll be starting out with a line that just takes the start coordinates and end coordinates. To draw a line from the top left of our screen to the bottom left of our screen we make a call to SDL_RenderDrawLine() and our Render() function now looks like:

/// <summary>
/// Renders to the window.
/// </summary>
void Render()
{
    // Sets the color that the screen will be cleared with.
    SDL.SDL_SetRenderDrawColor(renderer, 135, 206, 235, 255);

    // Clears the current render surface.
    SDL.SDL_RenderClear(renderer);

    // Set the color to red before drawing our shape
    SDL.SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);

    // Draw a line from top left to bottom right
    SDL.SDL_RenderDrawLine(renderer, 0, 0, 640, 480);

    // Switches out the currently presented render surface with the one we just did work on.
    SDL.SDL_RenderPresent(renderer);
}
Red line drawn from top left to bottom right of our window.

SDL has two other built-in shapes for us to use, points and rectangles. Points are drawn with SDL_RenderDrawPoint() while rectangles can be drawn filled in with SDL_RenderFillRect() or just as an outline with SDL_RenderDrawRect(). Points are easy enough to draw only requiring 3 arguments, a pointer to our renderer, an x location and a y location like this:


// Draws a point at (20, 20) using the currently set color.
SDL.SDL_RenderDrawPoint(renderer, 20, 20);

SDL_RenderFillRect() and SDL_RenderDrawRect() both require a pointer to our renderer as well as a reference to a SDL_Rect. An SDL_Rect is a simple struct the specifies the top left of the rectangle as (x,y) coordinates along with a width and height. Add the following to our Render() function, paying attention to the ref keyword needed when we pass our rect. and you’ll now have something the resembles the screenshot below!

// Specify the coordinates for our rectangle we will be drawing.
var rect = new SDL.SDL_Rect 
{ 
    x = 300,
    y = 100,
    w = 50,
    h = 50
};

// Draw a filled in rectangle.
SDL.SDL_RenderFillRect(renderer, ref rect);
Rectangle, Line, and a Point drawn.

These three basic shapes can give you a lot to work with, especially with basic game prototyping. During game jams, I’ll find myself using mostly rectangles to get a minimum viable product running before I start spending time drawing textures. As another note, you may have noticed that there are a lot of other similar function names to the 4 we’ve seen today. SDL has a plural variant of each such as SDL_RenderDrawRects() or SDL_RenderDrawLines(), as well as variants using floats instead of ints like SDL_RenderDrawRectF() and SDL_RenderDrawLineF(). Finally there are combo ones that draw multiple of the given shape, as well as using floats like SDL_RenderDrawPointsF().

Exercises

The best way to learn usage of these functions, and remember them is to try some exercises on your own. Below are some great ones that should reinforce SDLs shape functions. Feel free to leave a comment with any questions if you get stuck!

  • Draw each of the shapes in a different color.
  • Draw multiple rectangles with a single function call using SDL_RenderFillRects()
  • Use lines to draw a pentagon, hexagon, or bigger!
  • Create a Rectangle class that can hold its SDL_Rect and can be rendered. Bonus points if you create a Shape base class to encapsulate the shared features of all the shapes.

Leave a Comment

Your email address will not be published. Required fields are marked *