The Allegro Wiki is migrating to github at https://github.com/liballeg/allegro_wiki/wiki

NewAPI/Primitives

From Allegro Wiki
Jump to: navigation, search

Allegro 5 will have a set of new functions for drawing the various primitives that were available in Allegro 4. Unlike Allegro 4, however, these new functions shall be able to take floating point coordinates as their arguments. There are three major goals for these new functions:

  • Speed - The new functions must be as fast as possible, meeting and exceeding the speeds of Allegro 4's equivalents where possible
  • Accuracy - The new functions must be sub-pixel accurate as much as possible
  • Quality - The output of the new functions should match the output of the HW accelerated equivalents pixel for pixel

Primary functions

  • al_draw_primitive_2d(AL_BITMAP* bmp, AL_VERTEX2D* vtx, int num_primitives, int prim_type)

Draws the various primitives from an array of vertices. The num_primitives counts the number of primitives, so 1 line per 2 vertices, if it's a line list, or 1 + N vertices for N lines for line list. bmp, if not 0, makes the primitives use that texture.

Type can be one of the following:

  • AL_POINT_LIST - N vertices, draws N points
  • AL_LINE_LIST - 2N vertices, draws N lines, each vertex pair defines a line segment
  • AL_LINE_STRIP - N + 1 vertices, draws N lines, all connected to each other, end to end
  • AL_LINE_LOOP - N - 1 vertices, draws N lines connected in a loop
  • AL_TRI_LIST - 3N vertices, draws N triangles, each vertex triple defines a new triangle
  • AL_TRI_FAN - N + 2 vertices, draws N triangles using the fan method
  • AL_TRI_STRIP - N + 2 vertices, draws N triangles in a strip


  • al_draw_primitive_2d_idx(AL_BITMAP* bmp, AL_VERTEX2D* vtx, int* idx, int num_primitives, int prim_type)

An indexed version of the above. The idx points to an array of integers that are the indices into the vtx array. Num primitives now figures into the size of the idx instead of vtx.

AL_VERTEX2D shall probably look like this:

<highlightSyntax language="cpp">

typedef struct {

   float a,r,g,b;//color components, perhaps use the ALLEGRO_COLOR which is internally that, or not
   float u,v;//u,v texture parameters
   float x,y;//coordinates of the point

} AL_VERTEX2D;

</highlightSyntax>

Secondary Functions

These just make the life for an average user easier by calling the primary function with some useful vertex arrangements.

  • Linear Primitives
    • al_draw_line(float x1, float y1, float y1, float y2, ALLEGRO_COLOR color1, ALLEGRO_COLOR color2, float thickness) - draws a line, blending between the two colours, thickness <= 0 draws the hairline line, otherwise it draws a rotated rectangle
    • al_draw_triangle - won't be present, just use the main function
    • al_draw_rect - won't be present, just use the main function
  • Quadratic Primitives
    • al_draw_circle(float cx, float cy, float r, float thickness, ALLEGRO_COLOR color1, ALLEGRO_COLOR color2, int filled) - draws a circle with radius r, at center cx, cy. thickness <= 0 and filled = 0 will draw a hairline circle, otherwise drawing a thick circle. For a thick circle, the colour is interpolated from inner boundary to the outer-boundary (color1 to color2) If filled = 1 then it draws the filled circle, interpolating between the two colors, center to edge. Note, the linked article describes a pixel perfect circle, what is actually planned as this point is the polygonal approximation
    • al_draw_arc(float cx, float cy, float r, float a1, float a2, float thickness, ALLEGRO_COLOR color1, ALLEGRO_COLOR color2, int filled) - same as the circle, instead drawing a section of it defined by the two angles. Filled arc = pieslice, outlined arc = only the outer circle part drawn
    • al_draw_ellipse(float cx, float cy, float r1, float r2, float a, float thickness, ALLEGRO_COLOR color1, ALLEGRO_COLOR color2, int filled) - same as circle, but uses two differing radii to draw an ellipse. The a parameter rotates the ellipse.
    • al_draw_ellipse_arc() - probably not very useful?
  • Cubic Primitives
    • al_draw_bezier(AL_VERTEX* control_points, float thickness) - draws a bezier line from the control points, the colours etc of the control points are interpolated along the generated bezier points

Other Potential Functions

  • al_set_transform(AL_TRANSFORM* transform)
  • al_mult_transform(AL_TRANSFORM* transform)

Two functions to expose the matrix setting functionality of D3D and OpenGL, would be applied to all of the primitive calls, perhaps useful? AL_TRANSFORM would be a matrix.

  • al_bind_texture(AL_BITMAP* bmp)

Binds the texture, allows for removal of the first parameter of the al_draw_primitives -> will have an internal equivalent anyway, perhaps useful to expose as public API though?

Thoughts

Perhaps replace the secondary structures with point generators, i.e.

  • void al_calc_circle(AL_VERTEX* vtx, float cx, float cy, float r, float thickness, float filled, int n) - returns the computed vertices of a circle, which can then be assigned whatever texture coordinates the user might want.

Same for all other functions. As of now, I was thinking of assigning reasonable texture coordinates, (so radial mapping for circles for example). Naturally, having these calculator functions is more flexible, but they require many more lines to use.

<highlightSyntax language="cpp"> al_draw_circle(0,0, 200, -1, blah, bleh, 0)

//vs

AL_VERTEX vtx[20]; al_calc_circle(vtx, 0,0, 200, -1, 0, 20) vtx[0].r = blah.r;//the center vertex vtx[0].g = blah.g; vtx[0].b = blah.b; vtx[0].a = blah.a;

for(int ii = 1; ii < 20; ii++) {

   vtx[ii].r = bleh.r;
   vtx[ii].g = bleh.g;
   vtx[ii].b = bleh.b;
   vtx[ii].a = bleh.a;

}

al_draw_primitives(vtx, 20, AL_TRI_FAN); </highlightSyntax>

Or perhaps include both?

Status

Read this as follows: as soon as all of the queued items are done, a logical release can be made. Here's the planned release schedule:

  1. Software Buffers + Transforms + All Non-Textured Outlined Primitives
  2. All Non-Textured Filled Primitives
  3. All Textured Outlined Primitives
  4. All Textured Filled Primitives
  5. OpenGL/DirectX Buffers
  6. Specialized Software Routines


  • Vertex Buffers
    • General API - done
    • Software - done
    • OpenGL -
    • DirectX -
  • Low level primitives
    • Software
      • Lines
        • Clipping -
        • Generic Non-Textured - done
        • Generic Textured - queued
        • Specialized - (can't without A5 API change at this point (or incorporating this into the core))
      • Triangles
        • Clipping -
        • Generic Non-Textured - done
        • Generic Textured - queued
        • Specialized - (can't without A5 API change at this point (or incorporating this into the core))
    • OpenGL
      • Lines
        • Generic Non-Textured - done
        • Generic Textured - queued
      • Triangles
        • Generic Non-Textured - done
        • Generic Textured - queued
    • DirectX
      • Lines
        • Generic Non-Textured - done
        • Generic Textured -
      • Triangles
        • Generic Non-Textured - done
        • Generic Textured -
  • High Level Primitives
    • Outlined - done
    • Filled - done
  • Transformations
    • General API - done
    • Software Transforms - done
    • OpenGL Transforms - done
    • DirectX Transforms - done

New Stuff For the Future

  • Remove the general read/write flags for buffers: I think doing memory then video constant and then video mutable buffers is simpler
    • ALLEGRO_VBUFF_VIDEO_CONST, ALLEGRO_VBUFF_VIDEO_MUTABLE (memory by default)
  • Instead of having global primitive flags for 3d vs 2d and number of textures, I think it be better if I make vertex buffer be typed in that sense
    • I.e. ALLEGRO_VBUFF_3D, ALLEGRO_VBUFF_TEXTURE, ALLEGRO_VBUFF_2TEXTURE (2d, no texture by default)
    • Those possibilities will alter the vertex formats used
    • A possible problem is the case when you want to transform a 2D buffer with 3D transformations... do you ever want to do this?
  • Remove normals from vertices, I can't imagine a use case for them anymore
  • Add multitexture support
    • Not sure how to do this yet, either pass a struct to al_draw_prim which would contain the two textures, or add functions to set the textures globally
  • New Vertex Buffer

Stuff For The Future

  • What to do about the Z-buffer?