[canvas] Put primitive's transform in the attributes struct. When rendering, set current transform at the beginning of mg_next_shape(). (This avoid using an additional prevTransform matrix to correctly setup uvTransform when mg_finalize_shape() at the beginning of mg_next_shape())
This commit is contained in:
parent
d195fb1f61
commit
30aa6a4a48
|
@ -59,6 +59,7 @@ typedef struct mg_attributes
|
||||||
mg_image image;
|
mg_image image;
|
||||||
mp_rect srcRegion;
|
mp_rect srcRegion;
|
||||||
|
|
||||||
|
mg_mat2x3 transform;
|
||||||
mp_rect clip;
|
mp_rect clip;
|
||||||
|
|
||||||
} mg_attributes;
|
} mg_attributes;
|
||||||
|
@ -90,7 +91,6 @@ typedef struct mg_primitive
|
||||||
{
|
{
|
||||||
mg_primitive_cmd cmd;
|
mg_primitive_cmd cmd;
|
||||||
mg_attributes attributes;
|
mg_attributes attributes;
|
||||||
mg_mat2x3 transform;
|
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
@ -99,7 +99,6 @@ typedef struct mg_primitive
|
||||||
mg_rounded_rect roundedRect;
|
mg_rounded_rect roundedRect;
|
||||||
utf32 codePoint;
|
utf32 codePoint;
|
||||||
u32 jump;
|
u32 jump;
|
||||||
mg_mat2x3 matrix; //TODO remove when we use transform everywhere
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} mg_primitive;
|
} mg_primitive;
|
||||||
|
@ -220,17 +219,17 @@ typedef struct mg_canvas_data
|
||||||
|
|
||||||
mg_resource_pool imagePool;
|
mg_resource_pool imagePool;
|
||||||
|
|
||||||
|
/*
|
||||||
vec2 atlasPos;
|
vec2 atlasPos;
|
||||||
u32 atlasLineHeight;
|
u32 atlasLineHeight;
|
||||||
mg_image blankImage;
|
mg_image blankImage;
|
||||||
|
*/
|
||||||
|
|
||||||
//NOTE: these are used at render time
|
//NOTE: these are used at render time
|
||||||
mp_rect clip;
|
mp_rect clip;
|
||||||
mg_mat2x3 transform;
|
mg_mat2x3 transform;
|
||||||
mg_mat2x3 prevTransform; //TODO: [cleanup] use only one transform
|
mg_image image;
|
||||||
|
mp_rect srcRegion;
|
||||||
mg_image currentImage;
|
|
||||||
mp_rect currentSrcRegion;
|
|
||||||
|
|
||||||
vec4 shapeExtents;
|
vec4 shapeExtents;
|
||||||
u32 nextShapeIndex;
|
u32 nextShapeIndex;
|
||||||
|
@ -732,8 +731,8 @@ void mg_push_command(mg_canvas_data* canvas, mg_primitive primitive)
|
||||||
//NOTE(martin): push primitive and updates current stream, eventually patching a pending jump.
|
//NOTE(martin): push primitive and updates current stream, eventually patching a pending jump.
|
||||||
ASSERT(canvas->primitiveCount < MG_MAX_PRIMITIVE_COUNT);
|
ASSERT(canvas->primitiveCount < MG_MAX_PRIMITIVE_COUNT);
|
||||||
canvas->primitives[canvas->primitiveCount] = primitive;
|
canvas->primitives[canvas->primitiveCount] = primitive;
|
||||||
canvas->primitives[canvas->primitiveCount].transform = mg_matrix_stack_top(canvas);
|
|
||||||
canvas->primitives[canvas->primitiveCount].attributes = canvas->attributes;
|
canvas->primitives[canvas->primitiveCount].attributes = canvas->attributes;
|
||||||
|
canvas->primitives[canvas->primitiveCount].attributes.transform = mg_matrix_stack_top(canvas);
|
||||||
canvas->primitiveCount++;
|
canvas->primitiveCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,9 +769,9 @@ void mg_finalize_shape(mg_canvas_data* canvas)
|
||||||
if(canvas->nextShapeIndex)
|
if(canvas->nextShapeIndex)
|
||||||
{
|
{
|
||||||
//NOTE: set shape's uv transform for the _current_ shape
|
//NOTE: set shape's uv transform for the _current_ shape
|
||||||
vec2 texSize = mg_image_size(canvas->currentImage);
|
vec2 texSize = mg_image_size(canvas->image);
|
||||||
|
|
||||||
mp_rect srcRegion = canvas->currentSrcRegion;
|
mp_rect srcRegion = canvas->srcRegion;
|
||||||
|
|
||||||
mp_rect destRegion = {canvas->shapeExtents.x,
|
mp_rect destRegion = {canvas->shapeExtents.x,
|
||||||
canvas->shapeExtents.y,
|
canvas->shapeExtents.y,
|
||||||
|
@ -786,7 +785,7 @@ void mg_finalize_shape(mg_canvas_data* canvas)
|
||||||
mg_mat2x3 userToDestRegion = {1, 0, -destRegion.x,
|
mg_mat2x3 userToDestRegion = {1, 0, -destRegion.x,
|
||||||
0, 1, -destRegion.y};
|
0, 1, -destRegion.y};
|
||||||
|
|
||||||
mg_mat2x3 screenToUser = mg_mat2x3_inv(canvas->prevTransform);
|
mg_mat2x3 screenToUser = mg_mat2x3_inv(canvas->transform);
|
||||||
|
|
||||||
mg_mat2x3 uvTransform = srcRegionToTexture;
|
mg_mat2x3 uvTransform = srcRegionToTexture;
|
||||||
uvTransform = mg_mat2x3_mul_m(uvTransform, destRegionToSrcRegion);
|
uvTransform = mg_mat2x3_mul_m(uvTransform, destRegionToSrcRegion);
|
||||||
|
@ -798,14 +797,14 @@ void mg_finalize_shape(mg_canvas_data* canvas)
|
||||||
*(mg_mat2x3*)(layout->uvTransformBuffer + index*layout->uvTransformStride) = uvTransform;
|
*(mg_mat2x3*)(layout->uvTransformBuffer + index*layout->uvTransformStride) = uvTransform;
|
||||||
|
|
||||||
}
|
}
|
||||||
canvas->prevTransform = canvas->transform;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 mg_next_shape(mg_canvas_data* canvas, mg_attributes* attributes)
|
u32 mg_next_shape(mg_canvas_data* canvas, mg_attributes* attributes)
|
||||||
{
|
{
|
||||||
mg_finalize_shape(canvas);
|
mg_finalize_shape(canvas);
|
||||||
|
|
||||||
canvas->currentSrcRegion = attributes->srcRegion;
|
canvas->transform = attributes->transform;
|
||||||
|
canvas->srcRegion = attributes->srcRegion;
|
||||||
canvas->shapeExtents = (vec4){FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX};
|
canvas->shapeExtents = (vec4){FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX};
|
||||||
|
|
||||||
mg_vertex_layout* layout = &canvas->backend->vertexLayout;
|
mg_vertex_layout* layout = &canvas->backend->vertexLayout;
|
||||||
|
@ -2748,15 +2747,8 @@ mg_canvas mg_canvas_create(mg_surface surface)
|
||||||
0, 1, 0}};
|
0, 1, 0}};
|
||||||
|
|
||||||
|
|
||||||
//TODO: review this ////////////////////////////////////////////////////////////////////////
|
|
||||||
canvas = mg_canvas_alloc_handle(canvasData);
|
canvas = mg_canvas_alloc_handle(canvasData);
|
||||||
mg_canvas_set_current(canvas);
|
mg_canvas_set_current(canvas);
|
||||||
|
|
||||||
//NOTE: create a blank image
|
|
||||||
//WARN: this requires setting the current context before
|
|
||||||
u8 bytes[4] = {255, 255, 255, 255};
|
|
||||||
canvasData->blankImage = mg_image_create_from_rgba8(1, 1, bytes);
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(canvas);
|
return(canvas);
|
||||||
|
@ -2888,7 +2880,7 @@ void mg_flush_commands(int primitiveCount, mg_primitive* primitives, mg_path_elt
|
||||||
|
|
||||||
canvas->clip = (mp_rect){-FLT_MAX/2, -FLT_MAX/2, FLT_MAX, FLT_MAX};
|
canvas->clip = (mp_rect){-FLT_MAX/2, -FLT_MAX/2, FLT_MAX, FLT_MAX};
|
||||||
|
|
||||||
canvas->currentImage = mg_image_nil();
|
canvas->image = mg_image_nil();
|
||||||
|
|
||||||
canvas->backend->begin(canvas->backend);
|
canvas->backend->begin(canvas->backend);
|
||||||
|
|
||||||
|
@ -2902,13 +2894,12 @@ void mg_flush_commands(int primitiveCount, mg_primitive* primitives, mg_path_elt
|
||||||
mg_primitive* primitive = &(primitives[nextIndex]);
|
mg_primitive* primitive = &(primitives[nextIndex]);
|
||||||
nextIndex++;
|
nextIndex++;
|
||||||
|
|
||||||
if(i && primitive->attributes.image.h != canvas->currentImage.h)
|
if(i && primitive->attributes.image.h != canvas->image.h)
|
||||||
{
|
{
|
||||||
mg_image_data* imageData = mg_image_data_from_handle(canvas, canvas->currentImage);
|
mg_image_data* imageData = mg_image_data_from_handle(canvas, canvas->image);
|
||||||
mg_draw_batch(canvas, imageData);
|
mg_draw_batch(canvas, imageData);
|
||||||
canvas->currentImage = primitive->attributes.image;
|
canvas->image = primitive->attributes.image;
|
||||||
}
|
}
|
||||||
canvas->transform = primitive->transform;
|
|
||||||
|
|
||||||
switch(primitive->cmd)
|
switch(primitive->cmd)
|
||||||
{
|
{
|
||||||
|
@ -2996,7 +2987,7 @@ void mg_flush_commands(int primitiveCount, mg_primitive* primitives, mg_path_elt
|
||||||
}
|
}
|
||||||
exit_command_loop: ;
|
exit_command_loop: ;
|
||||||
|
|
||||||
mg_image_data* imageData = mg_image_data_from_handle(canvas, canvas->currentImage);
|
mg_image_data* imageData = mg_image_data_from_handle(canvas, canvas->image);
|
||||||
mg_draw_batch(canvas, imageData);
|
mg_draw_batch(canvas, imageData);
|
||||||
|
|
||||||
canvas->backend->end(canvas->backend);
|
canvas->backend->end(canvas->backend);
|
||||||
|
|
Loading…
Reference in New Issue