NewAPI/Blitting

From Allegro Wiki

Jump to: navigation, search

This is a work in progress, I started it after the Allegro_Hack_Day/2007 June 09 meeting, but it's far from done. Feel free to extend/edit/discuss.

The current implementation in SVN can be see here, and may differ significantly from the original proposal below: http://www.liballeg.org/naturaldocs/files/bitmap_new-c.html

Contents

Structures

This is the part of blitting out of Bob's original proposal, with some modifications. Most notably, there are no more target bitmaps (see the NewAPI/Display specification for this), run-time masking is gone and source as well as multiple clipping rectangles are gone. Blending is left out for now as Bob didn't specify details yet so this needs to be first thought about in detail.

Also, I changed the parameter orders to be more consistent with normal drawing functions. E.g. since we have al_draw_line(x, y, x2, y2, color) I made it al_draw_scaled_bitmap(x, y, w, h, bitmap, source_x, source_y, source_w, source_h). And flags parameters are always at the end instead of at the beginning.

It's also just an early work in progress right now.. some things are completely missing as of yet.

ALLEGRO_BITMAP

This likely stores internally:

  • a vtable for various methods - surely this should be a pointer to a vtable? MS
  • the bitmap size
  • except in special cases, a memory copy of the pixel data
  • if an alpha channel is to be used
  • and some more

Plus display/driver specific:

  • A display specific version of the data (i.e. a texture copy) for one or more displays
  • in special cases, a flag that this bitmap is e.g. a reference to the back-buffer
struct ALLEGRO_BITMAP

ALLEGRO_COLOR

An ALLEGRO_COLOR structure describes a color in a particular pixel format. A color that appears the same in one format may be internally very different in another format. Notably, color->raw[0] does not always represent the same color component (red, green, blue, alpha) and will not always be in the same scale or even data type. Users will not normally have to access the internals of this structure directly. The al_map_* and al_unmap_* functions should do the work for them.

typedef struct ALLEGRO_COLOR {
        uint64_t raw[4];
}

ALLEGRO_LOCKED_REGION

Users who wish to manually edit or read from a bitmap are required to lock it first. The ALLEGRO_LOCKED_REGION structure represents the locked region of the bitmap. This call will work with any bitmap, including memory bitmaps.

typedef struct ALLEGRO_LOCKED_REGION {
        void *data;
        int format;
        int pitch;
}

data points to the actual bitmap data. The format of the data depends on the format of the bitmap that was locked. pitch defines the number of bytes in a single row of bitmap data. The pitch may be greater than pixel_size*bitmap->w.


I changed this from "... read from a non-memory bitmap" to "read from a bitmap", as I think it's best to discourage use of structure internals, in case we want to change them in the future. Trent Gamblin 13:56, June 26, 2007 (UTC)

Configuration/Querying

al_set_new_bitmap_format

Sets the pixel format for newly created bitmaps. format is one of the same values as used for al_set_new_display_format. The default format is 0 and means the display driver will choose the best format.

void al_set_new_bitmap_format(int format);

al_set_new_bitmap_flags

Sets the flags to use for newly created bitmaps. Valid flags are:

  • ALLEGRO_MEMORY_BITMAP The bitmap will use a format most closely resembling the format used in the bitmap file and al_create_memory_bitmap will be used to create it. If this flag is not specified, al_create_bitmap will be used instead and the display driver will determine the format.
  • ALLEGRO_SYNC_MEMORY_COPY When modifying the bitmap, always keep the memory copy synchronized. This may mean copying back from the texture after render-to-texture operations which is slow, or it may mean doing each operation twice, once with render-to-texture, and once with a software renderer on the memory copy. Some drivers also may always have to do software rendering first then upload the modified parts, so this flag would have no effect.
  • ALLEGRO_USE_ALPHA Use alpha blending when drawing the bitmap
  • ALLEGRO_KEEP_BITMAP_FORMAT Only used when loading bitmaps from disk files, forces the resulting ALLEGRO_BITMAP to use the same format as the file.
void al_set_new_bitmap_flags(int flags);

al_get_new_bitmap_format

Returns the format used for newly created bitmaps.

