From: Jean-Philippe Bruyère Date: Wed, 5 Jan 2022 17:24:47 +0000 (+0100) Subject: pattern transform, opacity, debug getarcsteps (abs) X-Git-Tag: v0.3.0-beta~49 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=720d8e33af0b0862df7c8163533228917e837f8b;p=jp%2Fvkvg.git pattern transform, opacity, debug getarcsteps (abs) --- diff --git a/include/vkvg.h b/include/vkvg.h index c2744b8..0d60d34 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -325,7 +325,7 @@ vkvg_debug_stats_t vkvg_device_reset_stats (VkvgDevice dev); * This is the reference documentation for handling matrices to use as transformation in drawing operations. * Matrix computations in vkvg are taken from the cairo library. * @{ */ -#define VKVG_IDENTITY_MATRIX {1,0,0,1,0,0}/*!< The identity matrix*/ +#define VKVG_IDENTITY_MATRIX (vkvg_matrix_t){1,0,0,1,0,0}/*!< The identity matrix*/ /** * @brief vkvg matrix structure * @@ -1148,6 +1148,10 @@ void vkvg_clip (VkvgContext ctx); */ vkvg_public void vkvg_clip_preserve (VkvgContext ctx); +vkvg_public +void vkvg_set_opacity (VkvgContext ctx, float opacity); +vkvg_public +float vkvg_get_opacity (VkvgContext ctx); /** * @brief Set current source for drawing to the solid color defined by the supplied 32bit integer. * @param ctx a valid vkvg @ref context @@ -1695,6 +1699,11 @@ vkvg_filter_t vkvg_pattern_get_filter (VkvgPattern pat); */ vkvg_public vkvg_pattern_type_t vkvg_pattern_get_type (VkvgPattern pat); +vkvg_public +void vkvg_pattern_set_matrix (VkvgPattern pat, const vkvg_matrix_t* matrix); +vkvg_public +void vkvg_pattern_get_matrix (VkvgPattern pat, vkvg_matrix_t* matrix); + /** @}*/ /********* EXPERIMENTAL **************/ diff --git a/shaders/vkvg_main.frag b/shaders/vkvg_main.frag index f4aee07..0d60365 100644 --- a/shaders/vkvg_main.frag +++ b/shaders/vkvg_main.frag @@ -37,7 +37,8 @@ layout (std430, set=2, binding = 0) uniform _uboGrad { layout (location = 0) in vec3 inFontUV; //if it is a text drawing, inFontUV.z hold fontMap layer layout (location = 1) in vec4 inSrc; //source bounds or color depending on pattern type layout (location = 2) in flat int inPatType; //pattern type -layout (location = 3) in mat3x2 inMat; +layout (location = 3) in flat float inOpacity; +layout (location = 4) in mat3x2 inMat; layout (location = 0) out vec4 outFragColor; @@ -131,6 +132,7 @@ void main() if (inFontUV.z >= 0.0) c *= texture(fontMap, inFontUV).r; + c.a *= inOpacity; outFragColor = c; } diff --git a/shaders/vkvg_main.vert b/shaders/vkvg_main.vert index fd9a684..af28a9f 100644 --- a/shaders/vkvg_main.vert +++ b/shaders/vkvg_main.vert @@ -31,22 +31,24 @@ layout (location = 2) in vec3 inUV; layout (location = 0) out vec3 outUV; layout (location = 1) out vec4 outSrc; layout (location = 2) out flat int outPatType; -layout (location = 3) out mat3x2 outMat; - +layout (location = 3) out flat float outOpacity; +layout (location = 4) out mat3x2 outMat; /*out gl_PerVertex { vec4 gl_Position; };*/ layout(push_constant) uniform PushConsts { - vec4 source; - vec2 size; - int srcType; - int fullScreenQuad; - mat3x2 mat; - mat3x2 matInv; + vec4 source; + vec2 size; + int fullScreenQuad_srcType; + float opacity; + mat3x2 mat; + mat3x2 matInv; } pc; +#define FULLSCREEN_BIT 0x10000000 +#define SRCTYPE_MASK 0x000000FF #define SOLID 0 #define SURFACE 1 #define LINEAR 2 @@ -56,11 +58,12 @@ layout(push_constant) uniform PushConsts { void main() { - outPatType = pc.srcType; + outPatType = pc.fullScreenQuad_srcType & SRCTYPE_MASK; outMat = pc.matInv; - outSrc = pc.srcType == SOLID ? inColor : pc.source; + outSrc = outPatType == SOLID ? inColor : pc.source; + outOpacity = pc.opacity; - if (pc.fullScreenQuad != 0) { + if ((pc.fullScreenQuad_srcType & FULLSCREEN_BIT)==FULLSCREEN_BIT) { gl_Position = vec4(inPos, 0.0f, 1.0f); outUV = vec3(0,0,-1); return; diff --git a/src/vkvg_context.c b/src/vkvg_context.c index b16d2a4..72c7916 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -66,10 +66,10 @@ VkvgContext vkvg_create(VkvgSurface surf) ctx->bounds = (VkRect2D) {{0,0},{ctx->pSurf->width,ctx->pSurf->height}}; ctx->pushConsts = (push_constants) { - {.height=1}, + {.a = 1}, {(float)ctx->pSurf->width,(float)ctx->pSurf->height}, VKVG_PATTERN_TYPE_SOLID, - 0, + 1.0f, VKVG_IDENTITY_MATRIX, VKVG_IDENTITY_MATRIX }; @@ -286,6 +286,20 @@ void vkvg_destroy (VkvgContext ctx) free(ctx); } +void vkvg_set_opacity (VkvgContext ctx, float opacity) { + if (ctx->status) + return; + + if (EQUF(ctx->pushConsts.opacity, opacity)) + return; + + _emit_draw_cmd_undrawn_vertices (ctx); + ctx->pushConsts.opacity = opacity; + ctx->pushCstDirty = true; +} +float vkvg_get_opacity (VkvgContext ctx) { + return ctx->pushConsts.opacity; +} vkvg_status_t vkvg_status (VkvgContext ctx) { return ctx->status; } @@ -506,8 +520,8 @@ void vkvg_curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, flo //compute dyn distanceTolerance depending on current transform float dx = 1, dy = 1; - vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &dx, &dy); - float distanceTolerance = 0.02f / fmaxf(dx,dy); + vkvg_matrix_transform_point (&ctx->pushConsts.mat, &dx, &dy); + float distanceTolerance = fabs(0.02f / fmaxf(dx,dy)); _recursive_bezier (ctx, distanceTolerance, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0); /*cp.x = x3; @@ -862,9 +876,9 @@ void vkvg_set_source_rgba (VkvgContext ctx, float r, float g, float b, float a) void vkvg_set_source_surface(VkvgContext ctx, VkvgSurface surf, float x, float y){ if (ctx->status) return; - _update_cur_pattern (ctx, vkvg_pattern_create_for_surface(surf)); ctx->pushConsts.source.x = x; ctx->pushConsts.source.y = y; + _update_cur_pattern (ctx, vkvg_pattern_create_for_surface(surf)); ctx->pushCstDirty = true; } void vkvg_set_source (VkvgContext ctx, VkvgPattern pat){ diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index 8b2e6ef..5d0d649 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -160,6 +160,7 @@ void _finish_path (VkvgContext ctx){ ctx->pathes[ctx->pathPtr] = 0; ctx->segmentPtr = 0; + ctx->subpathCount++; } //clear path datas in context void _clear_path (VkvgContext ctx){ @@ -167,6 +168,7 @@ void _clear_path (VkvgContext ctx){ ctx->pathes [ctx->pathPtr] = 0; ctx->pointCount = 0; ctx->segmentPtr = 0; + ctx->subpathCount = 0; } void _remove_last_point (VkvgContext ctx){ ctx->pathes[ctx->pathPtr]--; @@ -208,7 +210,7 @@ float _normalizeAngle(float a) float _get_arc_step (VkvgContext ctx, float radius) { float dx = radius, dy = radius; vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &dx, &dy); - float r = fmaxf(dx,dy); + float r = fabsf(fmaxf(dx,dy)); if (r < 3.0f) return asinf (1.0f / r) * 0.25f; return asinf (1.0f / r) * 1.5f * sqrtf(r); @@ -639,8 +641,12 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { _update_descriptor_set (ctx, ctx->source, ctx->dsSrc); - vec4 srcRect = {{0},{0},{(float)surf->width},{(float)surf->height}}; - ctx->pushConsts.source = srcRect; + if (pat->hasMatrix) { + + } + + ctx->pushConsts.source.width = (float)surf->width; + ctx->pushConsts.source.height = (float)surf->height; break; } case VKVG_PATTERN_TYPE_LINEAR: @@ -663,15 +669,30 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { ctx->status = VKVG_STATUS_PATTERN_INVALID_GRADIENT; return; } + vkvg_matrix_t mat; + if (pat->hasMatrix) { + vkvg_pattern_get_matrix (pat, &mat); + if (vkvg_matrix_invert (&mat) != VKVG_STATUS_SUCCESS) + mat = VKVG_IDENTITY_MATRIX; + } + if (pat->hasMatrix) + vkvg_matrix_transform_point (&mat, &grad.cp[0].x, &grad.cp[0].y); + vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y); if (pat->type == VKVG_PATTERN_TYPE_LINEAR) { - vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y); + if (pat->hasMatrix) + vkvg_matrix_transform_point (&mat, &grad.cp[0].z, &grad.cp[0].w); vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].z, &grad.cp[0].w); } else { - //centers - vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[0].x, &grad.cp[0].y); + if (pat->hasMatrix) + vkvg_matrix_transform_point (&mat, &grad.cp[1].x, &grad.cp[1].y); vkvg_matrix_transform_point (&ctx->pushConsts.mat, &grad.cp[1].x, &grad.cp[1].y); + //radii + if (pat->hasMatrix) { + vkvg_matrix_transform_distance (&mat, &grad.cp[0].z, &grad.cp[0].w); + vkvg_matrix_transform_distance (&mat, &grad.cp[1].z, &grad.cp[0].w); + } vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &grad.cp[0].z, &grad.cp[0].w); vkvg_matrix_transform_distance (&ctx->pushConsts.mat, &grad.cp[1].z, &grad.cp[0].w); } @@ -680,7 +701,7 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) { vkvg_buffer_flush(&ctx->uboGrad); break; } - ctx->pushConsts.patternType = newPatternType; + ctx->pushConsts.fsq_patternType = (ctx->pushConsts.fsq_patternType & FULLSCREEN_BIT) + newPatternType; ctx->pushCstDirty = true; if (lastPat) vkvg_pattern_destroy (lastPat); @@ -1433,7 +1454,7 @@ void _vkvg_path_extents (VkvgContext ctx, bool transformed, float *x1, float *y1 while (ptrPath < ctx->pathPtr){ uint32_t pathPointCount = ctx->pathes[ptrPath] & PATH_ELT_MASK; - for (uint32_t i = firstPtIdx; i < firstPtIdx + pathPointCount - 1; i++){ + for (uint32_t i = firstPtIdx; i < firstPtIdx + pathPointCount; i++){ vec2 p = ctx->points[i]; if (transformed) vkvg_matrix_transform_point (&ctx->pushConsts.mat, &p.x, &p.y); @@ -1462,8 +1483,7 @@ void _vkvg_path_extents (VkvgContext ctx, bool transformed, float *x1, float *y1 *y1 = yMin; *y2 = yMax; } -static const uint32_t one = 1; -static const uint32_t zero = 0; + void _draw_full_screen_quad (VkvgContext ctx, bool useScissor) { #if defined(DEBUG) && defined (VKVG_DBG_UTILS) vkh_cmd_label_start(ctx->cmd, "_draw_full_screen_quad", DBG_LAB_COLOR_FSQ); @@ -1486,11 +1506,13 @@ void _draw_full_screen_quad (VkvgContext ctx, bool useScissor) { _add_vertexf (ctx, -1, 3); ctx->curVertOffset = ctx->vertCount; + ctx->pushConsts.fsq_patternType |= FULLSCREEN_BIT; CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout, - VK_SHADER_STAGE_VERTEX_BIT, 28, 4,&one); + VK_SHADER_STAGE_VERTEX_BIT, 24, 4,&ctx->pushConsts.fsq_patternType); CmdDraw (ctx->cmd,3,1,firstVertIdx,0); + ctx->pushConsts.fsq_patternType &= ~FULLSCREEN_BIT; CmdPushConstants(ctx->cmd, ctx->pSurf->dev->pipelineLayout, - VK_SHADER_STAGE_VERTEX_BIT, 28, 4,&zero); + VK_SHADER_STAGE_VERTEX_BIT, 24, 4,&ctx->pushConsts.fsq_patternType); if (us) CmdSetScissor(ctx->cmd, 0, 1, &ctx->bounds); diff --git a/src/vkvg_context_internal.h b/src/vkvg_context_internal.h index 69ae574..69cb9ec 100644 --- a/src/vkvg_context_internal.h +++ b/src/vkvg_context_internal.h @@ -49,7 +49,8 @@ #define VKVG_VK_INDEX_TYPE VK_INDEX_TYPE_UINT32 #endif - +#define FULLSCREEN_BIT 0x10000000 +#define SRCTYPE_MASK 0x000000FF #define CreateRgba(r, g, b, a) ((a << 24) | (r << 16) | (g << 8) | b) #ifdef VKVG_PREMULT_ALPHA @@ -67,8 +68,8 @@ typedef struct{ typedef struct { vec4 source; vec2 size; - uint32_t patternType; - uint32_t fullScreenQuad; + uint32_t fsq_patternType; + float opacity; vkvg_matrix_t mat; vkvg_matrix_t matInv; }push_constants; @@ -155,6 +156,7 @@ typedef struct _vkvg_context_t { uint32_t sizePathes; uint32_t segmentPtr; //current segment count in current path having curves + uint32_t subpathCount; //store count of subpath, not straight forward to retrieve from segmented path array float lineWidth; uint32_t dashCount; //value count in dash array, 0 if dash not set. diff --git a/src/vkvg_pattern.c b/src/vkvg_pattern.c index 06ae0b7..5536d1e 100644 --- a/src/vkvg_pattern.c +++ b/src/vkvg_pattern.c @@ -177,6 +177,16 @@ vkvg_status_t vkvg_pattern_get_color_stop_rgba (VkvgPattern pat, uint32_t index, *a = c.a; return VKVG_STATUS_SUCCESS; } +void vkvg_pattern_set_matrix (VkvgPattern pat, const vkvg_matrix_t* matrix) { + pat->matrix = *matrix; + pat->hasMatrix = true; +} +void vkvg_pattern_get_matrix (VkvgPattern pat, vkvg_matrix_t* matrix) { + if (pat->hasMatrix) + *matrix = pat->matrix; + else + *matrix = VKVG_IDENTITY_MATRIX; +} void vkvg_pattern_destroy(VkvgPattern pat) { diff --git a/src/vkvg_pattern.h b/src/vkvg_pattern.h index e437030..bc5fb76 100644 --- a/src/vkvg_pattern.h +++ b/src/vkvg_pattern.h @@ -30,6 +30,8 @@ typedef struct _vkvg_pattern_t { vkvg_pattern_type_t type; vkvg_extend_t extend; vkvg_filter_t filter; + vkvg_matrix_t matrix; + bool hasMatrix; void* data; uint32_t references; }vkvg_pattern_t; diff --git a/src/vkvg_surface.c b/src/vkvg_surface.c index 04325bc..c059136 100644 --- a/src/vkvg_surface.c +++ b/src/vkvg_surface.c @@ -157,7 +157,7 @@ VkvgSurface vkvg_surface_create_from_bitmap (VkvgDevice dev, unsigned char* img, vec4 srcRect = {.x=0,.y=0,.width=(float)surf->width,.height=(float)surf->height}; ctx->pushConsts.source = srcRect; - ctx->pushConsts.patternType = VKVG_PATTERN_TYPE_SURFACE; + ctx->pushConsts.fsq_patternType = (ctx->pushConsts.fsq_patternType & FULLSCREEN_BIT) + VKVG_PATTERN_TYPE_SURFACE; //_update_push_constants (ctx); _update_descriptor_set (ctx, tmpImg, ctx->dsSrc);