DinoMage on Twitter RSS Feed

Hey there!  This is a tutorial on some of the basics of using SDL_gpu.  If you are comfortable with C or C++ and SDL, then you’re ready for this.  I’ll post installation instructions for SDL_gpu some other time, though if you use SDL then you probably already have that down.

To start things off, here’s a listing of the functions we’ll be using:

GPU_SetDebugLevel
GPU_Init
GPU_LoadImage
GPU_Clear
GPU_Blit
GPU_Flip
GPU_Quit

These will be everything we need to put together a simple simulation to play with.

If you’ve used SDL’s built-in rendering before, then SDL_gpu shouldn’t feel too different.  They do the same basic things, but SDL_gpu has a lot more functionality and a few different conventions.  The most blatant convention difference you’ll see is that GPU_Blit() and the other blitting functions draw sprites at their center instead of from the upper-left corner.  This doesn’t actually change much in your code, but makes scaling and rotating sprites work without hassle.

Initialization

void GPU_SetDebugLevel(GPU_DebugLevelEnum level);
GPU_Target* GPU_Init(Uint16 w, Uint16 h, GPU_WindowFlagEnum SDL_flags);

There are a couple of ways that SDL_gpu lets you know when something goes wrong.  Some functions can have an obvious return value when there’s an error.  E.g. GPU_Init() will return a NULL render target on error.  SDL_gpu also maintains an error stack that you can check manually (sometimes a silent program is bliss). But we’re just starting off! We need to know right when errors occur. With GPU_SetDebugLevel(), we can tell SDL_gpu to print out the errors just as they happen.  That will help us catch some mistakes that we might make along the way.

GPU_Init() is the easy way to get a window and render target created.  All you have to do is pass in the width and height of the window you want.  You can also pass in some SDL window flags if you want to.  This will set everything up and choose the best renderer that is available.

So here’s a snippet of those two functions. Once you have #include “SDL_gpu.h” and set up your main() function:

// Tell us whenever something bad happens
GPU_SetDebugLevel(GPU_DEBUG_LEVEL_MAX);
// Get a 800x600 window to render to
GPU_Target* screen = GPU_Init(800, 600, GPU_DEFAULT_INIT_FLAGS);

Rendering an image

Now we would like to draw something on the screen. To render to our new window, we need either an image or we can draw shapes.  Here’s what we need for drawing images:

GPU_Image* GPU_LoadImage(const char* filename);
void GPU_Clear(GPU_Target* target);
void GPU_Blit(GPU_Image* image, GPU_Rect* src_rect, GPU_Target* target, float x, float y);
void GPU_Flip(GPU_Target* target);

GPU_LoadImage() of course loads images. It currently supports .png, .jpg, .tga, .gif, and .bmp image files. Before each frame is drawn, we might want to use GPU_Clear() to erase the contents of the screen target. In some cases you don’t need to, especially when you are drawing over the entire screen every frame (e.g. with a background image).  When we pass our new image and the screen target to GPU_Blit(), we get the image rendered right where we want it.  To actually see what we rendered, we need to GPU_Flip() the screen buffer so it is shown in the window.

// Load the image...
// (Make sure that you have some image named test_image.png in the executable's directory)
GPU_Image* image = GPU_LoadImage("test_image.png");
// Clear the screen
GPU_Clear(screen);
// Remember that GPU_Blit() draws the image *centered* at the given position
GPU_Blit(image, NULL, screen, image->w/2, image->h/2);
// Show the result in the window
GPU_Flip(screen);

With that, we can technically see something drawn…

Shutting down

void GPU_Quit(void);

Let’s not forget to shut down SDL_gpu at the end. GPU_Quit() will free up the resources that SDL_gpu was using.

Source

Here’s what your complete program might look like now with some usual SDL stuff thrown in:

#include "SDL_gpu.h"
int main(int argc, char** argv)
{
    // Tell us whenever something bad happens
    GPU_SetDebugLevel(GPU_DEBUG_LEVEL_MAX);
    // Get a 800x600 window to render to
    GPU_Target* screen = GPU_Init(800, 600, GPU_DEFAULT_INIT_FLAGS);
    // Did initialization fail?
    if(screen == NULL)
        return 1;
    // Load the image...
    // (Make sure that you have some image named test_image.png in the executable's directory)
    GPU_Image* image = GPU_LoadImage("test_image.png");
    if(image == NULL)
        return 2;
    SDL_Event event;
    Uint8 done = 0;
    while(!done)
    {
        while(SDL_PollEvent(&event))
        {
            if(event.type == SDL_QUIT)
                done = 1;
        }
        // Clear the screen
        GPU_Clear(screen);
        // Remember that GPU_Blit() draws the image *centered* at the given position
        GPU_Blit(image, NULL, screen, image->w/2, image->h/2);
        // Show the result in the window
        GPU_Flip(screen);
    }
    GPU_Quit();
    return 0;
}

Tags: ,

2 Responses to “SDL_gpu Simple Tutorial”

  1.  Carsten Holtkamp says:

    Thank you for this Tutorial and the whole page!

    Do you _need_ libstbi if you want to use SDL_gpu?
    I am using archlinux and can’t find a package.
    https://github.com/nothings/stb is the correct URL, right?

    Btw, the example code is missing the gpu include, right?

    •  Jonny D says:

      You’re welcome!

      SDL_gpu bundles stb-image and stb-image-write so if your distro doesn’t provide those packages, the CMake script will pick up the bundled versions instead.

      Yep!  The example code is missing the #include.  I’ll fix that.

Leave a Reply