int al_get_new_bitmap_format(void);

al_get_new_bitmap_flags

Returns the flags used for newly created bitmaps.

int al_get_new_bitmap_flags(void);

al_get_bitmap_width

Returns the width of a bitmap.

int al_get_bitmap_width(ALLEGRO_BITMAP *bitmap);

al_get_bitmap_height

Returns the height of a bitmap.

int al_get_bitmap_height(ALLEGRO_BITMAP *bitmap);

al_get_bitmap_format

Returns the pixel format of a bitmap.

int al_get_bitmap_format(ALLEGRO_BITMAP *bitmap);

al_get_bitmap_flags

Returns the flags of a bitmap.

int al_get_bitmap_flags(ALLEGRO_BITMAP *bitmap);

Creation and Loading

al_create_bitmap

Creates a new bitmap using the bitmap flags for the current thread. Blitting between bitmaps of differing formats, or blitting between memory bitmaps and display bitmaps may be slow.

ALLEGRO_BITMAP *al_create_bitmap(int width, int height)

al_destroy_bitmap

Destroys the given bitmap, freeing all resources used by it.

void al_destroy_bitmap(ALLEGRO_BITMAP *bitmap)


al_load_bitmap

ALLEGRO_BITMAP *al_load_bitmap(char const *filename)

al_load_bitmap_stream

Like al_load_bitmap, but load from a stream/packfile.

ALLEGRO_BITMAP *al_load_bitmap_stream(ALLEGRO_STREAM *stream)

Miscellaneous

al_is_compatible_bitmap

D3D and OpenGL allow sharing a texture in a way so it can be used for multiple windows. Each ALLEGRO_BITMAP created with al_create_bitmap however is usually tied to a single ALLEGRO_DISPLAY. This function can be used to know if the bitmap is compatible with the current display, even if it is another display than the one it was created with. It returns true if the bitmap is compatible (things like a cached texture version can be used) and false otherwise (blitting in the current display will be slow).

The only time this function is useful is if you are using multiple windows and need accelerated blitting of the same bitmaps to both.

bool al_is_compatible_bitmap(ALLEGRO_BITMAP *bitmap)

Colors

In addition to the al_map_* functions, there are equivalent unmapping functions, such as

void al_unmap_rgba(ALLEGRO_COLOR *p,
unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a);

al_map_rgb

/* ALLEGRO_COLOR* al_map_rgb(ALLEGRO_COLOR *p,
unsigned char r, unsigned char g, unsigned char b)
*/
/* Converts colors from a Red-Green-Blue hardware-independent format to the
* pixel format required by the target bitmap. In the 'p' parameter, pass
* a pointer to an already made ALLEGRO_COLOR object. The 'r', 'g' and 'b'
* parameters specify the intensity of each Red, Green and Blue components,
* respectivally. The range of the color components is from 0 to 255
* included.
*
* If an alpha channel is required, then 255 is automatically used for alpha.
*
* The return value is identical to the 'p' parameter, allowing you
* to chain calls to primitive functions.
*
* If either the 'p' is NULL, then this function
* silently fails. In this case, the value of '*p' is not touched.
*
* If the target bitmap uses floating-point components, then the integer
* values in the range 0-255 are first mapped to 0.0-1.0. Only then is the
* final color value computed.
*
* Example use:
* <pre>
*   ALLEGRO_COLOR color;
*   al_put_pixel(bmp, x, y, al_map_rgb(&color, 45, 63, 97));
* </pre>
*/

ALLEGRO_COLOR* al_map_rgb(ALLEGRO_COLOR *p, unsigned char r, unsigned char g, unsigned char b);


al_map_rgba

/* ALLEGRO_COLOR* al_map_rgba(ALLEGRO_COLOR *p,
unsigned char r, unsigned char g, unsigned char b, unsigned char a)
*/
/* Similar to al_map_rgb(), but also includes an alpha component. The alpha
* component should be in the range 0 to 255 included. The alpha component
* is ignored if the bitmap does not support an alpha channel.
*/

ALLEGRO_COLOR* al_map_rgba(ALLEGRO_COLOR *p, unsigned char r, unsigned char g, unsigned char b, unsigned char a);


