]> O.S.I.I.S - jp/vkvg.git/commitdiff
stroke context and dash context instead of static vars, radial gradient in ctx internal
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 11 Dec 2021 02:53:24 +0000 (03:53 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 11 Dec 2021 02:53:24 +0000 (03:53 +0100)
src/vectors.h
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_device_internal.c
tests/common/test.h

index 0886198fdfd3102b6ee285f609731305dffefe9a..872c2eee218c3cf8ef746d170437e3b34a74eafa 100644 (file)
@@ -174,6 +174,13 @@ vkvg_inline        bool vec2d_isnan (vec2d v){
 vkvg_inline float vec2_dot (vec2 a, vec2 b) {
        return (a.x * b.x) + (a.y * b.y);
 }
+vkvg_inline float vec2_det (vec2 a, vec2 b) {
+       return a.x * b.y - a.y * b.x;
+}
+vkvg_inline float vec2_slope (vec2 a, vec2 b) {
+       return (b.y - a.y) / (b.x - a.x);
+}
+
 
 vkvg_inline    bool vec4_equ (vec4 a, vec4 b){
        return (EQUF(a.x,b.x)&EQUF(a.y,b.y)&EQUF(a.z,b.z)&EQUF(a.w,b.w));
index 674a03134b4ad4f9147bba24b3967b4f03d8be78..91d689b5266d080bc2fb317ddddb4313685a878a 100644 (file)
@@ -745,41 +745,51 @@ void _draw_stoke_cap (VkvgContext ctx, float hw, vec2 p0, vec2 n, bool isStart)
        }
 }
 
-static bool            dashOn                  = true;
-static uint32_t curDash                        = 0;    //current dash index
-static float   curDashOffset   = 0.f;  //cur dash offset between defined path point and last dash segment(on/off) start
-static float   totDashLength   = 0;    //total length of dashes
-static vec2            normal                  = {0};
-
-float _draw_dashed_segment (VkvgContext ctx, float hw, vec2 pL, vec2 p, vec2 pR, bool isCurve) {
-       if (!dashOn)//we test in fact the next dash start, if dashOn = true => next segment is a void.
+typedef struct {
+       bool    dashOn;
+       uint32_t curDash;       //current dash index
+       float   curDashOffset;  //cur dash offset between defined path point and last dash segment(on/off) start
+       float   totDashLength;  //total length of dashes
+       vec2    normal;
+}dash_context_t;
+
+typedef struct {
+       uint32_t iL;
+       uint32_t iR;
+       uint32_t cp;//current point
+}stroke_context_t;
+
+float _draw_dashed_segment (VkvgContext ctx, float hw, dash_context_t* dc, vec2 pL, vec2 p, vec2 pR, bool isCurve) {
+       if (!dc->dashOn)//we test in fact the next dash start, if dashOn = true => next segment is a void.
                _build_vb_step (ctx, hw, pL, p, pR, isCurve);
 
        vec2 d = vec2_sub (pR, p);
-       normal = vec2_norm (d);
+       dc->normal = vec2_norm (d);
        float segmentLength = vec2_length(d);
 
-       while (curDashOffset < segmentLength){
-               vec2 p0 = vec2_add (p, vec2_mult(normal, curDashOffset));
+       while (dc->curDashOffset < segmentLength){
+               vec2 p0 = vec2_add (p, vec2_mult(dc->normal, dc->curDashOffset));
 
-               _draw_stoke_cap (ctx, hw, p0, normal, dashOn);
-               dashOn ^= true;
-               curDashOffset += ctx->dashes[curDash];
-               if (++curDash == ctx->dashCount)
-                       curDash = 0;
+               _draw_stoke_cap (ctx, hw, p0, dc->normal, dc->dashOn);
+               dc->dashOn ^= true;
+               dc->curDashOffset += ctx->dashes[dc->curDash];
+               if (++dc->curDash == ctx->dashCount)
+                       dc->curDash = 0;
        }
-       curDashOffset -= segmentLength;
-       curDashOffset = fmodf(curDashOffset, totDashLength);
+       dc->curDashOffset -= segmentLength;
+       dc->curDashOffset = fmodf(dc->curDashOffset, dc->totDashLength);
        return segmentLength;
 }
-static uint32_t curPathPointIdx, lastPathPointIdx, ptrPath, iL, iR;
-void _draw_segment (VkvgContext ctx, float hw, bool isCurve) {
-       iR = curPathPointIdx+1;
+
+
+
+void _draw_segment (VkvgContext ctx, float hw, stroke_context_t* str, dash_context_t* dc, bool isCurve) {
+       str->iR = str->cp + 1;
        if (ctx->dashCount > 0)
-               _draw_dashed_segment(ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], isCurve);
+               _draw_dashed_segment(ctx, hw, dc, ctx->points[str->iL], ctx->points[str->cp], ctx->points[str->iR], isCurve);
        else
-               _build_vb_step (ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], isCurve);
-       iL = curPathPointIdx++;
+               _build_vb_step (ctx, hw, ctx->points[str->iL], ctx->points[str->cp], ctx->points[str->iR], isCurve);
+       str->iL = str->cp++;
 }
 
 void vkvg_stroke_preserve (VkvgContext ctx)
@@ -794,18 +804,21 @@ void vkvg_stroke_preserve (VkvgContext ctx)
 
        LOG(VKVG_LOG_INFO, "STROKE: ctx = %p; path ptr = %d;\n", ctx, ctx->pathPtr);
 
-       curPathPointIdx = lastPathPointIdx = ptrPath = iL = iR = 0;
+       stroke_context_t str = {0};
+       uint32_t ptrPath = 0;
        float hw = ctx->lineWidth / 2.0f;
 
        while (ptrPath < ctx->pathPtr){
                uint32_t ptrSegment = 0, lastSegmentPointIdx = 0;
-               uint32_t firstPathPointIdx = curPathPointIdx;
+               uint32_t firstPathPointIdx = str.cp;
                uint32_t pathPointCount = ctx->pathes[ptrPath]&PATH_ELT_MASK;
-               lastPathPointIdx = curPathPointIdx + pathPointCount - 1;
+               uint32_t lastPathPointIdx = str.cp + pathPointCount - 1;
+
+               dash_context_t dc = {0};
 
                if (_path_has_curves (ctx,ptrPath)) {
                        ptrSegment = 1;
-                       lastSegmentPointIdx = curPathPointIdx + (ctx->pathes[ptrPath+ptrSegment]&PATH_ELT_MASK)-1;
+                       lastSegmentPointIdx = str.cp + (ctx->pathes[ptrPath+ptrSegment]&PATH_ELT_MASK)-1;
                }
 
                VKVG_IBO_INDEX_TYPE firstIdx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
@@ -815,65 +828,63 @@ void vkvg_stroke_preserve (VkvgContext ctx)
 
                if (ctx->dashCount > 0) {
                        //init dash stroke
-                       dashOn = true;
-                       curDash = 0;    //current dash index
-
-                       //limit offset to total length of dashes
-                       totDashLength = 0;
+                       dc.dashOn = true;
+                       dc.curDash = 0; //current dash index
+                       dc.totDashLength = 0;//limit offset to total length of dashes
                        for (uint32_t i=0;i<ctx->dashCount;i++)
-                               totDashLength += ctx->dashes[i];
-                       if (totDashLength == 0){
+                               dc.totDashLength += ctx->dashes[i];
+                       if (dc.totDashLength == 0){
                                ctx->status = VKVG_STATUS_INVALID_DASH;
                                return;
                        }
-                       curDashOffset = fmodf(ctx->dashOffset, totDashLength);  //cur dash offset between defined path point and last dash segment(on/off) start
-                       iL = lastPathPointIdx;
+                       dc.curDashOffset = fmodf(ctx->dashOffset, dc.totDashLength);    //cur dash offset between defined path point and last dash segment(on/off) start
+                       str.iL = lastPathPointIdx;
                } else if (_path_is_closed(ctx,ptrPath)){
-                       iL = lastPathPointIdx;
+                       str.iL = lastPathPointIdx;
                }else{
-                       _draw_stoke_cap(ctx, hw, ctx->points[curPathPointIdx], vec2_line_norm(ctx->points[curPathPointIdx], ctx->points[curPathPointIdx+1]), true);
-                       iL = curPathPointIdx++;
+                       _draw_stoke_cap(ctx, hw, ctx->points[str.cp], vec2_line_norm(ctx->points[str.cp], ctx->points[str.cp+1]), true);
+                       str.iL = str.cp++;
                }
 
                if (_path_has_curves (ctx,ptrPath)) {
-                       while (curPathPointIdx < lastPathPointIdx){
+                       while (str.cp < lastPathPointIdx){
 
                                bool curved = ctx->pathes [ptrPath + ptrSegment] & PATH_HAS_CURVES_BIT;
                                if (lastSegmentPointIdx == lastPathPointIdx)//last segment of path, dont draw end point here
                                        lastSegmentPointIdx--;
-                               while (curPathPointIdx <= lastSegmentPointIdx)
-                                       _draw_segment(ctx, hw, curved);
+                               while (str.cp <= lastSegmentPointIdx)
+                                       _draw_segment(ctx, hw, &str, &dc, curved);
 
                                ptrSegment ++;
                                uint32_t cptSegPts = ctx->pathes [ptrPath + ptrSegment]&PATH_ELT_MASK;
-                               lastSegmentPointIdx = curPathPointIdx + cptSegPts - 1;
+                               lastSegmentPointIdx = str.cp + cptSegPts - 1;
                                if (lastSegmentPointIdx == lastPathPointIdx && cptSegPts == 1) {
                                        //single point last segment
                                        ptrSegment++;
                                        break;
                                }
                        }
-               }else while (curPathPointIdx < lastPathPointIdx)
-                       _draw_segment(ctx, hw, false);
+               }else while (str.cp < lastPathPointIdx)
+                       _draw_segment(ctx, hw, &str, &dc, false);
 
                if (ctx->dashCount > 0) {
                        if (_path_is_closed(ctx,ptrPath)){
-                               iR = firstPathPointIdx;
-                               _draw_dashed_segment(ctx, hw, ctx->points[iL++], ctx->points[curPathPointIdx++], ctx->points[iR], false);
+                               str.iR = firstPathPointIdx;
+                               _draw_dashed_segment(ctx, hw, &dc, ctx->points[str.iL++], ctx->points[str.cp++], ctx->points[str.iR], false);
                        }
-                       if (!dashOn){
+                       if (!dc.dashOn){
                                //finishing last dash that is already started, draw end caps but not too close to start
                                //the default gap is the next void
-                               int32_t prevDash = (int32_t)curDash-1;
+                               int32_t prevDash = (int32_t)dc.curDash-1;
                                if (prevDash < 0)
-                                       curDash = ctx->dashCount-1;
-                               float m = fminf (ctx->dashes[prevDash] - curDashOffset, ctx->dashes[curDash]);
-                               vec2 p = vec2_sub(ctx->points[iR], vec2_mult(normal, m));
-                               _draw_stoke_cap (ctx, hw, p, normal, false);
+                                       dc.curDash = ctx->dashCount-1;
+                               float m = fminf (ctx->dashes[prevDash] - dc.curDashOffset, ctx->dashes[dc.curDash]);
+                               vec2 p = vec2_sub(ctx->points[str.iR], vec2_mult(dc.normal, m));
+                               _draw_stoke_cap (ctx, hw, p, dc.normal, false);
                        }
                } else if (_path_is_closed(ctx,ptrPath)){
-                       iR = firstPathPointIdx;
-                       float cross = _build_vb_step (ctx, hw, ctx->points[iL], ctx->points[curPathPointIdx], ctx->points[iR], false);
+                       str.iR = firstPathPointIdx;
+                       float cross = _build_vb_step (ctx, hw, ctx->points[str.iL], ctx->points[str.cp], ctx->points[str.iR], false);
 
                        VKVG_IBO_INDEX_TYPE* inds = &ctx->indexCache [ctx->indCount-6];
                        VKVG_IBO_INDEX_TYPE ii = firstIdx;
@@ -886,11 +897,11 @@ void vkvg_stroke_preserve (VkvgContext ctx)
                                inds[4] = ii;
                                inds[5] = ii+1;
                        }
-                       curPathPointIdx++;
+                       str.cp++;
                }else
-                       _draw_stoke_cap (ctx, hw, ctx->points[curPathPointIdx], vec2_line_norm(ctx->points[curPathPointIdx-1], ctx->points[curPathPointIdx]), false);
+                       _draw_stoke_cap (ctx, hw, ctx->points[str.cp], vec2_line_norm(ctx->points[str.cp-1], ctx->points[str.cp]), false);
 
-               curPathPointIdx = firstPathPointIdx + pathPointCount;
+               str.cp = firstPathPointIdx + pathPointCount;
 
                if (ptrSegment > 0)
                        ptrPath += ptrSegment;
index 84e62e86e9964cff8303e846b3d2238b79dfb6b9..2cef1ad91a634c12d6615a5ec4b8e3a36a47b971 100644 (file)
@@ -453,17 +453,18 @@ void _emit_draw_cmd_undrawn_vertices (VkvgContext ctx){
        _check_vao_size(ctx);
 
        _ensure_renderpass_is_started(ctx);
-       CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
-
-       LOG(VKVG_LOG_INFO, "RECORD DRAW CMD: ctx = %p; vertices = %d; indices = %d (vxOff = %d idxStart = %d idxTot = %d )\n",
-               ctx, ctx->vertCount - ctx->curVertOffset,
-               ctx->indCount - ctx->curIndStart, ctx->curVertOffset, ctx->curIndStart, ctx->indCount);
 
 #ifdef VKVG_WIRED_DEBUG
        CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipelineWired);
        CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
-       CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER);
+       //CmdBindPipeline(ctx->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, ctx->pSurf->dev->pipe_OVER);
+#else
+       CmdDrawIndexed(ctx->cmd, ctx->indCount - ctx->curIndStart, 1, ctx->curIndStart, (int32_t)ctx->curVertOffset, 0);
+
 #endif
+       LOG(VKVG_LOG_INFO, "RECORD DRAW CMD: ctx = %p; vertices = %d; indices = %d (vxOff = %d idxStart = %d idxTot = %d )\n",
+               ctx, ctx->vertCount - ctx->curVertOffset,
+               ctx->indCount - ctx->curIndStart, ctx->curVertOffset, ctx->curIndStart, ctx->indCount);
 
        ctx->curIndStart = ctx->indCount;
        ctx->curVertOffset = ctx->vertCount;
@@ -644,6 +645,7 @@ void _update_cur_pattern (VkvgContext ctx, VkvgPattern pat) {
                break;
        }
        case VKVG_PATTERN_TYPE_LINEAR:
+       case VKVG_PATTERN_TYPE_RADIAL:
                _flush_cmd_buff (ctx);
 
                if (lastPat && lastPat->type == VKVG_PATTERN_TYPE_SURFACE)
@@ -747,22 +749,23 @@ float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bo
        vec2 v0n = vec2_div (v0, length_v0);
        vec2 v1n = vec2_div (v1, length_v1);
 
-       vec2 bisec = vec2_norm(vec2_add(v0n,v1n));
+       vec2 bisec_n = vec2_norm(vec2_add(v0n,v1n));
 
-       float dot = v0n.x * v1n.x + v0n.y * v1n.y;
-       float alpha = acosf(dot)/2;
-       float cross = v0n.x * v1n.y - v0n.y * v1n.x;
+       float dot = vec2_dot (v0n, v1n);
+       float alpha = acosf(dot);
+       float det = v0n.x * v1n.y - v0n.y * v1n.x;
 
-       if (cross<0)
+       if (det<0)
                alpha = -alpha;
 
-       float lh = hw / cosf(alpha);
-       bisec = vec2_perp(bisec);
+       float lh = hw / cosf(alpha/2);
+       bisec_n = vec2_perp(bisec_n);
 
        //limit bisectrice length, may be improved but ok for perf
        lh=fminf (lh, fminf (sqrtf(length_v0*length_v0+hw*hw), sqrtf(length_v1*length_v1+hw*hw)));
 
-       bisec = vec2_mult(bisec,lh);
+
+       vec2 bisec = vec2_mult(bisec_n,lh);
 
        VKVG_IBO_INDEX_TYPE idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
 
@@ -772,9 +775,10 @@ float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bo
                v.pos = vec2_sub(p0, bisec);
                _add_vertex(ctx, v);
                _add_tri_indices_for_rect(ctx, idx);
+
        }else{
                vec2 vp = vec2_perp(v0n);
-               if (cross<0){
+               if (det<0){
                        v.pos = vec2_add (p0, bisec);
                        _add_vertex(ctx, v);
                        v.pos = vec2_sub (p0, vec2_mult (vp, hw));
@@ -786,7 +790,7 @@ float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bo
                _add_vertex(ctx, v);
 
                if (ctx->lineJoin == VKVG_LINE_JOIN_BEVEL){
-                       if (cross<0){
+                       if (det<0){
                                _add_triangle_indices(ctx, idx, idx+2, idx+1);
                                _add_triangle_indices(ctx, idx+2, idx+4, idx+0);
                                _add_triangle_indices(ctx, idx, idx+3, idx+4);
@@ -801,16 +805,16 @@ float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bo
                        if (vp.y < 0)
                                a = -a;
 
-                       if (cross<0){
+                       if (det<0){
                                a+=M_PIF;
-                               float a1 = a + alpha*2;
+                               float a1 = a + alpha;
                                a-=step;
                                while (a > a1){
                                        _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y);
                                        a-=step;
                                }
                        }else{
-                               float a1 = a + alpha*2;
+                               float a1 = a + alpha;
                                a+=step;
                                while (a < a1){
                                        _add_vertexf(ctx, cosf(a) * hw + p0.x, sinf(a) * hw + p0.y);
@@ -819,7 +823,7 @@ float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bo
                        }
                        VKVG_IBO_INDEX_TYPE p0Idx = (VKVG_IBO_INDEX_TYPE)(ctx->vertCount - ctx->curVertOffset);
                        _add_triangle_indices(ctx, idx, idx+2, idx+1);
-                       if (cross<0){
+                       if (det<0){
                                for (VKVG_IBO_INDEX_TYPE p = idx+2; p < p0Idx; p++)
                                        _add_triangle_indices(ctx, p, p+1, idx);
                                _add_triangle_indices(ctx, p0Idx, p0Idx+2, idx);
@@ -834,7 +838,7 @@ float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bo
                }
 
                vp = vec2_mult (vec2_perp(v1n), hw);
-               if (cross<0)
+               if (det<0)
                        v.pos = vec2_sub (p0, vp);
                else
                        v.pos = vec2_add (p0, vp);
@@ -854,7 +858,7 @@ float _build_vb_step (vkvg_context* ctx, float hw, vec2 pL, vec2 p0, vec2 pR, bo
        debugLinePoints[dlpCount+1] = pR;
        dlpCount+=2;
 #endif*/
-       return cross;
+       return det;
 }
 
 bool ptInTriangle(vec2 p, vec2 p0, vec2 p1, vec2 p2) {
index 602323e6b597875c4447f7b80f86381949edb3dd..af2e1df0ef7e6526b7ced4ecbb2beeacfbde1a60 100644 (file)
@@ -375,7 +375,7 @@ void _setupPipelines(VkvgDevice dev)
        VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFragWired));
 
        shaderStages[1].module = modFragWired;
-       inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+       inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
        rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
        VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineWired));
        vkDestroyShaderModule(dev->vkDev, modFragWired, NULL);
index 58fe95fa01430729fc60f17b74d34115af957f82..40afb80eb207937da6e8d10cbf9c5ec747dd7a4b 100644 (file)
@@ -101,6 +101,7 @@ extern float dashes[];
 extern uint32_t dashes_count;
 
 VkvgContext _initCtx();
+void _parse_args (int argc, char* argv[]);
 /*******************************/
 
 //run test in one step