Skip to content
Find file
Fetching contributors…
Cannot retrieve contributors at this time
365 lines (238 sloc) 10.5 KB

SDL provides several ways to draw graphical elements on the screen in three general categories: primitives, images, and text. All drawing occurs on a surface, represented by the SDLx::Surface class. Even the SDLx::App is an SDLx::Surface. Though this means it's possible to draw directly to the app's surface, there are several advantages to drawing on multiple surfaces.


SDL's surface coordinate system has its origin (where both the x and y coordinates have the value of zero) in the upper left corner. As the value of x increases, the position moves to the right of the origin. As the value of y increases, the position moves downward from the origin. The API always lists coordinates in x, y order.

Drawing with SDL

You can produce original pictures knowing little more than how to draw to a surface with SDL:

Surface Drawing Methods

As mentioned earlier, all drawing in SDL requires a surface. The SDLx::Surface object provides access to methods in the form of:

    $surface->draw_{something}( .... );

Parameters to these methods are generally coordinates and colors, provided as array references.

Rectangular Parameters

Some parameters are sets of coordinate positions and dimensions. For example, parameters to describe a rectangle of 40x40 pixels placed at (20, 20) pixel units on the screen make a four-element array reference of x, y, width, height:

    my $rect = [20, 20, 40, 40];


Need to document what the magnitude of the color and transparency values mean.

SDL color parameters require four-element array references. The first three numbers define the Red, Green, and Blue intensity of the color. The final number defines the transparency of the color.

    my $color = [255, 255, 255, 255];

The magnitude of each color value determines how much of that color component will be mixed into the resulting color. A 0 value specifies that none of the color channel should be used while 255 specifies a maximum intensity for a particular channel. The first value corresponds with the Red channel, so a higher number there means more red will be mixed into the resulting color. It is a common practice to achieve a grayscale of varying intensity by specifying the same value for each of the Red, Green, and Blue color channels. The fourth and final value designates the transparency (or Alpha channel) where a 0 value makes the resulting color fully transparent and 255 makes it entirely opaque. A transparency value somewhere in between will allow underlying (pixel data of surfaces below the current one) colors to be blended with the specified RGB values into the final color output.

You may also represent a color as hexadecimal values, where the values of the numbers range from 0-255 for 32 bit depth in RGBA format:

    my $color = 0xFFFFFFFF;
    my $white = 0xFFFFFFFF;
    my $black = 0x000000FF;
    my $red   = 0xFF0000FF;
    my $green = 0x00FF00FF;
    my $blue  = 0x0000FFFF;

... or as four-byte hexadecimal values, where each two-digit byte encodes the same RGBA values:

    my $goldenrod = 0xDAA520FF;


All SDLx::Surfaces are collections of pixels. You can read from and write to these pixels by treating the surface as an array reference:

    $app->[$x][$y] = $color;

... where $color is an unsigned integer value using the hexadecimal format (0xRRGGBBAA) or an anonymous array of the form [$red, $green, $blue, $alpha].


Drawing primitives are simple shapes that SDL supports natively.


A line is a series of contiguous pixels between two points. The draw_line method causes SDL to draw a line to a surface:

    $app->draw_line( [200, 20], [20, 200], [255, 255, 0, 255] );

This will draw a yellow line from positions (200, 20) to (20, 200).


A rectangle is a four-sided, filled polygon. Rectangles are a common building block for games. In SDL, rectangles are the most cost effective of the primitives to draw. The draw_rect method draws a rectangle on a surface:

    $app->draw_rect( [10, 20, 40, 40 ], [255, 255, 255,255] );

This draws a white square of size 40x40 onto the screen at the position (10,20).


A circle is a primitive a fixed radius around a given point. Circles may be filled or unfilled. The draw_circle and draw_circle_filled methods draw these to a surface:

    $app->draw_circle(        [100, 100], 20, [255, 0,   0, 255] );
    $app->draw_circle_filled( [100, 100], 19, [0,   0, 255, 255] );

These draw an unfilled red circle and a filled blue circle.

SDL provides more complex primitives in SDL::GFX::Primitives.

Drawing with Primitives

It's easy to combine several primitives to draw an interesting images.

Drawing on Multiple Surfaces

The examples so far have drawn on only a single surface, the display. SDL makes it possible to write on multiple surfaces. These other surfaces exist only in memory until you draw them to the display.

Creating Surfaces

There are several ways to create an SDLx::Surface for use. The most common is to create one manually with a constructor call:

    $surface = SDLx::Surface->new( width => $width, height => $height );

SDL::Image and SDL::Video can load images as surfaces too. SDL::Image provides support for all types of images, provided that the underlying SDL_image library supports the image type you want to load. For example, SDL_image must support PNG images to use:

    $surface = SDL::Image::load( 'picture.png' );

In the event that the desired SDL_image library is unavailable, you can fallback to the built-in support for the .bmp format.

    $surface = SDL::Video::load_BMP( 'picture.bmp' );

The SDLx::Sprite module provides another option to manipulate surfaces.

Lots of Flowers but One Seed

The flower example used a method called blit to draw a surface to the display. This method copies data from one surface to another. It's a fundamental operation, but it's a low level operation. SDLx::Sprite provides higher level options. Besides making drawing simpler, SDLx::Sprite adds several other features useful for moving images. Here's a revised example using SDLx::Sprite for flowers:

Flowers usually don't grow in the sky. Flowers make more sense on the ground. It's easy to insert plenty of identical flowers from a single sprite. Replace the line:

    $flower->draw_xy( $app, 0, 0 );

... with:

... to make an entire field of flowers.

Probably don't need this.


Hey! The above document had some coding errors, which are explained below:

Around line 1:

Unknown directive: =head0

Around line 71:

=end for without matching =begin. (Stack: [empty])

Around line 362:

=end for without matching =begin. (Stack: [empty])

Jump to Line
Something went wrong with that request. Please try again.