Surfaces manipulation

The basic surface manipulation usually consists of filling the part or whole surface with color, which can be in fact clearing the surface, and copying the surface content into another surface. As you already know, the surface can also represent the screen content. With these two groups of operations you can do almost anything.

Getting ready

In this recipe, you'll be working with routines that require a definition of a rectangular area over which the operation will occur. The libSDL library uses its own SDL_Rect object to define such a rectangular area. You can create this object either with SDL.SDL_Rect_new or SDL.SDL_Rect_local. The second one is preferred because it contains an automatic garbage collection routine, so you don't have to explicitly call the SDL.SDL_Rect_delete function to delete the object. The only downside of this is that you can't set the position nor the size of rectangle in the constructor. This means that you have to set all the parameters after the SDL_Rect object is created. The following code shows this in detail:

local rectangle = SDL.SDL_Rect_local()
rectangle.x = 16
rectangle.y = 32
rectangle.w = 64
rectangle.h = 64

This example contains an SDL_Rect object, where the x and y fields represent the position of the upper-left corner of the rectangle; the w and h fields are the width and height of the rectangle.

LibSDL usually allows you to use NULL (nil) value instead of the SDL_Rect object if you need to proceed with the operation on the entire surface. You will find such use cases in the SDL_FillRect or SDL_BlitSurface functions.

How to do it…

Filling a surface with color is done with the SDL.SDL_FillRect function. The function specification looks like this:

SDL_FillRect(surface, rectangle, color)

The Surface parameter defines the surface object that you want to fill with color. You can fill the whole surface or just a part of it. The last parameter, color, defines what color would be used to fill your surface. You have to be careful to use the SDL.SDL_MapRGBA function to get the correct color value because its value is dependent on the surface pixel format. This function has the following specification:

SDL_MapRGBA(pixel_format_descriptor, red, green, blue, alpha)

You can get the pixel format descriptor of the surface with the following code:

surface.format

Red, green, blue, and alpha parameters accept integer values in the range, 0-255. This function returns a 32-bit value of the selected color. Of course, you can store these values in a table, so you don't have to recompute them every time. Just keep in mind that these values can mean different colors on the surface with different pixel formats.

The following example shows how to fill the rectangular area of an empty surface with a red color. The surface has a size of 64 x 64 pixels and uses the RGBA pixel format with the 32-bit color depth:

local color = SDL.SDL_MapRGBA(surface.format, 255, 0, 0, 255)
local rect = SDL.SDL_Rect_local()
rect.x, rect.y, rect.w, rect.h = 16, 16, 32, 32
SDL.SDL_FillRect(surface, rect, color)

The result of this can be seen in the following screenshot:

How to do it…

Surface content copying is often called blitting. Many graphical APIs use this term to express the operation of putting data into another place. The libSDL library offers a SDL.SDL_BlitSurface function to blit surface content into another. This function is quite versatile as it can do automatic conversion of surface data to destination pixel format. Another thing to mention is that you can select what portion of the source surface should be copied into part of the destination surface. The formal specification of this function looks like this:

SDL_BlitSurface(source_surface, source_rectangle, destination_surface, destination_rectangle)

Note that the destination surface can be the screen surface object. Such blitting will draw the content of the source surface onto the screen.

In case you only need to convert the surface into another pixel format, you can use the SDL.SDL_ConvertSurface function. This function has the following specification:

SDL_ConvertSurface(source_surface, target_pixelformat, flags)

You can obtain the pixel format object from another valid surface or you can create one yourself with SDL.SDL_PixelFormat_local().

The flags parameter accepts the same values as the SDL_CreateRGBSurface function.

How it works…

LibSDL uses an internal mechanism to determine whether the conversion is necessary. Blitting between surfaces of the same pixel formats is called internally fastblit. It's much faster because it accompanies only the memcpy function to make a copy of the memory region. Optionally, libSDL offers SSE optimization for the blitting function to provide even faster drawing.

Blitting between two regions of the graphical memory is considered to be the fastest method because it's done entirely on the GPU. However, due to the limited availability of hardware acceleration of 2D operations, it's not used very often. Note that this is a different kind of acceleration to the one offered by modern GPUs. Most of the consumer-level graphic cards nowadays are oriented towards the provision of accelerated 3D operations (OpenGL, Direct X, and so on) and hardware video decoding.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.71.106