]> O.S.I.I.S - jp/vkvg.git/commitdiff
pattern transform, opacity, debug getarcsteps (abs)
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 5 Jan 2022 17:24:47 +0000 (18:24 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Wed, 5 Jan 2022 17:24:47 +0000 (18:24 +0100)
include/vkvg.h
shaders/vkvg_main.frag
shaders/vkvg_main.vert
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_context_internal.h
src/vkvg_pattern.c
src/vkvg_pattern.h
src/vkvg_surface.c

index c2744b85fe640ec854c47414ddcf0c10aecc4392..0d60d348cc7105b0c5f05f1553bbbeec3d2a6c7a 100644 (file)
@@ -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 **************/
index f4aee07e506219229b281ea7325bc0dff4a0efdd..0d60365e9cf38adfd388a90d7ff138d23093570b 100644 (file)
@@ -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;
 }
 
index fd9a68452dc22feaa9fe10a3492df3cfc562dc61..af28a9f75ce843d7589026652e471f093948dc9b 100644 (file)
@@ -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;
index b16d2a485ed53182bb2bdadd7f80664392ff1214..72c79169036ad5cbbccae63284ae5e6e92047aac 100644 (file)
@@ -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){
index 8b2e6ef85c20dacc90379ceb5acb601dc7c2f431..5d0d649c27044e862d2e36d19c42331604d6e65b 100644 (file)
@@ -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);
 
index 69ae574ce921b70c664911429828ac55d7f1f0e4..69cb9ec330bbefb5178856f54c1558ba628903a8 100644 (file)
@@ -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.
index 06ae0b75d153367af431f3938c09ceea85b5922e..5536d1ec454ad5568062d06a90e0ff6164138cf7 100644 (file)
@@ -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)
 {
index e43703062f96cd26b2143cb0511c1d77b6f545f6..bc5fb761503092220054dadbeaa26e20ff7e3fa8 100644 (file)
@@ -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;
index 04325bc2b8cd6d0f25ca90adb99c96fcbe0e1170..c0591362bafb2f8fb6e66581b1c0fb03f1b003ab 100644 (file)
@@ -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);