feat(experimental): add rectangle shape support

This commit is contained in:
Beriff
2026-03-10 02:02:22 +07:00
parent 2bdcbfae1f
commit 61f9f1eed0
7 changed files with 112 additions and 18 deletions

View File

@@ -49,6 +49,24 @@ void vektor_polygon_free(VektorPolygon* pg) {
free(pg);
}
VektorRectangle* vektor_rectangle_new(void) {
VektorRectangle* rct = malloc(sizeof(VektorRectangle));
rct->start = (V2){.x = 0, .y = 0};
rct->end = (V2){.x = 0, .y = 0};
return rct;
}
void vektor_rectangle_set_end(VektorRectangle* rct, V2 point) {
rct->end = point;
}
void vektor_rectangle_set_start(VektorRectangle* rct, V2 point) {
rct->start = point;
}
void vektor_rectangle_free(VektorRectangle* rct) {
free(rct);
}
void vektor_shapebuffer_add_shape(VektorShapeBuffer* buffer,
VektorShape shape) {
if (buffer->count >= buffer->capacity) {
@@ -59,7 +77,7 @@ void vektor_shapebuffer_add_shape(VektorShapeBuffer* buffer,
buffer->shapes[buffer->count++] = shape;
}
VektorBBox polyline_mk_bbox(VektorPrimitive prim) {
VektorBBox vektor_polyline_get_bbox(VektorPrimitive prim) {
float min_x, max_x, min_y, max_y;
for (size_t i = 0; i < prim.polyline->count; i++) {
V2 p = prim.polyline->points[i];
@@ -72,7 +90,7 @@ VektorBBox polyline_mk_bbox(VektorPrimitive prim) {
return (VektorBBox){(V2){min_x, min_y}, (V2){max_x, max_y}};
}
VektorBBox polygon_mk_bbox(VektorPrimitive prim) {
VektorBBox vektor_polygon_get_bbox(VektorPrimitive prim) {
float min_x, max_x, min_y, max_y;
for (size_t i = 0; i < prim.polygon->count; i++) {
V2 p = prim.polygon->points[i];
@@ -85,14 +103,22 @@ VektorBBox polygon_mk_bbox(VektorPrimitive prim) {
return (VektorBBox){(V2){min_x, min_y}, (V2){max_x, max_y}};
}
VektorBBox vektor_mk_bbox(VektorPrimitive prim) {
VektorBBox vektor_rectangle_get_bbox(VektorPrimitive prim) {
return *(VektorBBox*)&prim.rectangle;
}
VektorBBox vektor_primitive_get_bbox(VektorPrimitive prim) {
switch (prim.kind) {
case VEKTOR_POLYLINE:
return polyline_mk_bbox(prim);
return vektor_polyline_get_bbox(prim);
break;
case VEKTOR_POLYGON:
return polygon_mk_bbox(prim);
return vektor_polygon_get_bbox(prim);
break;
case VEKTOR_RECTANGLE:
return vektor_rectangle_get_bbox(prim);
break;
default:
@@ -103,11 +129,11 @@ VektorBBox vektor_mk_bbox(VektorPrimitive prim) {
VektorShape vektor_shape_new(VektorPrimitive prim, VektorStyle style,
int z_index) {
return (VektorShape){.primitive = prim, .style = style, .z_index = z_index, .bbox=vektor_mk_bbox(prim)};
return (VektorShape){.primitive = prim, .style = style, .z_index = z_index, .bbox=vektor_primitive_get_bbox(prim)};
}
void vektor_shapes_update_bbox(VektorShapeBuffer* buffer) {
for (size_t i = 0; i < buffer->count; i++) {
buffer->shapes[i].bbox = vektor_mk_bbox(buffer->shapes[i].primitive);
buffer->shapes[i].bbox = vektor_primitive_get_bbox(buffer->shapes[i].primitive);
}
}

View File

@@ -23,10 +23,16 @@ typedef struct {
double radius;
} VektorCircle;
typedef struct {
V2 start;
V2 end;
} VektorRectangle;
typedef enum {
VEKTOR_POLYLINE,
VEKTOR_POLYGON,
VEKTOR_CIRCLE
VEKTOR_CIRCLE,
VEKTOR_RECTANGLE
} VektorPrimitiveKind;
typedef struct {
@@ -35,6 +41,7 @@ typedef struct {
VektorPolyline* polyline;
VektorPolygon* polygon;
VektorCircle circle;
VektorRectangle rectangle;
};
} VektorPrimitive;
@@ -46,6 +53,11 @@ VektorPolygon* vektor_polygon_new(void);
void vektor_polygon_add_point(VektorPolygon* pl, V2 point);
void vektor_polygon_free(VektorPolygon* pl);
VektorRectangle* vektor_rectangle_new(void);
void vektor_rectangle_set_end(VektorRectangle* rct, V2 point);
void vektor_rectangle_set_start(VektorRectangle* rct, V2 point);
void vektor_rectangle_free(VektorRectangle* rct);
typedef struct {
VektorColor stroke_color;
float stroke_width;
@@ -63,10 +75,11 @@ typedef struct {
VektorPrimitive primitive;
} VektorShape;
VektorBBox polyline_mk_bbox(VektorPrimitive prim);
VektorBBox polygon_mk_bbox(VektorPrimitive prim);
VektorBBox vektor_polyline_get_bbox(VektorPrimitive prim);
VektorBBox vektor_polygon_get_bbox(VektorPrimitive prim);
VektorBBox vektor_rectangle_get_bbox(VektorPrimitive prim);
VektorBBox vektor_mk_bbox(VektorPrimitive prim);
VektorBBox vektor_primitive_get_bbox(VektorPrimitive prim);
VektorShape vektor_shape_new(VektorPrimitive prim, VektorStyle style,
int z_index);

View File

@@ -12,7 +12,7 @@ void vektor_edgebuffer_add_edge(EdgeBuffer* buffer, Edge edge) {
buffer->edges[buffer->count++] = edge;
}
void vektor_polyline_flatten(EdgeBuffer* buffer, VektorPolyline* line,
void vektor_polyline_tessellate(EdgeBuffer* buffer, VektorPolyline* line,
size_t j) {
for (size_t i = 0; i + 1 < line->count; i++) {
vektor_edgebuffer_add_edge(
@@ -20,7 +20,7 @@ void vektor_polyline_flatten(EdgeBuffer* buffer, VektorPolyline* line,
}
}
void vektor_polygon_flatten(EdgeBuffer* buffer, VektorPolygon* polygon,
void vektor_polygon_tessellate(EdgeBuffer* buffer, VektorPolygon* polygon,
size_t j) {
for (size_t i = 0; i + 1 < polygon->count; i++) {
vektor_edgebuffer_add_edge(
@@ -30,6 +30,20 @@ void vektor_polygon_flatten(EdgeBuffer* buffer, VektorPolygon* polygon,
buffer, (Edge){polygon->points[polygon->count - 1], polygon->points[0], 0, j});
}
void vektor_rectangle_tessellate(EdgeBuffer* buffer, VektorRectangle* rct, size_t j) {
if (vec2_equals(rct->end, rct->start)) {return;}
Edge top = (Edge){rct->start, (V2){rct->end.x, rct->start.y}, 0, j };
Edge right = (Edge){(V2){rct->end.x, rct->start.y}, rct->end, 0, j};
Edge bottom = (Edge){(V2){rct->start.x, rct->end.y}, rct->end, 0, j};
Edge left = (Edge){rct->start, (V2){rct->start.x, rct->end.y}, 0, j };
vektor_edgebuffer_add_edge(buffer, top);
vektor_edgebuffer_add_edge(buffer, right);
vektor_edgebuffer_add_edge(buffer, bottom);
vektor_edgebuffer_add_edge(buffer, left);
}
void vektor_rasterize(VertexBuffer* vb, VektorShapeBuffer* shapes) {
EdgeBuffer edges = {0};
for (size_t i = 0; i < shapes->count; i++) {
@@ -37,11 +51,15 @@ void vektor_rasterize(VertexBuffer* vb, VektorShapeBuffer* shapes) {
switch (p->kind) {
case VEKTOR_POLYLINE:
vektor_polyline_flatten(&edges, p->polyline, i);
vektor_polyline_tessellate(&edges, p->polyline, i);
break;
case VEKTOR_POLYGON:
vektor_polygon_flatten(&edges, p->polygon, i);
vektor_polygon_tessellate(&edges, p->polygon, i);
break;
case VEKTOR_RECTANGLE:
vektor_rectangle_tessellate(&edges, &p->rectangle, i);
break;
default:

View File

@@ -23,8 +23,9 @@ typedef struct {
void vektor_edgebuffer_add_edge(EdgeBuffer* edges, Edge edge);
void vektor_polyline_flatten(EdgeBuffer* edges, VektorPolyline* line, size_t i);
void vektor_polygon_flatten(EdgeBuffer* buffer, VektorPolygon* line, size_t i);
void vektor_polyline_tessellate(EdgeBuffer* edges, VektorPolyline* line, size_t i);
void vektor_polygon_tessellate(EdgeBuffer* buffer, VektorPolygon* polygon, size_t i);
void vektor_rectangle_tessellate(EdgeBuffer* buffer, VektorRectangle* rct, size_t i);
typedef struct {
V2 coords;

View File

@@ -22,6 +22,10 @@ static inline V2 vec2_add(const V2 v1, const V2 v2) {
return (V2){v1.x + v2.x, v1.y + v2.y};
}
static inline bool vec2_equals(const V2 v1, const V2 v2) {
return (bool)(v1.x == v2.x && v1.y == v2.x);
}
static inline V2 vec2_sub(const V2 v1, const V2 v2) {
return (V2){v1.x - v2.x, v1.y - v2.y};
}