These functions are declared in the following header file. Link with allegro_primitives.
#include <allegro5/allegro_primitives.h>
uint32_t al_get_allegro_primitives_version(void)
Returns the (compiled) version of the addon, in the same format as al_get_allegro_version.
bool al_init_primitives_addon(void)
Initializes the primitives addon.
Returns: True on success, false on failure.
See also: al_shutdown_primitives_addon
Examples:
bool al_is_primitives_addon_initialized(void)
Returns true if the primitives addon is initialized, otherwise returns false.
Since: 5.2.6
See also: al_init_primitives_addon, al_shutdown_primitives_addon
void al_shutdown_primitives_addon(void)
Shut down the primitives addon. This is done automatically at program exit, but can be called any time the user wishes as well.
See also: al_init_primitives_addon
High level drawing routines encompass the most common usage of this addon: to draw geometric primitives, both smooth (variations on the circle theme) and piecewise linear. Outlined primitives support the concept of thickness with two distinct modes of output: hairline lines and thick lines. Hairline lines are specifically designed to be exactly a pixel wide, and are commonly used for drawing outlined figures that need to be a pixel wide. Hairline thickness is designated as thickness less than or equal to 0. Unfortunately, the exact rasterization rules for drawing these hairline lines vary from one video card to another, and sometimes leave gaps where the lines meet. If that matters to you, then you should use thick lines. In many cases, having a thickness of 1 will produce 1 pixel wide lines that look better than hairline lines. Obviously, hairline lines cannot replicate thicknesses greater than 1. Thick lines grow symmetrically around the generating shape as thickness is increased.
While normally you should not be too concerned with which pixels are displayed when the high level primitives are drawn, it is nevertheless possible to control that precisely by carefully picking the coordinates at which you draw those primitives.
To be able to do that, however, it is critical to understand how GPU cards convert shapes to pixels. Pixels are not the smallest unit that can be addressed by the GPU. Because the GPU deals with floating point coordinates, it can in fact assign different coordinates to different parts of a single pixel. To a GPU, thus, a screen is composed of a grid of squares that have width and length of 1. The top left corner of the top left pixel is located at (0, 0). Therefore, the center of that pixel is at (0.5, 0.5). The basic rule that determines which pixels are associated with which shape is then as follows: a pixel is treated to belong to a shape if the pixel’s center is located in that shape. The figure below illustrates the above concepts:
This figure depicts three shapes drawn at the top left of the screen: an orange and green rectangles and a purple circle. On the left are the mathematical descriptions of pixels on the screen and the shapes to be drawn. On the right is the screen output. Only a single pixel has its center inside the circle, and therefore only a single pixel is drawn on the screen. Similarly, two pixels are drawn for the orange rectangle. Since there are no pixels that have their centers inside the green rectangle, the output image has no green pixels.
Here is a more practical example. The image below shows the output of this code:
/* blue vertical line */
(0.5, 0, 0.5, 6, color_blue, 1);
al_draw_line/* red horizontal line */
(2, 1, 6, 1, color_red, 2);
al_draw_line/* green filled rectangle */
(3, 4, 5, 5, color_green);
al_draw_filled_rectangle/* purple outlined rectangle */
(2.5, 3.5, 5.5, 5.5, color_purple, 1); al_draw_rectangle
It can be seen that lines are generated by making a rectangle based
on the dashed line between the two endpoints. The thickness causes the
rectangle to grow symmetrically about that generating line, as can be
seen by comparing the red and blue lines. Note that to get proper pixel
coverage, the coordinates passed to the al_draw_line
had to
be offset by 0.5 in the appropriate dimensions.
Filled rectangles are generated by making a rectangle between the
endpoints passed to the al_draw_filled_rectangle
.
Outlined rectangles are generated by symmetrically expanding an outline of a rectangle. With a thickness of 1, as depicted in the diagram, this means that an offset of 0.5 is needed for both sets of endpoint coordinates to exactly line up with the pixels of the display raster.
The above rules only apply when multisampling is turned off. When multisampling is turned on, the area of a pixel that is covered by a shape is taken into account when choosing what color to draw there. This also means that shapes no longer have to contain the pixel’s center to affect its color. For example, the green rectangle in the first diagram may in fact be drawn as two (or one) semi-transparent pixels. The advantages of multisampling is that slanted shapes will look smoother because they will not have jagged edges. A disadvantage of multisampling is that it may make vertical and horizontal edges blurry. While the exact rules for multisampling are unspecified, and may vary from GPU to GPU, it is usually safe to assume that as long as a pixel is either completely covered by a shape or completely not covered, then the shape edges will be sharp. The offsets used in the second diagram were chosen so that this is the case: if you use those offsets, your shapes (if they are oriented the same way as they are on the diagram) should look the same whether multisampling is turned on or off.
void al_draw_line(float x1, float y1, float x2, float y2,
, float thickness) ALLEGRO_COLOR color
Draws a line segment between two points.
Parameters:
<= 0
to draw
hairline linesSee also: al_draw_soft_line
Examples:
void al_draw_triangle(float x1, float y1, float x2, float y2,
float x3, float y3, ALLEGRO_COLOR color, float thickness)
Draws an outlined triangle.
Parameters:
<= 0
to
draw hairline linesSee also: al_draw_filled_triangle, al_draw_soft_triangle
Examples:
void al_draw_filled_triangle(float x1, float y1, float x2, float y2,
float x3, float y3, ALLEGRO_COLOR color)
Draws a filled triangle.
Parameters:
See also: al_draw_triangle
Examples:
void al_draw_rectangle(float x1, float y1, float x2, float y2,
, float thickness) ALLEGRO_COLOR color
Draws an outlined rectangle.
Parameters:
<= 0
to
draw hairline linesSee also: al_draw_filled_rectangle, al_draw_rounded_rectangle
Examples:
void al_draw_filled_rectangle(float x1, float y1, float x2, float y2,
) ALLEGRO_COLOR color
Draws a filled rectangle.
Parameters:
See also: al_draw_rectangle, al_draw_filled_rounded_rectangle
Examples:
void al_draw_rounded_rectangle(float x1, float y1, float x2, float y2,
float rx, float ry, ALLEGRO_COLOR color, float thickness)
Draws an outlined rounded rectangle.
Parameters:
<= 0
to
draw hairline linesSee also: al_draw_filled_rounded_rectangle, al_draw_rectangle
Examples:
void al_draw_filled_rounded_rectangle(float x1, float y1, float x2, float y2,
float rx, float ry, ALLEGRO_COLOR color)
Draws an filled rounded rectangle.
Parameters:
See also: al_draw_rounded_rectangle, al_draw_filled_rectangle
Examples:
void al_calculate_arc(float* dest, int stride, float cx, float cy,
float rx, float ry, float start_theta, float delta_theta, float thickness,
int num_points)
When thickness <= 0
this function computes positions
of num_points
regularly spaced points on an elliptical arc.
When thickness > 0
this function computes two sets of
points, obtained as follows: the first set is obtained by taking the
points computed in the thickness <= 0
case and shifting
them by thickness / 2
outward, in a direction perpendicular
to the arc curve. The second set is the same, but shifted
thickness / 2
inward relative to the arc. The two sets of
points are interleaved in the destination buffer (i.e. the first pair of
points will be collinear with the arc center, the first point of the
pair will be farther from the center than the second point; the next
pair will also be collinear, but at a different angle and so on).
The destination buffer dest
is interpreted as a set of
regularly spaced pairs of floats, each pair holding the coordinates of
the corresponding point on the arc. The two floats in the pair are
adjacent, and the distance (in bytes) between the addresses of the first
float in two successive pairs is stride
. For example, if
you have a tightly packed array of floats with no spaces between pairs,
then stride
will be exactly
2 * sizeof(float)
.
Example with thickness <= 0
:
const int num_points = 4;
float points[num_points][2];
(&points[0][0], 2 * sizeof(float), 0, 0, 10, 10, 0, ALLEGRO_PI / 2, 0, num_points);
al_calculate_arc
((int)points[0][0] == 10);
assert((int)points[0][1] == 0);
assert
((int)points[num_points - 1][0] == 0);
assert((int)points[num_points - 1][1] == 10); assert
Example with thickness > 0
:
const int num_points = 4;
float points[num_points * 2][2];
(&points[0][0], 2 * sizeof(float), 0, 0, 10, 10, 0, ALLEGRO_PI / 2, 2, num_points);
al_calculate_arc
((int)points[0][0] == 11);
assert((int)points[0][1] == 0);
assert((int)points[1][0] == 9);
assert((int)points[1][1] == 0);
assert
((int)points[(num_points - 1) * 2][0] == 0);
assert((int)points[(num_points - 1) * 2][1] == 11);
assert((int)points[(num_points - 1) * 2 + 1][0] == 0);
assert((int)points[(num_points - 1) * 2 + 1][1] == 9); assert
Parameters:
See also: al_draw_arc, al_calculate_spline, al_calculate_ribbon
Examples:
void al_draw_pieslice(float cx, float cy, float r, float start_theta,
float delta_theta, ALLEGRO_COLOR color, float thickness)
Draws a pieslice (outlined circular sector).
Parameters:
<= 0
to
draw hairline piesliceSince: 5.0.6, 5.1.0
See also: al_draw_filled_pieslice
Examples:
void al_draw_filled_pieslice(float cx, float cy, float r, float start_theta,
float delta_theta, ALLEGRO_COLOR color)
Draws a filled pieslice (filled circular sector).
Parameters:
Since: 5.0.6, 5.1.0
See also: al_draw_pieslice
Examples:
void al_draw_ellipse(float cx, float cy, float rx, float ry,
, float thickness) ALLEGRO_COLOR color
Draws an outlined ellipse.
Parameters:
<= 0
to
draw a hairline ellipseSee also: al_draw_filled_ellipse, al_draw_circle
Examples:
void al_draw_filled_ellipse(float cx, float cy, float rx, float ry,
) ALLEGRO_COLOR color
Draws a filled ellipse.
Parameters:
See also: al_draw_ellipse, al_draw_filled_circle
Examples:
void al_draw_circle(float cx, float cy, float r, ALLEGRO_COLOR color,
float thickness)
Draws an outlined circle.
Parameters:
<= 0
to
draw a hairline circleSee also: al_draw_filled_circle, al_draw_ellipse
Examples:
void al_draw_filled_circle(float cx, float cy, float r, ALLEGRO_COLOR color)
Draws a filled circle.
Parameters:
See also: al_draw_circle, al_draw_filled_ellipse
Examples:
void al_draw_arc(float cx, float cy, float r, float start_theta,
float delta_theta, ALLEGRO_COLOR color, float thickness)
Draws an arc.
Parameters:
<= 0
to draw
hairline arcSee also: al_calculate_arc, al_draw_elliptical_arc
Examples:
void al_draw_elliptical_arc(float cx, float cy, float rx, float ry, float start_theta,
float delta_theta, ALLEGRO_COLOR color, float thickness)
Draws an elliptical arc.
Parameters:
<= 0
to draw
hairline arcSince: 5.0.6, 5.1.0
See also: al_calculate_arc, al_draw_arc
Examples:
void al_calculate_spline(float* dest, int stride, float points[8],
float thickness, int num_segments)
Calculates a Bézier spline given 4 control points. If
thickness <= 0
, then num_segments
of points
are required in the destination, otherwise twice as many are needed. The
destination buffer should consist of regularly spaced (by distance of
stride bytes) doublets of floats, corresponding to x and y coordinates
of the vertices.
Parameters:
See also: al_draw_spline, al_calculate_arc, al_calculate_ribbon
void al_draw_spline(float points[8], ALLEGRO_COLOR color, float thickness)
Draws a Bézier spline given 4 control points.
Parameters:
<= 0
to
draw a hairline splineSee also: al_calculate_spline
Examples:
void al_calculate_ribbon(float* dest, int dest_stride, const float *points,
int points_stride, float thickness, int num_segments)
Calculates a ribbon given an array of points. The ribbon will go
through all of the passed points. If thickness <= 0
,
then num_segments
of points are required in the destination
buffer, otherwise twice as many are needed. The destination and the
points buffer should consist of regularly spaced doublets of floats,
corresponding to x and y coordinates of the vertices.
Parameters:
See also: al_draw_ribbon, al_calculate_arc, al_calculate_spline
void al_draw_ribbon(const float *points, int points_stride, ALLEGRO_COLOR color,
float thickness, int num_segments)
Draws a ribbon given an array of points. The ribbon will go through all of the passed points. The points buffer should consist of regularly spaced doublets of floats, corresponding to x and y coordinates of the vertices.
Parameters:
<= 0
to
draw hairline splineSee also: al_calculate_ribbon
Low level drawing routines allow for more advanced usage of the addon, allowing you to pass arbitrary sequences of vertices to draw to the screen. These routines also support using textures on the primitives with the following restrictions:
For maximum portability, you should only use textures that have dimensions that are a power of two, as not every videocard supports textures of different sizes completely. This warning is relaxed, however, if the texture coordinates never exit the boundaries of a single bitmap (i.e. you are not having the texture repeat/tile). As long as that is the case, any texture can be used safely. Sub-bitmaps work as textures, but cannot be tiled.
Some platforms also dictate a minimum texture size, which means that textures smaller than that size will not tile properly. The minimum size that will work on all platforms is 32 by 32.
A note about pixel coordinates. In OpenGL the texture coordinate (0, 0) refers to the top left corner of the pixel. This confuses some drivers, because due to rounding errors the actual pixel sampled might be the pixel to the top and/or left of the (0, 0) pixel. To make this error less likely it is advisable to offset the texture coordinates you pass to the al_draw_prim by (0.5, 0.5) if you need precise pixel control. E.g. to refer to pixel (5, 10) you’d set the u and v to 5.5 and 10.5 respectively.
See also: Pixel-precise output
int al_draw_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl,
* texture, int start, int end, int type) ALLEGRO_BITMAP
Draws a subset of the passed vertex array.
Parameters:
Returns: Number of primitives drawn
For example to draw a textured triangle you could use:
= al_map_rgb_f(1, 1, 1);
ALLEGRO_COLOR white [] = {
ALLEGRO_VERTEX v{.x = 128, .y = 0, .z = 0, .color = white, .u = 128, .v = 0},
{.x = 0, .y = 256, .z = 0, .color = white, .u = 0, .v = 256},
{.x = 256, .y = 256, .z = 0, .color = white, .u = 256, .v = 256}};
(v, NULL, texture, 0, 3, ALLEGRO_PRIM_TRIANGLE_LIST); al_draw_prim
See also: ALLEGRO_VERTEX, ALLEGRO_PRIM_TYPE, ALLEGRO_VERTEX_DECL, al_draw_indexed_prim
Examples:
int al_draw_indexed_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl,
* texture, const int* indices, int num_vtx, int type) ALLEGRO_BITMAP
Draws a subset of the passed vertex array. This function uses an index array to specify which vertices to use.
Parameters:
Returns: Number of primitives drawn
See also: ALLEGRO_VERTEX, ALLEGRO_PRIM_TYPE, ALLEGRO_VERTEX_DECL, al_draw_prim
Examples:
int al_draw_vertex_buffer(ALLEGRO_VERTEX_BUFFER* vertex_buffer,
* texture, int start, int end, int type) ALLEGRO_BITMAP
Draws a subset of the passed vertex buffer. The vertex buffer must
not be locked. Additionally, to draw onto memory bitmaps or with memory
bitmap textures the vertex buffer must support reading (i.e. it must be
created with the ALLEGRO_PRIM_BUFFER_READWRITE
).
Parameters:
Returns: Number of primitives drawn
Since: 5.1.3
See also: ALLEGRO_VERTEX_BUFFER, ALLEGRO_PRIM_TYPE
Examples:
int al_draw_indexed_buffer(ALLEGRO_VERTEX_BUFFER* vertex_buffer,
* texture, ALLEGRO_INDEX_BUFFER* index_buffer,
ALLEGRO_BITMAPint start, int end, int type)
Draws a subset of the passed vertex buffer. This function uses an
index buffer to specify which vertices to use. Both buffers must not be
locked. Additionally, to draw onto memory bitmaps or with memory bitmap
textures both buffers must support reading (i.e. they must be created
with the ALLEGRO_PRIM_BUFFER_READWRITE
).
Parameters:
Returns: Number of primitives drawn
Since: 5.1.8
See also: ALLEGRO_VERTEX_BUFFER, ALLEGRO_INDEX_BUFFER, ALLEGRO_PRIM_TYPE
Examples:
void al_draw_soft_triangle(
* v1, ALLEGRO_VERTEX* v2, ALLEGRO_VERTEX* v3, uintptr_t state,
ALLEGRO_VERTEXvoid (*init)(uintptr_t, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*),
void (*first)(uintptr_t, int, int, int, int),
void (*step)(uintptr_t, int),
void (*draw)(uintptr_t, int, int, int))
Draws a triangle using the software rasterizer and user supplied pixel functions. For help in understanding what these functions do, see the implementation of the various shading routines in addons/primitives/tri_soft.c. The triangle is drawn in two segments, from top to bottom. The segments are deliniated by the vertically middle vertex of the triangle. One of the two segments may be absent if two vertices are horizontally collinear.
Parameters:
See also: al_draw_triangle
void al_draw_soft_line(ALLEGRO_VERTEX* v1, ALLEGRO_VERTEX* v2, uintptr_t state,
void (*first)(uintptr_t, int, int, ALLEGRO_VERTEX*, ALLEGRO_VERTEX*),
void (*step)(uintptr_t, int),
void (*draw)(uintptr_t, int, int))
Draws a line using the software rasterizer and user supplied pixel functions. For help in understanding what these functions do, see the implementation of the various shading routines in addons/primitives/line_soft.c. The line is drawn top to bottom.
Parameters:
See also: al_draw_line
* al_create_vertex_decl(const ALLEGRO_VERTEX_ELEMENT* elements, int stride) ALLEGRO_VERTEX_DECL
Creates a vertex declaration, which describes a custom vertex format.
Parameters:
Returns: Newly created vertex declaration.
See also: ALLEGRO_VERTEX_ELEMENT, ALLEGRO_VERTEX_DECL, al_destroy_vertex_decl
Examples:
void al_destroy_vertex_decl(ALLEGRO_VERTEX_DECL* decl)
Destroys a vertex declaration.
Parameters:
See also: ALLEGRO_VERTEX_ELEMENT, ALLEGRO_VERTEX_DECL, al_create_vertex_decl
Examples:
* al_create_vertex_buffer(ALLEGRO_VERTEX_DECL* decl,
ALLEGRO_VERTEX_BUFFERconst void* initial_data, int num_vertices, int flags)
Creates a vertex buffer. Can return NULL if the buffer could not be created (e.g. the system only supports write-only buffers).
Note:
This is an advanced feature, often unsupported on lower-end video cards. Be extra mindful of this function failing and make arrangements for fallback drawing functionality or a nice error message for users with such lower-end cards.
Parameters:
NULL
, in which case the buffer is
uninitialized.ALLEGRO_PRIM_BUFFER_STATIC
.Since: 5.1.3
See also: ALLEGRO_VERTEX_BUFFER, al_destroy_vertex_buffer
Examples:
void al_destroy_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer)
Destroys a vertex buffer. Does nothing if passed NULL.
Since: 5.1.3
See also: ALLEGRO_VERTEX_BUFFER, al_create_vertex_buffer
Examples:
void* al_lock_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer, int offset,
int length, int flags)
Locks a vertex buffer so you can access its data. Will return NULL if the parameters are invalid, if reading is requested from a write only buffer, or if the buffer is already locked.
Parameters:
Since: 5.1.3
See also: ALLEGRO_VERTEX_BUFFER, al_unlock_vertex_buffer
Examples:
void al_unlock_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer)
Unlocks a previously locked vertex buffer.
Since: 5.1.3
See also: ALLEGRO_VERTEX_BUFFER, al_lock_vertex_buffer
Examples:
int al_get_vertex_buffer_size(ALLEGRO_VERTEX_BUFFER* buffer)
Returns the size of the vertex buffer
Since: 5.1.8
See also: ALLEGRO_VERTEX_BUFFER
* al_create_index_buffer(int index_size,
ALLEGRO_INDEX_BUFFERconst void* initial_data, int num_indices, int flags)
Creates a index buffer. Can return NULL if the buffer could not be created (e.g. the system only supports write-only buffers).
Note:
This is an advanced feature, often unsupported on lower-end video cards. Be extra mindful of this function failing and make arrangements for fallback drawing functionality or a nice error message for users with such lower-end cards.
Parameters:
NULL
, in which case the buffer is
uninitialized.ALLEGRO_PRIM_BUFFER_STATIC
.Since: 5.1.8
See also: ALLEGRO_INDEX_BUFFER, al_destroy_index_buffer
Examples:
void al_destroy_index_buffer(ALLEGRO_INDEX_BUFFER* buffer)
Destroys a index buffer. Does nothing if passed NULL.
Since: 5.1.8
See also: ALLEGRO_INDEX_BUFFER, al_create_index_buffer
Examples:
void* al_lock_index_buffer(ALLEGRO_INDEX_BUFFER* buffer, int offset,
int length, int flags)
Locks a index buffer so you can access its data. Will return NULL if the parameters are invalid, if reading is requested from a write only buffer and if the buffer is already locked.
Parameters:
Since: 5.1.8
See also: ALLEGRO_INDEX_BUFFER, al_unlock_index_buffer
Examples:
void al_unlock_index_buffer(ALLEGRO_INDEX_BUFFER* buffer)
Unlocks a previously locked index buffer.
Since: 5.1.8
See also: ALLEGRO_INDEX_BUFFER, al_lock_index_buffer
Examples:
int al_get_index_buffer_size(ALLEGRO_INDEX_BUFFER* buffer)
Returns the size of the index buffer
Since: 5.1.8
See also: ALLEGRO_INDEX_BUFFER
void al_draw_polyline(const float* vertices, int vertex_stride,
int vertex_count, int join_style, int cap_style,
, float thickness, float miter_limit) ALLEGRO_COLOR color
Draw a series of line segments.
<= 0
to draw
hairline linesThe stride is normally 2 * sizeof(float)
but may be more
if the vertex coordinates are in an array of some structure type,
e.g.
struct VertexInfo {
float x;
float y;
int id;
};
void my_draw(struct VertexInfo verts[], int vertex_count, ALLEGRO_COLOR c)
{
((float *)verts, sizeof(VertexInfo), vertex_count,
al_draw_polyline, ALLEGRO_LINE_CAP_NONE, c, 1.0, 1.0);
ALLEGRO_LINE_JOIN_NONE}
The stride may also be negative if the vertices are stored in reverse order.
Since: 5.1.0
See also: al_draw_polygon, ALLEGRO_LINE_JOIN, ALLEGRO_LINE_CAP
Examples:
void al_draw_polygon(const float *vertices, int vertex_count,
int join_style, ALLEGRO_COLOR color, float thickness, float miter_limit)
Draw an unfilled polygon. This is the same as passing
ALLEGRO_LINE_CAP_CLOSED
to al_draw_polyline.
<= 0
to draw
hairline linesSince: 5.1.0
See also: al_draw_filled_polygon, al_draw_polyline, ALLEGRO_LINE_JOIN
Examples:
void al_draw_filled_polygon(const float *vertices, int vertex_count,
) ALLEGRO_COLOR color
Draw a filled, simple polygon. Simple means it does not have to be convex but must not be self-overlapping.
When the y-axis is facing downwards (the usual), the coordinates must be ordered anti-clockwise.
Since: 5.1.0
See also: al_draw_polygon, al_draw_filled_polygon_with_holes
Examples:
void al_draw_filled_polygon_with_holes(const float *vertices,
const int *vertex_counts, ALLEGRO_COLOR color)
Draws a filled simple polygon with zero or more other simple polygons subtracted from it - the holes. The holes cannot touch or intersect with the outline of the filled polygon.
When the y-axis is facing downwards (the usual) the filled polygon coordinates must be ordered anti-clockwise. All hole vertices must use the opposite order (clockwise with y down). All hole vertices must be inside the main polygon and no hole may overlap the main polygon.
For example:
float vertices[] = {
0, 0, // filled polygon, upper left corner
0, 100, // filled polygon, lower left corner
100, 100, // filled polygon, lower right corner
100, 0, // filled polygon, upper right corner
10, 10, // hole, upper left
90, 10, // hole, upper right
90, 90 // hole, lower right
};
int vertex_counts[] = {
4, // number of vertices for filled polygon
3, // number of vertices for hole
0 // terminator
};
There are 7 vertices: four for an outer square from (0, 0) to (100, 100) in anti-clockwise order, and three more for an inner triangle in clockwise order. The outer main polygon uses vertices 0 to 3 (inclusive) and the hole uses vertices 4 to 6 (inclusive).
Since: 5.1.0
See also: al_draw_filled_polygon, al_draw_filled_polygon_with_holes, al_triangulate_polygon
Examples:
bool al_triangulate_polygon(
const float* vertices, size_t vertex_stride, const int* vertex_counts,
void (*emit_triangle)(int, int, int, void*), void* userdata)
Divides a simple polygon into triangles, with zero or more other simple polygons subtracted from it - the holes. The holes cannot touch or intersect with the outline of the main polygon. Simple means the polygon does not have to be convex but must not be self-overlapping.
Parameters:
vertices
and userdata
.Since: 5.1.0
See also: al_draw_filled_polygon_with_holes
typedef struct ALLEGRO_VERTEX ALLEGRO_VERTEX;
Defines the generic vertex type, with a 3D position, color and texture coordinates for a single texture. Note that at this time, the software driver for this addon cannot render 3D primitives. If you want a 2D only primitive, set z to 0. Note that you must initialize all members of this struct when you’re using it. One exception to this rule are the u and v variables which can be left uninitialized when you are not using textures.
Fields:
See also: ALLEGRO_PRIM_ATTR
Examples:
typedef struct ALLEGRO_VERTEX_DECL ALLEGRO_VERTEX_DECL;
A vertex declaration. This opaque structure is responsible for describing the format and layout of a user defined custom vertex. It is created and destroyed by specialized functions.
See also: al_create_vertex_decl, al_destroy_vertex_decl, ALLEGRO_VERTEX_ELEMENT
Examples:
typedef struct ALLEGRO_VERTEX_ELEMENT ALLEGRO_VERTEX_ELEMENT;
A small structure describing a certain element of a vertex. E.g. the position of the vertex, or its color. These structures are used by the al_create_vertex_decl function to create the vertex declaration. For that they generally occur in an array. The last element of such an array should have the attribute field equal to 0, to signify that it is the end of the array. Here is an example code that would create a declaration describing the ALLEGRO_VERTEX structure (passing this as vertex declaration to al_draw_prim would be identical to passing NULL):
/* On compilers without the offsetof keyword you need to obtain the
* offset with sizeof and make sure to account for packing.
*/
[] = {
ALLEGRO_VERTEX_ELEMENT elems{ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, offsetof(ALLEGRO_VERTEX, x)},
{ALLEGRO_PRIM_TEX_COORD_PIXEL, ALLEGRO_PRIM_FLOAT_2, offsetof(ALLEGRO_VERTEX, u)},
{ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ALLEGRO_VERTEX, color)},
{0, 0, 0}
};
* decl = al_create_vertex_decl(elems, sizeof(ALLEGRO_VERTEX)); ALLEGRO_VERTEX_DECL
Fields:
See also: al_create_vertex_decl, ALLEGRO_VERTEX_DECL, ALLEGRO_PRIM_ATTR, ALLEGRO_PRIM_STORAGE
Examples:
typedef enum ALLEGRO_PRIM_TYPE
Enumerates the types of primitives this addon can draw.
ALLEGRO_PRIM_POINT_LIST - A list of points, each vertex defines a point
ALLEGRO_PRIM_LINE_LIST - A list of lines, sequential pairs of vertices define disjointed lines
ALLEGRO_PRIM_LINE_STRIP - A strip of lines, sequential vertices define a strip of lines
ALLEGRO_PRIM_LINE_LOOP - Like a line strip, except at the end the first and the last vertices are also connected by a line
ALLEGRO_PRIM_TRIANGLE_LIST - A list of triangles, sequential triplets of vertices define disjointed triangles
ALLEGRO_PRIM_TRIANGLE_STRIP - A strip of triangles, sequential vertices define a strip of triangles
ALLEGRO_PRIM_TRIANGLE_FAN - A fan of triangles, all triangles share the first vertex
typedef enum ALLEGRO_PRIM_ATTR
Enumerates the types of vertex attributes that a custom vertex may have.
ALLEGRO_PRIM_POSITION - Position information, can be stored only in ALLEGRO_PRIM_SHORT_2, ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_FLOAT_3.
ALLEGRO_PRIM_COLOR_ATTR - Color information, stored in an ALLEGRO_COLOR. The storage field of ALLEGRO_VERTEX_ELEMENT is ignored
ALLEGRO_PRIM_TEX_COORD - Texture coordinate information, can be stored only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. These coordinates are normalized by the width and height of the texture, meaning that the bottom-right corner has texture coordinates of (1, 1).
ALLEGRO_PRIM_TEX_COORD_PIXEL - Texture coordinate information, can be stored only in ALLEGRO_PRIM_FLOAT_2 and ALLEGRO_PRIM_SHORT_2. These coordinates are measured in pixels.
ALLEGRO_PRIM_USER_ATTR - A user specified attribute. You can use
any storage for this attribute. You may have at most
ALLEGRO_PRIM_MAX_USER_ATTR (currently 10) of these that you can specify
by adding an index to the value of ALLEGRO_PRIM_USER_ATTR, e.g. the
first user attribute is ALLEGRO_PRIM_USER_ATTR + 0
, the
second is ALLEGRO_PRIM_USER_ATTR + 1
and so on.
To access these custom attributes from GLSL shaders you need to
declare attributes that follow this nomenclature:
al_user_attr_#
where # is the index of the attribute.
For example to have a position and a normal vector for each vertex you could declare it like this:
[3] = {
ALLEGRO_VERTEX_ELEMENT elements{ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_3, 0},
{ALLEGRO_PRIM_USER_ATTR + 0, ALLEGRO_PRIM_FLOAT_3, 12},
{0, 0, 0}};
And then in your vertex shader access it like this:
; // ALLEGRO_PRIM_POSITION
attribute vec3 al_pos; // ALLEGRO_PRIM_USER_ATTR + 0
attribute vec3 al_user_attr_0float light;
varying const vec3 light_direction = vec3(0, 0, 1);
void main() {
= dot(al_user_attr_0, light_direction);
light = al_pos;
gl_Position }
To access these custom attributes from HLSL you need to declare a
parameter with the following semantics: TEXCOORD{# + 2}
where # is the index of the attribute. E.g. the first attribute can be
accessed via TEXCOORD2
, second via TEXCOORD3
and so on.
Since: 5.1.6
See also: ALLEGRO_VERTEX_DECL, ALLEGRO_PRIM_STORAGE, al_attach_shader_source
typedef enum ALLEGRO_PRIM_STORAGE
Enumerates the types of storage an attribute of a custom vertex may be stored in. Many of these can only be used for ALLEGRO_PRIM_USER_ATTR attributes and can only be accessed via shaders. Usually no matter what the storage is specified the attribute gets converted to single precision floating point when the shader is run. Despite that, it may be advantageous to use more dense storage formats (e.g. ALLEGRO_PRIM_NORMALIZED_UBYTE_4 instead of ALLEGRO_PRIM_FLOAT_4) when bandwidth (amount of memory sent to the GPU) is an issue but precision is not.
ALLEGRO_PRIM_FLOAT_1 - A single float
Since: 5.1.6
ALLEGRO_PRIM_FLOAT_2 - A doublet of floats
ALLEGRO_PRIM_FLOAT_3 - A triplet of floats
ALLEGRO_PRIM_FLOAT_4 - A quad of floats
Since: 5.1.6
ALLEGRO_PRIM_SHORT_2 - A doublet of shorts
ALLEGRO_PRIM_SHORT_4 - A quad of shorts
Since: 5.1.6
ALLEGRO_PRIM_UBYTE_4 - A quad of unsigned bytes
Since: 5.1.6
ALLEGRO_PRIM_NORMALIZED_SHORT_2 - A doublet of shorts. Before being sent to the shader, each component is divided by 32767. Each component of the resultant float doublet ranges between -1.0 and 1.0
Since: 5.1.6
ALLEGRO_PRIM_NORMALIZED_SHORT_4 - A quad of shorts. Before being sent to the shader, each component is divided by 32767. Each component of the resultant float quad ranges between -1.0 and 1.0
Since: 5.1.6
ALLEGRO_PRIM_NORMALIZED_UBYTE_4 - A quad of unsigned bytes. Before being sent to the shader, each component is divided by 255. Each component of the resultant float quad ranges between 0.0 and 1.0
Since: 5.1.6
ALLEGRO_PRIM_NORMALIZED_USHORT_2 - A doublet of unsigned shorts. Before being sent to the shader, each component is divided by 65535. Each component of the resultant float doublet ranges between 0.0 and 1.0
Since: 5.1.6
ALLEGRO_PRIM_NORMALIZED_USHORT_4 - A quad of unsigned shorts. Before being sent to the shader, each component is divided by 65535. Each component of the resultant float quad ranges between 0.0 and 1.0
Since: 5.1.6
ALLEGRO_PRIM_HALF_FLOAT_2 - A doublet of half-precision floats. Note that this storage format is not supported on all platforms. al_create_vertex_decl will return NULL if you use it on those platforms
Since: 5.1.6
ALLEGRO_PRIM_HALF_FLOAT_4 - A quad of half-precision floats. Note that this storage format is not supported on all platforms. al_create_vertex_decl will return NULL if you use it on those platforms.
Since: 5.1.6
See also: ALLEGRO_PRIM_ATTR
#define ALLEGRO_VERTEX_CACHE_SIZE 256
Defines the size of the transformation vertex cache for the software renderer. If you pass less than this many vertices to the primitive rendering functions you will get a speed boost. This also defines the size of the cache vertex buffer, used for the high-level primitives. This corresponds to the maximum number of line segments that will be used to form them.
#define ALLEGRO_PRIM_QUALITY 10
Controls the quality of the approximation of curved primitives (e.g. circles). Curved primitives are drawn by approximating them with a sequence of line segments. By default, this roughly corresponds to error of less than half of a pixel.
typedef enum ALLEGRO_LINE_JOIN
See the picture for the difference.
The maximum miter length (relative to the line width) can be specified as parameter to the polygon functions.
Since: 5.1.0
See also: al_draw_polygon
Examples:
typedef enum ALLEGRO_LINE_CAP
See the picture for the difference.
ALLEGRO_LINE_CAP_CLOSED is different from the others - it causes the polygon to have no caps. (And the ALLEGRO_LINE_JOIN style will determine how the vertex looks.)
Since: 5.1.0
See also: al_draw_polygon
Examples:
typedef struct ALLEGRO_VERTEX_BUFFER ALLEGRO_VERTEX_BUFFER;
A GPU vertex buffer that you can use to store vertices on the GPU instead of uploading them afresh during every drawing operation.
Since: 5.1.3
See also: al_create_vertex_buffer, al_destroy_vertex_buffer
Examples:
typedef struct ALLEGRO_INDEX_BUFFER ALLEGRO_INDEX_BUFFER;
A GPU index buffer that you can use to store indices of vertices in a vertex buffer on the GPU instead of uploading them afresh during every drawing operation.
Since: 5.1.8
See also: al_create_index_buffer, al_destroy_index_buffer
Examples:
typedef enum ALLEGRO_PRIM_BUFFER_FLAGS
Flags to specify how to create a vertex or an index buffer.
ALLEGRO_PRIM_BUFFER_STREAM - Hints to the driver that the buffer is written to often, but used only a few times per frame
ALLEGRO_PRIM_BUFFER_STATIC - Hints to the driver that the buffer is written to once and is used often
ALLEGRO_PRIM_BUFFER_DYNAMIC - Hints to the driver that the buffer is written to often and is used often
ALLEGRO_PRIM_BUFFER_READWRITE - Specifies that you want to be
able read from this buffer. By default this is disabled for performance.
Some platforms (like OpenGL ES) do not support reading from vertex
buffers, so if you pass this flag to
al_create_vertex_buffer
or
al_create_index_buffer
the call will fail.
Since: 5.1.3
See also: al_create_vertex_buffer, al_create_index_buffer