[canvas] make shapeIndex implicit in calls to mg_push_vertex
This commit is contained in:
parent
4e816a838b
commit
09a18419e4
258
src/graphics.c
258
src/graphics.c
|
@ -496,10 +496,13 @@ int* mg_reserve_indices(mg_canvas_data* canvas, u32 indexCount)
|
||||||
return(base);
|
return(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_push_vertex(mg_canvas_data* canvas, vec2 pos, vec4 cubic, u64 shapeIndex)
|
void mg_push_vertex(mg_canvas_data* canvas, vec2 pos, vec4 cubic)
|
||||||
{
|
{
|
||||||
mg_vertex_layout* layout = &canvas->backend->vertexLayout;
|
mg_vertex_layout* layout = &canvas->backend->vertexLayout;
|
||||||
DEBUG_ASSERT(canvas->vertexCount < layout->maxVertexCount);
|
DEBUG_ASSERT(canvas->vertexCount < layout->maxVertexCount);
|
||||||
|
DEBUG_ASSERT(canvas->nextShapeIndex > 0);
|
||||||
|
|
||||||
|
int shapeIndex = maximum(0, canvas->nextShapeIndex-1);
|
||||||
|
|
||||||
u32 index = canvas->vertexCount;
|
u32 index = canvas->vertexCount;
|
||||||
|
|
||||||
|
@ -513,11 +516,11 @@ void mg_push_vertex(mg_canvas_data* canvas, vec2 pos, vec4 cubic, u64 shapeIndex
|
||||||
// Path Filling
|
// Path Filling
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------------
|
||||||
//NOTE(martin): forward declarations
|
//NOTE(martin): forward declarations
|
||||||
void mg_render_fill_cubic(mg_canvas_data* canvas, vec2 p[4], u32 shapeIndex, mg_color color);
|
void mg_render_fill_cubic(mg_canvas_data* canvas, vec2 p[4], mg_color color);
|
||||||
|
|
||||||
//NOTE(martin): quadratics filling
|
//NOTE(martin): quadratics filling
|
||||||
|
|
||||||
void mg_render_fill_quadratic(mg_canvas_data* canvas, vec2 p[3], u32 shapeIndex, mg_color color)
|
void mg_render_fill_quadratic(mg_canvas_data* canvas, vec2 p[3], mg_color color)
|
||||||
{
|
{
|
||||||
u32 baseIndex = mg_vertices_base_index(canvas);
|
u32 baseIndex = mg_vertices_base_index(canvas);
|
||||||
|
|
||||||
|
@ -525,18 +528,15 @@ void mg_render_fill_quadratic(mg_canvas_data* canvas, vec2 p[3], u32 shapeIndex,
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p[0].x, p[0].y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p[0].x, p[0].y}),
|
||||||
(vec4){0, 0, 0, 1},
|
(vec4){0, 0, 0, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p[1].x, p[1].y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p[1].x, p[1].y}),
|
||||||
(vec4){0.5, 0, 0.5, 1},
|
(vec4){0.5, 0, 0.5, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p[2].x, p[2].y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p[2].x, p[2].y}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
indices[0] = baseIndex + 0;
|
indices[0] = baseIndex + 0;
|
||||||
indices[1] = baseIndex + 1;
|
indices[1] = baseIndex + 1;
|
||||||
|
@ -545,7 +545,7 @@ void mg_render_fill_quadratic(mg_canvas_data* canvas, vec2 p[3], u32 shapeIndex,
|
||||||
|
|
||||||
//NOTE(martin): cubic filling
|
//NOTE(martin): cubic filling
|
||||||
|
|
||||||
void mg_split_and_fill_cubic(mg_canvas_data* canvas, vec2 p[4], f32 tSplit, u32 shapeIndex, mg_color color)
|
void mg_split_and_fill_cubic(mg_canvas_data* canvas, vec2 p[4], f32 tSplit, mg_color color)
|
||||||
{
|
{
|
||||||
int subVertexCount = 0;
|
int subVertexCount = 0;
|
||||||
int subIndexCount = 0;
|
int subIndexCount = 0;
|
||||||
|
@ -579,30 +579,27 @@ void mg_split_and_fill_cubic(mg_canvas_data* canvas, vec2 p[4], f32 tSplit, u32
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p[0].x, p[0].y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p[0].x, p[0].y}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){split.x, split.y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){split.x, split.y}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p[3].x, p[3].y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p[3].x, p[3].y}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
indices[0] = baseIndex + 0;
|
indices[0] = baseIndex + 0;
|
||||||
indices[1] = baseIndex + 1;
|
indices[1] = baseIndex + 1;
|
||||||
indices[2] = baseIndex + 2;
|
indices[2] = baseIndex + 2;
|
||||||
|
|
||||||
mg_render_fill_cubic(canvas, subPointsLow, shapeIndex, color);
|
mg_render_fill_cubic(canvas, subPointsLow, color);
|
||||||
mg_render_fill_cubic(canvas, subPointsHigh, shapeIndex, color);
|
mg_render_fill_cubic(canvas, subPointsHigh, color);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_render_fill_cubic(mg_canvas_data* canvas, vec2 p[4], u32 shapeIndex, mg_color color)
|
void mg_render_fill_cubic(mg_canvas_data* canvas, vec2 p[4], mg_color color)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("graphics render fill cubic\n");
|
LOG_DEBUG("graphics render fill cubic\n");
|
||||||
|
|
||||||
|
@ -674,7 +671,7 @@ void mg_render_fill_cubic(mg_canvas_data* canvas, vec2 p[4], u32 shapeIndex, mg_
|
||||||
{1.5*p[1].x - 0.5*p[0].x, 1.5*p[1].y - 0.5*p[0].y},
|
{1.5*p[1].x - 0.5*p[0].x, 1.5*p[1].y - 0.5*p[0].y},
|
||||||
p[3]};
|
p[3]};
|
||||||
|
|
||||||
mg_render_fill_quadratic(canvas, quadControlPoints, shapeIndex, color);
|
mg_render_fill_quadratic(canvas, quadControlPoints, color);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if( (discrFactor2 > 0 && d1 != 0)
|
else if( (discrFactor2 > 0 && d1 != 0)
|
||||||
|
@ -743,13 +740,13 @@ void mg_render_fill_cubic(mg_canvas_data* canvas, vec2 p[4], u32 shapeIndex, mg_
|
||||||
if(sd != 0 && td/sd < 0.99 && td/sd > 0.01)
|
if(sd != 0 && td/sd < 0.99 && td/sd > 0.01)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("split curve at first double point\n");
|
LOG_DEBUG("split curve at first double point\n");
|
||||||
mg_split_and_fill_cubic(canvas, p, td/sd, shapeIndex, color);
|
mg_split_and_fill_cubic(canvas, p, td/sd, color);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(se != 0 && te/se < 0.99 && te/se > 0.01)
|
if(se != 0 && te/se < 0.99 && te/se > 0.01)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("split curve at second double point\n");
|
LOG_DEBUG("split curve at second double point\n");
|
||||||
mg_split_and_fill_cubic(canvas, p, te/se, shapeIndex, color);
|
mg_split_and_fill_cubic(canvas, p, te/se, color);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -959,7 +956,7 @@ void mg_render_fill_cubic(mg_canvas_data* canvas, vec2 p[4], u32 shapeIndex, mg_
|
||||||
vec2 pos = mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[i]]);
|
vec2 pos = mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[i]]);
|
||||||
vec4 cubic = testCoords[orderedHullIndices[i]];
|
vec4 cubic = testCoords[orderedHullIndices[i]];
|
||||||
cubic.w = outsideTest;
|
cubic.w = outsideTest;
|
||||||
mg_push_vertex(canvas, pos, cubic, shapeIndex);
|
mg_push_vertex(canvas, pos, cubic);
|
||||||
|
|
||||||
indices[i] = baseIndex + i;
|
indices[i] = baseIndex + i;
|
||||||
}
|
}
|
||||||
|
@ -988,33 +985,27 @@ void mg_render_fill_cubic(mg_canvas_data* canvas, vec2 p[4], u32 shapeIndex, mg_
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[0]]),
|
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[0]]),
|
||||||
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[0]]), outsideTest1},
|
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[0]]), outsideTest1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[1]]),
|
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[1]]),
|
||||||
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[1]]), outsideTest1},
|
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[1]]), outsideTest1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[2]]),
|
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[2]]),
|
||||||
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[2]]), outsideTest1},
|
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[2]]), outsideTest1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[0]]),
|
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[0]]),
|
||||||
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[0]]), outsideTest2},
|
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[0]]), outsideTest2});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[2]]),
|
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[2]]),
|
||||||
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[2]]), outsideTest2},
|
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[2]]), outsideTest2});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[3]]),
|
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[3]]),
|
||||||
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[3]]), outsideTest2},
|
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[3]]), outsideTest2});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
indices[0] = baseIndex + 0;
|
indices[0] = baseIndex + 0;
|
||||||
indices[1] = baseIndex + 1;
|
indices[1] = baseIndex + 1;
|
||||||
|
@ -1039,8 +1030,7 @@ void mg_render_fill_cubic(mg_canvas_data* canvas, vec2 p[4], u32 shapeIndex, mg_
|
||||||
{
|
{
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[i]]),
|
mg_mat2x3_mul(canvas->transform, p[orderedHullIndices[i]]),
|
||||||
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[i]]), outsideTest},
|
(vec4){vec4_expand_xyz(testCoords[orderedHullIndices[i]]), outsideTest});
|
||||||
shapeIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
indices[0] = baseIndex + 0;
|
indices[0] = baseIndex + 0;
|
||||||
|
@ -1054,7 +1044,7 @@ void mg_render_fill_cubic(mg_canvas_data* canvas, vec2 p[4], u32 shapeIndex, mg_
|
||||||
|
|
||||||
//NOTE(martin): global path fill
|
//NOTE(martin): global path fill
|
||||||
|
|
||||||
void mg_render_fill(mg_canvas_data* canvas, mg_path_elt* elements, mg_path_descriptor* path, u32 shapeIndex, mg_color color)
|
void mg_render_fill(mg_canvas_data* canvas, mg_path_elt* elements, mg_path_descriptor* path, mg_color color)
|
||||||
{
|
{
|
||||||
u32 eltCount = path->count;
|
u32 eltCount = path->count;
|
||||||
vec2 startPoint = path->startPoint;
|
vec2 startPoint = path->startPoint;
|
||||||
|
@ -1084,14 +1074,14 @@ void mg_render_fill(mg_canvas_data* canvas, mg_path_elt* elements, mg_path_descr
|
||||||
|
|
||||||
case MG_PATH_QUADRATIC:
|
case MG_PATH_QUADRATIC:
|
||||||
{
|
{
|
||||||
mg_render_fill_quadratic(canvas, controlPoints, shapeIndex, color);
|
mg_render_fill_quadratic(canvas, controlPoints, color);
|
||||||
endPoint = controlPoints[2];
|
endPoint = controlPoints[2];
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case MG_PATH_CUBIC:
|
case MG_PATH_CUBIC:
|
||||||
{
|
{
|
||||||
mg_render_fill_cubic(canvas, controlPoints, shapeIndex, color);
|
mg_render_fill_cubic(canvas, controlPoints, color);
|
||||||
endPoint = controlPoints[3];
|
endPoint = controlPoints[3];
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
@ -1109,7 +1099,7 @@ void mg_render_fill(mg_canvas_data* canvas, mg_path_elt* elements, mg_path_descr
|
||||||
|
|
||||||
for(int i=0; i<3; i++)
|
for(int i=0; i<3; i++)
|
||||||
{
|
{
|
||||||
mg_push_vertex(canvas, pos[i], cubic, shapeIndex);
|
mg_push_vertex(canvas, pos[i], cubic);
|
||||||
indices[i] = baseIndex + i;
|
indices[i] = baseIndex + i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1121,7 +1111,7 @@ void mg_render_fill(mg_canvas_data* canvas, mg_path_elt* elements, mg_path_descr
|
||||||
// Path Stroking
|
// Path Stroking
|
||||||
//-----------------------------------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
void mg_render_stroke_line(mg_canvas_data* canvas, vec2 p[2], u32 shapeIndex, mg_attributes* attributes)
|
void mg_render_stroke_line(mg_canvas_data* canvas, vec2 p[2], mg_attributes* attributes)
|
||||||
{
|
{
|
||||||
//NOTE(martin): get normals multiplied by halfWidth
|
//NOTE(martin): get normals multiplied by halfWidth
|
||||||
f32 halfW = attributes->width/2;
|
f32 halfW = attributes->width/2;
|
||||||
|
@ -1140,23 +1130,19 @@ void mg_render_stroke_line(mg_canvas_data* canvas, vec2 p[2], u32 shapeIndex, mg
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p[0].x + n0.x, p[0].y + n0.y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p[0].x + n0.x, p[0].y + n0.y}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p[1].x + n0.x, p[1].y + n0.y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p[1].x + n0.x, p[1].y + n0.y}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p[1].x - n0.x, p[1].y - n0.y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p[1].x - n0.x, p[1].y - n0.y}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p[0].x - n0.x, p[0].y - n0.y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p[0].x - n0.x, p[0].y - n0.y}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
indices[0] = baseIndex;
|
indices[0] = baseIndex;
|
||||||
indices[1] = baseIndex + 1;
|
indices[1] = baseIndex + 1;
|
||||||
|
@ -1282,7 +1268,7 @@ void mg_quadratic_split(vec2 p[3], f32 t, vec2 outLeft[3], vec2 outRight[3])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mg_render_stroke_quadratic(mg_canvas_data* canvas, vec2 p[4], u32 shapeIndex, mg_attributes* attributes)
|
void mg_render_stroke_quadratic(mg_canvas_data* canvas, vec2 p[4], mg_attributes* attributes)
|
||||||
{
|
{
|
||||||
#define CHECK_SAMPLE_COUNT 5
|
#define CHECK_SAMPLE_COUNT 5
|
||||||
f32 checkSamples[CHECK_SAMPLE_COUNT] = {1./6, 2./6, 3./6, 4./6, 5./6};
|
f32 checkSamples[CHECK_SAMPLE_COUNT] = {1./6, 2./6, 3./6, 4./6, 5./6};
|
||||||
|
@ -1336,17 +1322,17 @@ void mg_render_stroke_quadratic(mg_canvas_data* canvas, vec2 p[4], u32 shapeInde
|
||||||
vec2 splitLeft[3];
|
vec2 splitLeft[3];
|
||||||
vec2 splitRight[3];
|
vec2 splitRight[3];
|
||||||
mg_quadratic_split(p, maxOvershootParameter, splitLeft, splitRight);
|
mg_quadratic_split(p, maxOvershootParameter, splitLeft, splitRight);
|
||||||
mg_render_stroke_quadratic(canvas, splitLeft, shapeIndex, attributes);
|
mg_render_stroke_quadratic(canvas, splitLeft, attributes);
|
||||||
mg_render_stroke_quadratic(canvas, splitRight, shapeIndex, attributes);
|
mg_render_stroke_quadratic(canvas, splitRight, attributes);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//NOTE(martin): push the actual fill commands for the offset contour
|
//NOTE(martin): push the actual fill commands for the offset contour
|
||||||
|
|
||||||
u32 shapeIndex = mg_next_shape(canvas, attributes->color);
|
mg_next_shape(canvas, attributes->color);
|
||||||
|
|
||||||
mg_render_fill_quadratic(canvas, positiveOffsetHull, shapeIndex, attributes->color);
|
mg_render_fill_quadratic(canvas, positiveOffsetHull, attributes->color);
|
||||||
mg_render_fill_quadratic(canvas, negativeOffsetHull, shapeIndex, attributes->color);
|
mg_render_fill_quadratic(canvas, negativeOffsetHull, attributes->color);
|
||||||
|
|
||||||
//NOTE(martin): add base triangles
|
//NOTE(martin): add base triangles
|
||||||
u32 baseIndex = mg_vertices_base_index(canvas);
|
u32 baseIndex = mg_vertices_base_index(canvas);
|
||||||
|
@ -1354,23 +1340,19 @@ void mg_render_stroke_quadratic(mg_canvas_data* canvas, vec2 p[4], u32 shapeInde
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, positiveOffsetHull[0]),
|
mg_mat2x3_mul(canvas->transform, positiveOffsetHull[0]),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, positiveOffsetHull[2]),
|
mg_mat2x3_mul(canvas->transform, positiveOffsetHull[2]),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, negativeOffsetHull[2]),
|
mg_mat2x3_mul(canvas->transform, negativeOffsetHull[2]),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, negativeOffsetHull[0]),
|
mg_mat2x3_mul(canvas->transform, negativeOffsetHull[0]),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
indices[0] = baseIndex + 0;
|
indices[0] = baseIndex + 0;
|
||||||
indices[1] = baseIndex + 1;
|
indices[1] = baseIndex + 1;
|
||||||
|
@ -1436,7 +1418,7 @@ void mg_cubic_split(vec2 p[4], f32 t, vec2 outLeft[4], vec2 outRight[4])
|
||||||
outRight[3] = p[3];
|
outRight[3] = p[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_render_stroke_cubic(mg_canvas_data* canvas, vec2 p[4], u32 shapeIndex, mg_attributes* attributes)
|
void mg_render_stroke_cubic(mg_canvas_data* canvas, vec2 p[4], mg_attributes* attributes)
|
||||||
{
|
{
|
||||||
#define CHECK_SAMPLE_COUNT 5
|
#define CHECK_SAMPLE_COUNT 5
|
||||||
f32 checkSamples[CHECK_SAMPLE_COUNT] = {1./6, 2./6, 3./6, 4./6, 5./6};
|
f32 checkSamples[CHECK_SAMPLE_COUNT] = {1./6, 2./6, 3./6, 4./6, 5./6};
|
||||||
|
@ -1490,18 +1472,18 @@ void mg_render_stroke_cubic(mg_canvas_data* canvas, vec2 p[4], u32 shapeIndex, m
|
||||||
vec2 splitLeft[4];
|
vec2 splitLeft[4];
|
||||||
vec2 splitRight[4];
|
vec2 splitRight[4];
|
||||||
mg_cubic_split(p, maxOvershootParameter, splitLeft, splitRight);
|
mg_cubic_split(p, maxOvershootParameter, splitLeft, splitRight);
|
||||||
mg_render_stroke_cubic(canvas, splitLeft, shapeIndex, attributes);
|
mg_render_stroke_cubic(canvas, splitLeft, attributes);
|
||||||
mg_render_stroke_cubic(canvas, splitRight, shapeIndex, attributes);
|
mg_render_stroke_cubic(canvas, splitRight, attributes);
|
||||||
|
|
||||||
//TODO: render joint between the split curves
|
//TODO: render joint between the split curves
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//NOTE(martin): push the actual fill commands for the offset contour
|
//NOTE(martin): push the actual fill commands for the offset contour
|
||||||
u32 shapeIndex = mg_next_shape(canvas, attributes->color);
|
mg_next_shape(canvas, attributes->color);
|
||||||
|
|
||||||
mg_render_fill_cubic(canvas, positiveOffsetHull, shapeIndex, attributes->color);
|
mg_render_fill_cubic(canvas, positiveOffsetHull, attributes->color);
|
||||||
mg_render_fill_cubic(canvas, negativeOffsetHull, shapeIndex, attributes->color);
|
mg_render_fill_cubic(canvas, negativeOffsetHull, attributes->color);
|
||||||
|
|
||||||
//NOTE(martin): add base triangles
|
//NOTE(martin): add base triangles
|
||||||
u32 baseIndex = mg_vertices_base_index(canvas);
|
u32 baseIndex = mg_vertices_base_index(canvas);
|
||||||
|
@ -1510,23 +1492,19 @@ void mg_render_stroke_cubic(mg_canvas_data* canvas, vec2 p[4], u32 shapeIndex, m
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, positiveOffsetHull[0]),
|
mg_mat2x3_mul(canvas->transform, positiveOffsetHull[0]),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, positiveOffsetHull[3]),
|
mg_mat2x3_mul(canvas->transform, positiveOffsetHull[3]),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, negativeOffsetHull[3]),
|
mg_mat2x3_mul(canvas->transform, negativeOffsetHull[3]),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, negativeOffsetHull[0]),
|
mg_mat2x3_mul(canvas->transform, negativeOffsetHull[0]),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
indices[0] = baseIndex + 0;
|
indices[0] = baseIndex + 0;
|
||||||
indices[1] = baseIndex + 1;
|
indices[1] = baseIndex + 1;
|
||||||
|
@ -1551,30 +1529,26 @@ void mg_stroke_cap(mg_canvas_data* canvas, vec2 p0, vec2 direction, mg_attribute
|
||||||
vec2 m0 = {alpha*direction.x,
|
vec2 m0 = {alpha*direction.x,
|
||||||
alpha*direction.y};
|
alpha*direction.y};
|
||||||
|
|
||||||
u32 shapeIndex = mg_next_shape(canvas, attributes->color);
|
mg_next_shape(canvas, attributes->color);
|
||||||
|
|
||||||
u32 baseIndex = mg_vertices_base_index(canvas);
|
u32 baseIndex = mg_vertices_base_index(canvas);
|
||||||
i32* indices = mg_reserve_indices(canvas, 6);
|
i32* indices = mg_reserve_indices(canvas, 6);
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p0.x + n0.x, p0.y + n0.y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p0.x + n0.x, p0.y + n0.y}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p0.x + n0.x + m0.x, p0.y + n0.y + m0.y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p0.x + n0.x + m0.x, p0.y + n0.y + m0.y}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p0.x - n0.x + m0.x, p0.y - n0.y + m0.y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p0.x - n0.x + m0.x, p0.y - n0.y + m0.y}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p0.x - n0.x, p0.y - n0.y}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p0.x - n0.x, p0.y - n0.y}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
indices[0] = baseIndex;
|
indices[0] = baseIndex;
|
||||||
indices[1] = baseIndex + 1;
|
indices[1] = baseIndex + 1;
|
||||||
|
@ -1613,7 +1587,7 @@ void mg_stroke_joint(mg_canvas_data* canvas,
|
||||||
n1.y *= -1;
|
n1.y *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 shapeIndex = mg_next_shape(canvas, attributes->color);
|
mg_next_shape(canvas, attributes->color);
|
||||||
|
|
||||||
//NOTE(martin): use the same code as hull offset to find mitter point...
|
//NOTE(martin): use the same code as hull offset to find mitter point...
|
||||||
/*NOTE(martin): let vector u = (n0+n1) and vector v = pIntersect - p1
|
/*NOTE(martin): let vector u = (n0+n1) and vector v = pIntersect - p1
|
||||||
|
@ -1638,23 +1612,19 @@ void mg_stroke_joint(mg_canvas_data* canvas,
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, p0),
|
mg_mat2x3_mul(canvas->transform, p0),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p0.x + n0.x*halfW, p0.y + n0.y*halfW}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p0.x + n0.x*halfW, p0.y + n0.y*halfW}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, mitterPoint),
|
mg_mat2x3_mul(canvas->transform, mitterPoint),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p0.x + n1.x*halfW, p0.y + n1.y*halfW}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p0.x + n1.x*halfW, p0.y + n1.y*halfW}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
indices[0] = baseIndex;
|
indices[0] = baseIndex;
|
||||||
indices[1] = baseIndex + 1;
|
indices[1] = baseIndex + 1;
|
||||||
|
@ -1671,18 +1641,15 @@ void mg_stroke_joint(mg_canvas_data* canvas,
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, p0),
|
mg_mat2x3_mul(canvas->transform, p0),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p0.x + n0.x*halfW, p0.y + n0.y*halfW}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p0.x + n0.x*halfW, p0.y + n0.y*halfW}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
mg_push_vertex(canvas,
|
mg_push_vertex(canvas,
|
||||||
mg_mat2x3_mul(canvas->transform, (vec2){p0.x + n1.x*halfW, p0.y + n1.y*halfW}),
|
mg_mat2x3_mul(canvas->transform, (vec2){p0.x + n1.x*halfW, p0.y + n1.y*halfW}),
|
||||||
(vec4){1, 1, 1, 1},
|
(vec4){1, 1, 1, 1});
|
||||||
shapeIndex);
|
|
||||||
|
|
||||||
DEBUG_ASSERT(!isnan(n0.x) && !isnan(n0.y) && !isnan(n1.x) && !isnan(n1.y));
|
DEBUG_ASSERT(!isnan(n0.x) && !isnan(n0.y) && !isnan(n1.x) && !isnan(n1.y));
|
||||||
|
|
||||||
|
@ -1702,22 +1669,22 @@ void mg_render_stroke_element(mg_canvas_data* canvas,
|
||||||
{
|
{
|
||||||
vec2 controlPoints[4] = {currentPoint, element->p[0], element->p[1], element->p[2]};
|
vec2 controlPoints[4] = {currentPoint, element->p[0], element->p[1], element->p[2]};
|
||||||
int endPointIndex = 0;
|
int endPointIndex = 0;
|
||||||
u32 shapeIndex = mg_next_shape(canvas, attributes->color);
|
mg_next_shape(canvas, attributes->color);
|
||||||
|
|
||||||
switch(element->type)
|
switch(element->type)
|
||||||
{
|
{
|
||||||
case MG_PATH_LINE:
|
case MG_PATH_LINE:
|
||||||
mg_render_stroke_line(canvas, controlPoints, shapeIndex, attributes);
|
mg_render_stroke_line(canvas, controlPoints, attributes);
|
||||||
endPointIndex = 1;
|
endPointIndex = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MG_PATH_QUADRATIC:
|
case MG_PATH_QUADRATIC:
|
||||||
mg_render_stroke_quadratic(canvas, controlPoints, shapeIndex, attributes);
|
mg_render_stroke_quadratic(canvas, controlPoints, attributes);
|
||||||
endPointIndex = 2;
|
endPointIndex = 2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MG_PATH_CUBIC:
|
case MG_PATH_CUBIC:
|
||||||
mg_render_stroke_cubic(canvas, controlPoints, shapeIndex, attributes);
|
mg_render_stroke_cubic(canvas, controlPoints, attributes);
|
||||||
endPointIndex = 3;
|
endPointIndex = 3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1835,7 +1802,7 @@ void mg_render_rectangle_fill(mg_canvas_data* canvas, mp_rect rect, mg_attribute
|
||||||
u32 baseIndex = mg_vertices_base_index(canvas);
|
u32 baseIndex = mg_vertices_base_index(canvas);
|
||||||
i32* indices = mg_reserve_indices(canvas, 6);
|
i32* indices = mg_reserve_indices(canvas, 6);
|
||||||
|
|
||||||
u32 shapeIndex = mg_next_shape(canvas, attributes->color);
|
mg_next_shape(canvas, attributes->color);
|
||||||
|
|
||||||
vec2 points[4] = {{rect.x, rect.y},
|
vec2 points[4] = {{rect.x, rect.y},
|
||||||
{rect.x + rect.w, rect.y},
|
{rect.x + rect.w, rect.y},
|
||||||
|
@ -1846,7 +1813,7 @@ void mg_render_rectangle_fill(mg_canvas_data* canvas, mp_rect rect, mg_attribute
|
||||||
for(int i=0; i<4; i++)
|
for(int i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
vec2 pos = mg_mat2x3_mul(canvas->transform, points[i]);
|
vec2 pos = mg_mat2x3_mul(canvas->transform, points[i]);
|
||||||
mg_push_vertex(canvas, pos, cubic, shapeIndex);
|
mg_push_vertex(canvas, pos, cubic);
|
||||||
}
|
}
|
||||||
indices[0] = baseIndex + 0;
|
indices[0] = baseIndex + 0;
|
||||||
indices[1] = baseIndex + 1;
|
indices[1] = baseIndex + 1;
|
||||||
|
@ -1862,7 +1829,7 @@ void mg_render_rectangle_stroke(mg_canvas_data* canvas, mp_rect rect, mg_attribu
|
||||||
u32 baseIndex = mg_vertices_base_index(canvas);
|
u32 baseIndex = mg_vertices_base_index(canvas);
|
||||||
i32* indices = mg_reserve_indices(canvas, 12);
|
i32* indices = mg_reserve_indices(canvas, 12);
|
||||||
|
|
||||||
u32 shapeIndex = mg_next_shape(canvas, attributes->color);
|
mg_next_shape(canvas, attributes->color);
|
||||||
|
|
||||||
//NOTE(martin): limit stroke width to the minimum dimension of the rectangle
|
//NOTE(martin): limit stroke width to the minimum dimension of the rectangle
|
||||||
f32 width = minimum(attributes->width, minimum(rect.w, rect.h));
|
f32 width = minimum(attributes->width, minimum(rect.w, rect.h));
|
||||||
|
@ -1882,13 +1849,13 @@ void mg_render_rectangle_stroke(mg_canvas_data* canvas, mp_rect rect, mg_attribu
|
||||||
for(int i=0; i<4; i++)
|
for(int i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
vec2 pos = mg_mat2x3_mul(canvas->transform, outerPoints[i]);
|
vec2 pos = mg_mat2x3_mul(canvas->transform, outerPoints[i]);
|
||||||
mg_push_vertex(canvas, pos, cubic, shapeIndex);
|
mg_push_vertex(canvas, pos, cubic);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<4; i++)
|
for(int i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
vec2 pos = mg_mat2x3_mul(canvas->transform, innerPoints[i]);
|
vec2 pos = mg_mat2x3_mul(canvas->transform, innerPoints[i]);
|
||||||
mg_push_vertex(canvas, pos, cubic, shapeIndex);
|
mg_push_vertex(canvas, pos, cubic);
|
||||||
}
|
}
|
||||||
|
|
||||||
indices[0] = baseIndex + 0;
|
indices[0] = baseIndex + 0;
|
||||||
|
@ -1905,7 +1872,7 @@ void mg_render_rectangle_stroke(mg_canvas_data* canvas, mp_rect rect, mg_attribu
|
||||||
indices[11] = baseIndex + 7;
|
indices[11] = baseIndex + 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_render_fill_arc_corner(mg_canvas_data* canvas, f32 x, f32 y, f32 rx, f32 ry, u32 shapeIndex, mg_color color)
|
void mg_render_fill_arc_corner(mg_canvas_data* canvas, f32 x, f32 y, f32 rx, f32 ry, mg_color color)
|
||||||
{
|
{
|
||||||
//NOTE(martin): draw a precomputed arc corner, using a bezier approximation
|
//NOTE(martin): draw a precomputed arc corner, using a bezier approximation
|
||||||
u32 baseIndex = mg_vertices_base_index(canvas);
|
u32 baseIndex = mg_vertices_base_index(canvas);
|
||||||
|
@ -1927,7 +1894,7 @@ void mg_render_fill_arc_corner(mg_canvas_data* canvas, f32 x, f32 y, f32 rx, f32
|
||||||
for(int i=0; i<4; i++)
|
for(int i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
vec2 pos = mg_mat2x3_mul(canvas->transform, points[i]);
|
vec2 pos = mg_mat2x3_mul(canvas->transform, points[i]);
|
||||||
mg_push_vertex(canvas, pos, cubics[i], shapeIndex);
|
mg_push_vertex(canvas, pos, cubics[i]);
|
||||||
}
|
}
|
||||||
indices[0] = baseIndex + 0;
|
indices[0] = baseIndex + 0;
|
||||||
indices[1] = baseIndex + 1;
|
indices[1] = baseIndex + 1;
|
||||||
|
@ -1939,8 +1906,7 @@ void mg_render_fill_arc_corner(mg_canvas_data* canvas, f32 x, f32 y, f32 rx, f32
|
||||||
|
|
||||||
void mg_render_rounded_rectangle_fill_with_z_index(mg_canvas_data* canvas,
|
void mg_render_rounded_rectangle_fill_with_z_index(mg_canvas_data* canvas,
|
||||||
mg_rounded_rect rect,
|
mg_rounded_rect rect,
|
||||||
mg_attributes* attributes,
|
mg_attributes* attributes)
|
||||||
u32 shapeIndex)
|
|
||||||
{
|
{
|
||||||
//NOTE(martin): draw a rounded rectangle by drawing a normal rectangle and 4 corners,
|
//NOTE(martin): draw a rounded rectangle by drawing a normal rectangle and 4 corners,
|
||||||
// approximating an arc by a precomputed bezier curve
|
// approximating an arc by a precomputed bezier curve
|
||||||
|
@ -1963,7 +1929,7 @@ void mg_render_rounded_rectangle_fill_with_z_index(mg_canvas_data* canvas,
|
||||||
for(int i=0; i<8; i++)
|
for(int i=0; i<8; i++)
|
||||||
{
|
{
|
||||||
vec2 pos = mg_mat2x3_mul(canvas->transform, points[i]);
|
vec2 pos = mg_mat2x3_mul(canvas->transform, points[i]);
|
||||||
mg_push_vertex(canvas, pos, cubic, shapeIndex);
|
mg_push_vertex(canvas, pos, cubic);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const i32 fanIndices[18] = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 7 }; // inner fan
|
static const i32 fanIndices[18] = { 0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0, 6, 7 }; // inner fan
|
||||||
|
@ -1972,24 +1938,24 @@ void mg_render_rounded_rectangle_fill_with_z_index(mg_canvas_data* canvas,
|
||||||
indices[i] = fanIndices[i] + baseIndex;
|
indices[i] = fanIndices[i] + baseIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
mg_render_fill_arc_corner(canvas, rect.x, rect.y, rect.r, rect.r, shapeIndex, attributes->color);
|
mg_render_fill_arc_corner(canvas, rect.x, rect.y, rect.r, rect.r, attributes->color);
|
||||||
mg_render_fill_arc_corner(canvas, rect.x + rect.w, rect.y, -rect.r, rect.r, shapeIndex, attributes->color);
|
mg_render_fill_arc_corner(canvas, rect.x + rect.w, rect.y, -rect.r, rect.r, attributes->color);
|
||||||
mg_render_fill_arc_corner(canvas, rect.x + rect.w, rect.y + rect.h, -rect.r, -rect.r, shapeIndex, attributes->color);
|
mg_render_fill_arc_corner(canvas, rect.x + rect.w, rect.y + rect.h, -rect.r, -rect.r, attributes->color);
|
||||||
mg_render_fill_arc_corner(canvas, rect.x, rect.y + rect.h, rect.r, -rect.r, shapeIndex, attributes->color);
|
mg_render_fill_arc_corner(canvas, rect.x, rect.y + rect.h, rect.r, -rect.r, attributes->color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mg_render_rounded_rectangle_fill(mg_canvas_data* canvas,
|
void mg_render_rounded_rectangle_fill(mg_canvas_data* canvas,
|
||||||
mg_rounded_rect rect,
|
mg_rounded_rect rect,
|
||||||
mg_attributes* attributes)
|
mg_attributes* attributes)
|
||||||
{
|
{
|
||||||
u32 shapeIndex = mg_next_shape(canvas, attributes->color);
|
mg_next_shape(canvas, attributes->color);
|
||||||
mg_render_rounded_rectangle_fill_with_z_index(canvas, rect, attributes, shapeIndex);
|
mg_render_rounded_rectangle_fill_with_z_index(canvas, rect, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_render_rounded_rectangle_stroke(mg_canvas_data* canvas,
|
void mg_render_rounded_rectangle_stroke(mg_canvas_data* canvas,
|
||||||
mg_rounded_rect rect,
|
mg_rounded_rect rect,
|
||||||
mg_attributes* attributes)
|
mg_attributes* attributes)
|
||||||
{
|
{
|
||||||
//NOTE(martin): stroke rounded rectangle by filling two scaled rounded rectangles with the same shapeIndex
|
//NOTE(martin): stroke rounded rectangle by filling two scaled rounded rectangles with the same shapeIndex
|
||||||
f32 width = minimum(attributes->width, minimum(rect.w, rect.h));
|
f32 width = minimum(attributes->width, minimum(rect.w, rect.h));
|
||||||
|
@ -1998,15 +1964,12 @@ void mg_render_rounded_rectangle_stroke(mg_canvas_data* canvas,
|
||||||
mg_rounded_rect inner = {rect.x + halfW, rect.y + halfW, rect.w - width, rect.h - width, rect.r - halfW};
|
mg_rounded_rect inner = {rect.x + halfW, rect.y + halfW, rect.w - width, rect.h - width, rect.r - halfW};
|
||||||
mg_rounded_rect outer = {rect.x - halfW, rect.y - halfW, rect.w + width, rect.h + width, rect.r + halfW};
|
mg_rounded_rect outer = {rect.x - halfW, rect.y - halfW, rect.w + width, rect.h + width, rect.r + halfW};
|
||||||
|
|
||||||
u32 shapeIndex = mg_next_shape(canvas, attributes->color);
|
mg_next_shape(canvas, attributes->color);
|
||||||
mg_render_rounded_rectangle_fill_with_z_index(canvas, outer, attributes, shapeIndex);
|
mg_render_rounded_rectangle_fill_with_z_index(canvas, outer, attributes);
|
||||||
mg_render_rounded_rectangle_fill_with_z_index(canvas, inner, attributes, shapeIndex);
|
mg_render_rounded_rectangle_fill_with_z_index(canvas, inner, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_render_ellipse_fill_with_z_index(mg_canvas_data* canvas,
|
void mg_render_ellipse_fill_with_z_index(mg_canvas_data* canvas, mp_rect rect, mg_attributes* attributes)
|
||||||
mp_rect rect,
|
|
||||||
mg_attributes* attributes,
|
|
||||||
u32 shapeIndex)
|
|
||||||
{
|
{
|
||||||
//NOTE(martin): draw a filled ellipse by drawing a diamond and 4 corners,
|
//NOTE(martin): draw a filled ellipse by drawing a diamond and 4 corners,
|
||||||
// approximating an arc by a precomputed bezier curve
|
// approximating an arc by a precomputed bezier curve
|
||||||
|
@ -2027,7 +1990,7 @@ void mg_render_ellipse_fill_with_z_index(mg_canvas_data* canvas,
|
||||||
for(int i=0; i<4; i++)
|
for(int i=0; i<4; i++)
|
||||||
{
|
{
|
||||||
vec2 pos = mg_mat2x3_mul(canvas->transform, points[i]);
|
vec2 pos = mg_mat2x3_mul(canvas->transform, points[i]);
|
||||||
mg_push_vertex(canvas, pos, cubic, shapeIndex);
|
mg_push_vertex(canvas, pos, cubic);
|
||||||
}
|
}
|
||||||
|
|
||||||
indices[0] = baseIndex + 0;
|
indices[0] = baseIndex + 0;
|
||||||
|
@ -2037,16 +2000,16 @@ void mg_render_ellipse_fill_with_z_index(mg_canvas_data* canvas,
|
||||||
indices[4] = baseIndex + 2;
|
indices[4] = baseIndex + 2;
|
||||||
indices[5] = baseIndex + 3;
|
indices[5] = baseIndex + 3;
|
||||||
|
|
||||||
mg_render_fill_arc_corner(canvas, rect.x, rect.y, rx, ry, shapeIndex, attributes->color);
|
mg_render_fill_arc_corner(canvas, rect.x, rect.y, rx, ry, attributes->color);
|
||||||
mg_render_fill_arc_corner(canvas, rect.x + rect.w, rect.y, -rx, ry, shapeIndex, attributes->color);
|
mg_render_fill_arc_corner(canvas, rect.x + rect.w, rect.y, -rx, ry, attributes->color);
|
||||||
mg_render_fill_arc_corner(canvas, rect.x + rect.w, rect.y + rect.h, -rx, -ry, shapeIndex, attributes->color);
|
mg_render_fill_arc_corner(canvas, rect.x + rect.w, rect.y + rect.h, -rx, -ry, attributes->color);
|
||||||
mg_render_fill_arc_corner(canvas, rect.x, rect.y + rect.h, rx, -ry, shapeIndex, attributes->color);
|
mg_render_fill_arc_corner(canvas, rect.x, rect.y + rect.h, rx, -ry, attributes->color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_render_ellipse_fill(mg_canvas_data* canvas, mp_rect rect, mg_attributes* attributes)
|
void mg_render_ellipse_fill(mg_canvas_data* canvas, mp_rect rect, mg_attributes* attributes)
|
||||||
{
|
{
|
||||||
u32 shapeIndex = mg_next_shape(canvas, attributes->color);
|
mg_next_shape(canvas, attributes->color);
|
||||||
mg_render_ellipse_fill_with_z_index(canvas, rect, attributes, shapeIndex);
|
mg_render_ellipse_fill_with_z_index(canvas, rect, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_render_ellipse_stroke(mg_canvas_data* canvas, mp_rect rect, mg_attributes* attributes)
|
void mg_render_ellipse_stroke(mg_canvas_data* canvas, mp_rect rect, mg_attributes* attributes)
|
||||||
|
@ -2058,9 +2021,9 @@ void mg_render_ellipse_stroke(mg_canvas_data* canvas, mp_rect rect, mg_attribute
|
||||||
mp_rect inner = {rect.x + halfW, rect.y + halfW, rect.w - width, rect.h - width};
|
mp_rect inner = {rect.x + halfW, rect.y + halfW, rect.w - width, rect.h - width};
|
||||||
mp_rect outer = {rect.x - halfW, rect.y - halfW, rect.w + width, rect.h + width};
|
mp_rect outer = {rect.x - halfW, rect.y - halfW, rect.w + width, rect.h + width};
|
||||||
|
|
||||||
u32 shapeIndex = mg_next_shape(canvas, attributes->color);
|
mg_next_shape(canvas, attributes->color);
|
||||||
mg_render_ellipse_fill_with_z_index(canvas, outer, attributes, shapeIndex);
|
mg_render_ellipse_fill_with_z_index(canvas, outer, attributes);
|
||||||
mg_render_ellipse_fill_with_z_index(canvas, inner, attributes, shapeIndex);
|
mg_render_ellipse_fill_with_z_index(canvas, inner, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_render_image(mg_canvas_data* canvas, mg_image image, mp_rect rect)
|
void mg_render_image(mg_canvas_data* canvas, mg_image image, mp_rect rect)
|
||||||
|
@ -2076,7 +2039,7 @@ void mg_render_image(mg_canvas_data* canvas, mg_image image, mp_rect rect)
|
||||||
u32 baseIndex = mg_vertices_base_index(canvas);
|
u32 baseIndex = mg_vertices_base_index(canvas);
|
||||||
i32* indices = mg_reserve_indices(canvas, 6);
|
i32* indices = mg_reserve_indices(canvas, 6);
|
||||||
|
|
||||||
u32 shapeIndex = mg_next_shape(canvas, attributes->color);
|
mg_next_shape(canvas, attributes->color);
|
||||||
|
|
||||||
vec2 points[4] = {{rect.x, rect.y},
|
vec2 points[4] = {{rect.x, rect.y},
|
||||||
{rect.x + rect.w, rect.y},
|
{rect.x + rect.w, rect.y},
|
||||||
|
@ -2096,7 +2059,7 @@ void mg_render_image(mg_canvas_data* canvas, mg_image image, mp_rect rect)
|
||||||
vec2 transformedUV = {uv[i].x / MG_ATLAS_SIZE, uv[i].y / MG_ATLAS_SIZE};
|
vec2 transformedUV = {uv[i].x / MG_ATLAS_SIZE, uv[i].y / MG_ATLAS_SIZE};
|
||||||
|
|
||||||
vec2 pos = mg_mat2x3_mul(canvas->transform, points[i]);
|
vec2 pos = mg_mat2x3_mul(canvas->transform, points[i]);
|
||||||
mg_push_textured_vertex(canvas, pos, cubic, transformedUV, color, shapeIndex);
|
mg_push_textured_vertex(canvas, pos, cubic, transformedUV, color);
|
||||||
}
|
}
|
||||||
indices[0] = baseIndex + 0;
|
indices[0] = baseIndex + 0;
|
||||||
indices[1] = baseIndex + 1;
|
indices[1] = baseIndex + 1;
|
||||||
|
@ -2660,7 +2623,7 @@ mg_canvas mg_canvas_create(mg_surface surface)
|
||||||
canvasData->primitiveCount = 0;
|
canvasData->primitiveCount = 0;
|
||||||
canvasData->path.startIndex = 0;
|
canvasData->path.startIndex = 0;
|
||||||
canvasData->path.count = 0;
|
canvasData->path.count = 0;
|
||||||
canvasData->nextShapeIndex = 1;
|
canvasData->nextShapeIndex = 0;
|
||||||
canvasData->attributes.color = (mg_color){0, 0, 0, 1};
|
canvasData->attributes.color = (mg_color){0, 0, 0, 1};
|
||||||
canvasData->attributes.tolerance = 1;
|
canvasData->attributes.tolerance = 1;
|
||||||
canvasData->attributes.width = 10;
|
canvasData->attributes.width = 10;
|
||||||
|
@ -2881,11 +2844,10 @@ void mg_flush_commands(int primitiveCount, mg_primitive* primitives, mg_path_elt
|
||||||
|
|
||||||
case MG_CMD_FILL:
|
case MG_CMD_FILL:
|
||||||
{
|
{
|
||||||
u32 shapeIndex = mg_next_shape(canvas, primitive->attributes.color);
|
mg_next_shape(canvas, primitive->attributes.color);
|
||||||
mg_render_fill(canvas,
|
mg_render_fill(canvas,
|
||||||
pathElements + primitive->path.startIndex,
|
pathElements + primitive->path.startIndex,
|
||||||
&primitive->path,
|
&primitive->path,
|
||||||
shapeIndex,
|
|
||||||
primitive->attributes.color);
|
primitive->attributes.color);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
2
todo.txt
2
todo.txt
|
@ -17,7 +17,7 @@ Overview
|
||||||
Clean+Fixes
|
Clean+Fixes
|
||||||
-----------
|
-----------
|
||||||
[ ] Clean canvas code
|
[ ] Clean canvas code
|
||||||
[ ] make zIndex implicit when calling push_vertex
|
[x] make zIndex implicit when calling push_vertex
|
||||||
[x] rename zIndex with "shapeIndex" everywhere
|
[x] rename zIndex with "shapeIndex" everywhere
|
||||||
[ ] remove color args in functions that don't need it anymore
|
[ ] remove color args in functions that don't need it anymore
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue