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

Vector graphic objects

From Allegro Wiki
Revision as of 05:23, May 25, 2009 by Matt Smith (talk | contribs) (type definition of LINESEG struct)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Vector Graphic Objects

A VectorGraphics Subject These are the datatypes used in the prototype Vector Render API.

fig 1

Vector shapes are represented in memory by a series of vertices, connected by lines. LINE fragments are joined into PATHs. Where lines intersect, a new PATH is started. Filled AREAs are defined by a list of PATHs. They are defined in order (clockwise).

A small example of a 2d vector object engine in C

type definition of SHAPE struct

<highlightSyntax language="cpp">typedef struct SHAPE {

  V2D_f * verts;    /* list of vertices, including invisible control points */
  LINE * lines;     /* each line segment has 4 control points, 2 are unused for
                       straight segments */
  PATH * paths;     /* each path is a list of line segments */
  AREA * areas;     /* areas are bounded by list of paths (indexed from paths list) */   

} SHAPE;

</highlightSyntax>


type definition of LINESEG struct

<highlightSyntax language="cpp">typedef struct LINESEG {

  int p1,p2;            /* start and end points (index to vertex list) */
  int p3,p4;            /* bezier control points, set to -1 if segment is straight */
  float thickness;      
  int color;
  int flags;            /* used in the editor and for memory management. not described here */    

} LINESEG;

</highlightSyntax>

type definition of PATH struct

<highlightSyntax language="cpp">typedef struct PATH {

  int p1,p2;            /* start and end verts */
  int n_seg;            /* number of segments in line */
  int segs[];           /* list of indices to shape->lines */ 

} PATH;

</highlightSyntax>


type definition of AREA struct

<highlightSyntax language="cpp">typedef struct AREA {

  int n_paths;           /* number of segments in line */
  int paths[];           /* list of indices to shape->paths, with direction bit */ 


  FILLTYPE_ENUM filltype;   /* enum FILLTYPE_NONE, FILLTYPE_SOLID, FILLTYPE_LINEARGRADIENT,
                               FILLTYPE_RADIALGRADIENT, FILLTYPE_TEXTURED */ 
  GRADIENT * gradient;   /* specifies gradient table when FILLTYPE_LINEARGRADIENT or FILLTYPE_RADIALGRADIENT
                            are used */
  AL_BITMAP * bmp;       /* specifies bitmap to use as texture when FILLTYPE_TEXTURED is used*/
  // int gl_tex;         /* only used in A4 as above*/   
  float fill_ox,fill_oy;  /* origin of fill co-ords */     
  float fill_ux,fill_uy;  /* u axis, relative to ox,oy */   
  float fill_vx,fill_vy;  /* v axis */  

} AREA;

</highlightSyntax>

filltype

Rendering

There are two main methods. Your choice depends on what the output is good at, triangles and lines; or hlines.

Primitive rendering

This is the normal method when using OpenGL The AREAs in a SHAPE are first decomposed into triangles and drawn, then the LINEs are drawn on at the right thickness, after being decomposed into straight line segments.

Notes:

  • complex AREAs only need to be decomposed once, so AREA structs could advantagously store the decomposed mesh for fast redraw. The mesh would be in the same co-ords as the SHAPE, and so would be valid after moving/rotating/resizing the SHAPE. Matt Smith 20:24, May 21, 2009 (MDT)
  • extra vertices would be generated where curves are decomposed. Would these need to be indexable in the SHAPE array? If all the PATHs are decomposed in the first pass, it would save doing it twice (once for each AREA on either side) and would ensure that the AREAs butt perfectly when divided by a zero-width line. Maybe even the overdrawn lines could use the same decomposed PATHs Matt Smith 20:24, May 21, 2009 (MDT)

Scanline rendering

This is the normal method when drawing in software to a bitmap in memory. It is more complicated, but performs better and gives almost free anti-aliasing on the left and right edges of everything. The algorithm depends on building for each scanline an ordered-from-left-to-right list of transitions from one area (or line, or the background). The final pass of rendering the SHAPE can then draw all the scanlines using optimal hline() style functions.