SDL (Simple DirectMedia Layer) - Rendering surfaces
In this section, we will modify our code to optimise SDL_Surface
blitting using SDL_ConvertSurface
and stretch our image to fullscreen using SDL_BlitScaled
.
You can download the source code of this section in this GitLab repository. All source code is stored in this group.
Optimising a SDL_Surface
for blitting
[edit | edit source]We can optimise a SDL_Surface
for blitting, which in turn improves performance. SDL_ConvertSurface
is used to optimize images for faster repeat blitting. This is accomplished by converting the original and storing the result as a new surface.
We'll update our wb_loadImage
function by using the following code.
/* Set temporary SDL_Surface */
SDL_Surface *temp = NULL;
/* Load the image from its file path to a SDL_Surface */
temp = IMG_Load(WB_IMAGE_PATH);
if (temp == NULL) {
fprintf(stderr, "WikiBook failed to load image: %s\n", IMG_GetError());
return -1;
}
/* Optimise SDL_Surface for blitting */
wb->image = SDL_ConvertSurface(temp, wb->screen->format, 0);
/* Destroy temporary SDL_Surface */
SDL_FreeSurface(temp);
Remember to destroy SDL object pointers using their corresponding functions, in this case SDL_FreeSurface
.
Blitting a SDL_Surface
to fullscreen
[edit | edit source]We'll replace SDL_BlitSurface
with SDL_BlitScaled
. We'll write a static (and therefore private) function that blits a surface to fullscreen.
/* Maximise surface to full screen */
static int setSurfaceFullScreen(SDL_Surface *surface, SDL_Surface *screen) {
/* Create SDL_Rect to full screen */
SDL_Rect rt = { 0, 0, WB_WIDTH, WB_HEIGHT };
/* Blit SDL_Surface to the size of SDL_Rect */
if (SDL_BlitScaled(surface, NULL, screen, &rt) < 0) {
fprintf(stderr, "Failed to set surface to full screen: %s\n", SDL_GetError());
return -1;
}
return 0;
}
We'll have to initialise and declare a SDL_Rect
with the size of the entire window and blit the surface using dimensions of that SDL_Rect
.
We replace the blitting function in our wb_loadImage
:
/* Blit SDL_Surface to full screen */
if (setSurfaceFullScreen(wb->image, wb->screen) < 0) {
return -1;
}
You'll notice that we're not declaring a SDL_Rect
pointer, it's a relatively small structure compared to SDL_Surface
and the like, so we don't have to dynamically allocate memory for it.