Render a sprite to the canvas

Now that we have learned how to render text to our HTML canvas element using SDL and Emscripten, we can take the next step and learn how to render sprites. The code used to render a sprite to the canvas is quite similar to the code that we used to render a TrueType font. We will still be using the virtual filesystem to generate a data file that contains the sprites we are using, but we will need a new SDL library to do this. We no longer need SDL2_ttf to load a TrueType font and render it to a texture. Instead, we need SDL2_image. We will show you how to change our call to emcc to include this new library a little later.

First, let's take a look at the new version of the SDL code that renders an image to our HTML canvas element instead of the text we rendered in the previous section:

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <emscripten.h>
#include <stdio.h>
#define SPRITE_FILE "sprites/Franchise1.png"

int main() {
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Rect dest = {.x = 160, .y = 100, .w = 0, .h = 0 };
SDL_Texture *texture;
SDL_Init( SDL_INIT_VIDEO );
SDL_CreateWindowAndRenderer( 320, 200, 0, &window, &renderer );
SDL_SetRenderDrawColor( renderer, 0, 0, 0, 255 );
SDL_RenderClear( renderer );
SDL_Surface *temp_surface = IMG_Load( SPRITE_FILE );

if( !temp_surface ) {
printf("failed to load image: %s\n", IMG_GetError() );
return 0;
}

texture = SDL_CreateTextureFromSurface( renderer, temp_surface );

SDL_FreeSurface( temp_surface );

SDL_QueryTexture( texture,
NULL, NULL,
&dest.w, &dest.h ); // query the width and
height

dest.x -= dest.w / 2;
dest.y -= dest.h / 2;

SDL_RenderCopy( renderer, texture, NULL, &dest );
SDL_RenderPresent( renderer );

SDL_Delay(5000);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}

This code is similar to the code we wrote in the last section, HTML5 and WebAssembly, for the HELLO SDL! application. Instead of using the SDL2_ttf module, we are using the SDL2_image module. Because of this, we will need to include the SDL2/SDL_image.h header file. We will also need to load a sprite file from the sprites directory, which we will add to the WebAssembly virtual filesystem:

SDL_Surface *temp_surface = IMG_Load( SPRITE_FILE );

if( !temp_surface ) {
printf("failed to load image: %s\n", IMG_GetError() );
return 0;
}

Below the call to IMG_Load, we add an error check that will let us know what went wrong if the file fails to load. Aside from that, the code is mostly the same. If we are successful, the canvas will display our 16x16 pixel image of the Starship Franchise:

Figure 4.2: Franchise1.png

In the next section, we will learn how to use SDL to animate a sprite on our canvas.