al_map_rgb_f

/* ALLEGRO_COLOR* al_map_rgb_f(ALLEGRO_COLOR *p,
float r, float g, float b)
*/
/* Similar to al_map_rgb(), but accepts color components as single-precision
* floating-point numbers. The values of 'r', 'g' and 'b' should be in the range
* 0.0 to 1.0 included.
*
* An alpha of 1.0 is automatically inserted if the target bitmap supports an
* alpha channel.
*
* If the target bitmap uses integer components instead of floating-point
* ones, then the floating point components are scaled to the apropreate
* range and converted to integers before the final color value is computed.
*/

ALLEGRO_COLOR* al_map_rgb_f (ALLEGRO_COLOR *p, float r, float g, float b);


al_map_rgba_f

/* ALLEGRO_COLOR* al_map_rgba_f(ALLEGRO_COLOR *p,
float r, float g, float b, float a)
*/
/* Similar to al_map_rgb_f(), but also includes an alpha component. The alpha
* component should be in the range 0.0 to 1.0 included. The alpha component
* is ignored if the bitmap does not support an alpha channel.
*/

ALLEGRO_COLOR* al_map_rgba_f(ALLEGRO_COLOR *p, float r, float g, float b, float a);


al_map_rgb_i

/* ALLEGRO_COLOR* al_map_rgb_i(ALLEGRO_COLOR *p, int r, int g, int b) */
/* Similar to al_map_rgb(), but accepts color components in half the integer
* range. If the target bitmap uses integer components, then the color
* components in the range 0 to INT_MAX are scaled down to the apropreate
* range before the final color value is computed. However, if the target
* bitmap uses floating-point components, then the color components are
* first mapped to the range 0.0 to 1.0 before computing the final color
* value.
*
* An alpha of INT_MAX is assumed for target bitmaps requiring an alpha
* channel.
*/

ALLEGRO_COLOR* al_map_rgb_i(ALLEGRO_COLOR *p, int r, int g, int b);


al_map_rgba_i

/* ALLEGRO_COLOR* al_map_rgba_i(ALLEGRO_COLOR *p,
int r, int g, int b, int a)
*/
/* Similar to al_map_rgb_i(), but also includes an alpha component. The alpha
* component should be in the range 0 to INT_MAX included. The alpha component
* is ignored if the target bitmap does not support an alpha channel.
*/

ALLEGRO_COLOR* al_map_rgba_i(ALLEGRO_COLOR *p, int r, int g, int b, int a);

Masking

Color-key masking is not a supported feature of modern APIs like OpenGL and Direct3D, which are the main target backends for Allegro 5. Therefore, color masking support as seen in Allegro 4 has been removed. Alpha blending is now used in it's place. The convenience function al_convert_mask_to_alpha can be used to simulate masking.

al_convert_mask_to_alpha

Convert the given mask color to an alpha channel.

void al_convert_mask_to_alpha(ALLEGRO_BITMAP *bitmap, ALLEGRO_COLOR *color)
/*
* This can be used to convert an Allegro 4.2 style bitmap:
* al_convert_mask_to_alpha(bitmap, magenta)
*/

Sub-bitmaps

al_create_sub_bitmap

/* ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent, int x, int y,
int w, int h)
*/
/* Creates a sub-bitmap of the parent, at the specified coordinates and of the
* specified size. A sub-bitmap is a bitmap that shares drawing memory with a
* pre-existing (parent) bitmap, but possibly with a different size and clipping
* settings.
*
* If the sub-bitmap does not lie completely inside the parent bitmap, then
* it is automatically clipped so that it does.
*
* The parent bitmap's clipping rectangles are ignored.
*
* If a sub-bitmap was not or cannot be created then NULL is returned.
*
* Note that destroying parents of sub-bitmaps will not destroy the
* sub-bitmaps; instead the sub-bitmaps become invalid and should no
* longer be used.
*/
ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent, int x, int y, int w, int h);


Drawing

al_put_pixel

void al_put_pixel(int x, int y, ALLEGRO_COLOR *color);

al_get_pixel

ALLEGRO_COLOR *al_get_pixel(ALLEGRO_BITMAP *bitmap, int x, int  y, ALLEGRO_COLOR *color);

al_draw_bitmap

  • For details, see Bob's al_blit. The allowed flags are:
    • ALLEGRO_FLIP_HORIZONTAL
    • ALLEGRO_FLIP_VERTICAL
void al_draw_bitmap(ALLEGRO_BITMAP *bitmap, int dx, int dy, int flags)

al_draw_bitmap_region

al_draw_bitmap_region(ALLEGRO_BITMAP *bitmap, int sx, int sy, int sw, int sh, int dx, int dy, int flags);
/*
* al_draw_bitmap_region(bitmap, 0, 0, bitmap->w, bitmap->h, dx, dy, flags)
* is identical to
* al_draw_bitmap(bitmap, dx, dy, flags)
*/

al_draw_scaled_bitmap

al_draw_scaled_bitmap(ALLEGRO_BITMAP *bitmap, int sx, int sy, int swidth, int sheight,
int dx, int dy, int dwidth, int dheight, int flags)
/*
* al_draw_scaled_bitmap(bitmap, 0, 0, bitmap->w, bitmap->h, dx, dy, bitmap->w, bitmap->h, flags)
* is identical to
* al_draw_bitmap(bitmap, dx, dy, flags)
*/

al_draw_rotated_bitmap

Draws a bitmap rotated counter-clockwise by angle, which is measured in radians. The point center_x, center_y will be drawn at dx, dy with the bitmap rotated around that point.

al_draw_rotated_bitmap(ALLEGRO_BITMAP *bitmap, int center_x, int center_y,
int dx, int dy, float angle, int flags)
/*
* al_draw_rotated_bitmap(bitmap, 0, 0, dx, dy, 0, flags)
* is identical to
* al_draw_bitmap(bitmap, dx, dy, flags)
*/

al_draw_rotated_scaled_bitmap

Like al_draw_rotated_bitmap, but can also scale the bitmap. center_x and center_y are in source bitmap coordinates.

al_draw_rotated_scaled_bitmap(ALLEGRO_BITMAP *bitmap, int center_x, int center_y,
int dx, int dy, float x_scale, float y_scale, float angle, int flags)
/*
* al_draw_rotated_scaled_bitmap(bitmap, 0, 0, dx, dy, 1, 1, 0, flags)
* is identical to
* al_draw_bitmap(bitmap, dx, dy, flags)
*/


Primitives

al_draw_line

Draws a line to the current target.

void al_draw_line(int x1, int y1, int x2, int y2, ALLEGRO_COLOR *color);

al_draw_filled_rectangle

Draws a filled rectangle to the current target.

void al_draw_filled_rectangle(int x1, int y1, int x2, int y2, ALLEGRO_COLOR *color);


Locking

al_lock_bitmap

bool al_lock_bitmap(ALLEGRO_BITMAP *bitmap, ALLEGRO_LOCKED_REGION *locked_region, int flags);

Lock an entire bitmap for reading or writing. If the bitmap is a display bitmap it will be updated from system memory after the bitmap is unlocked. locked_region must point to an already allocated ALLEGRO_LOCKED_REGION structure. Returns false if the bitmap cannot be locked, e.g. the bitmap was locked previously and not unlocked.

Flags are:

  • ALLEGRO_LOCK_READONLY - The locked region will not be written to. This can be faster if the bitmap is a video texture, as it can be discarded after the lock instead of uploaded back to the card.

al_lock_bitmap_region

bool al_lock_bitmap_region(ALLEGRO_BITMAP *bitmap, int x, int y,
int width, int height, ALLEGRO_LOCKED_REGION *locked_region, int flags);

Like al_lock_bitmap, but only locks a specific area of the bitmap. If the bitmap is a display bitmap, only that area of the texture will be updated when it is unlocked. Locking only the region you indend to modify will be faster than locking the whole bitmap.

al_unlock_bitmap

void al_unlock_bitmap(ALLEGRO_BITMAP *bitmap);

Unlock a previously locked bitmap or bitmap region. If the bitmap is a display bitmap, the texture will be updated to match the system memory copy.

Personal tools