]> O.S.I.I.S - jp/vkvg.git/commitdiff
get matrix scaling to scale arcstep and curve dist limit
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 13 Jan 2022 14:03:05 +0000 (15:03 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 13 Jan 2022 14:03:05 +0000 (15:03 +0100)
include/vkvg.h
src/vkvg_context.c
src/vkvg_context_internal.c
src/vkvg_device_internal.c
src/vkvg_matrix.c
tests/getarcstep.c [new file with mode: 0644]

index 9a6250135019bf5c47b5997b63a68fa8ea61fa73..2da756e20b0838554c8a4a896aefcad1bd929394 100644 (file)
@@ -507,6 +507,8 @@ void vkvg_matrix_transform_point (const vkvg_matrix_t *matrix, float *x, float *
  */
 vkvg_public
 vkvg_status_t vkvg_matrix_invert (vkvg_matrix_t *matrix);
+vkvg_public
+void vkvg_matrix_get_scale (const vkvg_matrix_t *matrix, float *sx, float *sy);
 /** @}*/
 
 /*!
index 2cb248be4bb4d805a1dca2b175fab1dd57830c8b..7835951a9279764c5615489658e1d745ed5af2e4 100644 (file)
@@ -550,10 +550,10 @@ void _curve_to (VkvgContext ctx, float x1, float y1, float x2, float y2, float x
 
        vec2 cp = _get_current_position(ctx);
 
-       //compute dyn distanceTolerance depending on current transform
-       float dx = 1, dy = 1;
-       vkvg_matrix_transform_point (&ctx->pushConsts.mat, &dx, &dy);
-       float distanceTolerance = fabs(0.02f / fmaxf(dx,dy));
+       //compute dyn distanceTolerance depending on current scale
+       float sx = 1, sy = 1;
+       vkvg_matrix_get_scale (&ctx->pushConsts.mat, &sx, &sy);
+       float distanceTolerance = fabs(1.0f / fmaxf(sx,sy));
 
        _recursive_bezier (ctx, distanceTolerance, cp.x, cp.y, x1, y1, x2, y2, x3, y3, 0);
        /*cp.x = x3;
index c5c6279af85ab4bc236b01152a9551215635ac6d..15e2c359d90bc8fd0f757162e30086a2d4e371dd 100644 (file)
@@ -218,14 +218,12 @@ float _normalizeAngle(float a)
     return res;
 }
 float _get_arc_step (VkvgContext ctx, float radius) {
-       float dx = radius, dy = radius;
-       vkvg_matrix_transform_point (&ctx->pushConsts.mat, &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);*/
-       //return fmax(8, M_PI / (r * 1.1f));
-       return fminf(M_PI / 3.f,M_PI / (r * 0.8f));
+       float sx, sy;
+       vkvg_matrix_get_scale (&ctx->pushConsts.mat, &sx, &sy);
+       float r = radius * fabsf(fmaxf(sx,sy));
+       if (r < 15.0f)
+               return fminf(M_PI / 3.f, M_PI / r);
+       return fminf(M_PI / 3.f,M_PI / (r * 0.4f));
 }
 void _create_gradient_buff (VkvgContext ctx){
        vkvg_buffer_create (ctx->pSurf->dev,
index fac91a54ed8c8c6ac9295013ded7e2871f556eee..90556a283858282b9eb01dd8ea819123ec6a4e00 100644 (file)
@@ -373,18 +373,19 @@ void _setupPipelines(VkvgDevice dev)
 
 
 #ifdef VKVG_WIRED_DEBUG
-       rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
-       inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP;
-       VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineLineList));
-
        createInfo.pCode = (uint32_t*)wired_frag_spv;
        createInfo.codeSize = wired_frag_spv_len;
        VK_CHECK_RESULT(vkCreateShaderModule(dev->vkDev, &createInfo, NULL, &modFragWired));
 
        shaderStages[1].module = modFragWired;
+
+       rasterizationState.polygonMode = VK_POLYGON_MODE_LINE;
+       VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineLineList));
+
        inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
-       rasterizationState.polygonMode = VK_POLYGON_MODE_POINT;
+       rasterizationState.polygonMode = VK_POLYGON_MODE_FILL;
        VK_CHECK_RESULT(vkCreateGraphicsPipelines(dev->vkDev, dev->pipelineCache, 1, &pipelineCreateInfo, NULL, &dev->pipelineWired));
+
        vkDestroyShaderModule(dev->vkDev, modFragWired, NULL);
 #endif
 
index d0525f0dd13ed30b5c8d4782c607a2a35f2f1037..998ece03a68409062bfc934bef6a326c2c5b8290 100644 (file)
@@ -257,3 +257,11 @@ void vkvg_matrix_transform_point (const vkvg_matrix_t *matrix, float *x, float *
        *x += matrix->x0;
        *y += matrix->y0;
 }
+void vkvg_matrix_get_scale (const vkvg_matrix_t *matrix, float *sx, float *sy) {
+       *sx = sqrt (matrix->xx * matrix->xx + matrix->xy * matrix->xy);
+       /*if (matrix->xx < 0)
+               *sx = -*sx;*/
+       *sy = sqrt (matrix->yx * matrix->yx + matrix->yy * matrix->yy);
+       /*if (matrix->yy < 0)
+               *sy = -*sy;*/
+}
diff --git a/tests/getarcstep.c b/tests/getarcstep.c
new file mode 100644 (file)
index 0000000..dd47a24
--- /dev/null
@@ -0,0 +1,158 @@
+#include "test.h"
+#include "vectors.h"
+#include "vkvg_context_internal.h"
+
+vkvg_fill_rule_t fillrule = VKVG_FILL_RULE_NON_ZERO;
+static VkSampleCountFlags samples = VK_SAMPLE_COUNT_8_BIT;
+float lineWidth = 3.0f;
+vkvg_line_join_t lineJoin = VKVG_LINE_JOIN_MITER;
+vkvg_line_cap_t lineCap = VKVG_LINE_CAP_BUTT;
+bool isClosed = false;
+bool startWithArc = false, endWithArc = false;
+float angle = 0;
+float r;
+vec2 mouse;
+
+void draw (){
+       angle += 0.001f;
+
+       VkvgContext ctx = vkvg_create(surf);
+       vkvg_clear(ctx);
+
+       float r = fabsf(test_width/2 - mouse.x)/zoom;
+
+       vkvg_new_path(ctx);
+       vkvg_set_source_rgba(ctx,1,0,0,1);
+       vkvg_set_line_width (ctx,lineWidth/zoom);
+
+       vkvg_translate(ctx, test_width/2, test_height/2);
+       vkvg_scale(ctx, zoom, zoom);
+       //vkvg_rotate (ctx, angle);
+
+       vkvg_matrix_t mat;
+       vkvg_get_matrix(ctx, &mat);
+       float sx, sy;
+       vkvg_matrix_get_scale(&mat, &sx, &sy);
+
+       vkvg_arc (ctx,0,0,r, 0, M_PIF*2);
+       vkvg_fill(ctx);
+
+       float steps = _get_arc_step(ctx, r);
+       vkvg_identity_matrix(ctx);
+
+       vkvg_set_source_rgba(ctx,1,1,1,1);
+       char txt[100];
+       sprintf(txt, "scale: %f, %f", sx, sy);
+       vkvg_move_to(ctx,10,10);
+       vkvg_show_text(ctx,txt);
+       sprintf(txt, "angle: %f", angle);
+       vkvg_move_to(ctx,10,25);
+       vkvg_show_text(ctx,txt);
+       sprintf(txt, "radius: %f", r);
+       vkvg_move_to(ctx,10,40);
+       vkvg_show_text(ctx,txt);
+       sprintf(txt, "zoom: %f", zoom);
+       vkvg_move_to(ctx,10,55);
+       vkvg_show_text(ctx,txt);
+       sprintf(txt, "arc step: %f", steps);
+       vkvg_move_to(ctx,10,70);
+       vkvg_show_text(ctx,txt);
+       sprintf(txt, "steps: %d", (int)roundf(2.0f*M_PI / steps));
+       vkvg_move_to(ctx,10,85);
+       vkvg_show_text(ctx,txt);
+
+       vkvg_destroy(ctx);
+}
+static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
+       if (action != GLFW_PRESS)
+               return;
+       switch (key) {
+       case GLFW_KEY_ESCAPE :
+               glfwSetWindowShouldClose(window, GLFW_TRUE);
+               break;
+       case GLFW_KEY_KP_ADD :
+               zoom *= 2.0f;
+               break;
+       case GLFW_KEY_KP_SUBTRACT :
+               zoom *= 0.5f;
+               break;
+#ifdef VKVG_WIRED_DEBUG
+       case GLFW_KEY_F1:
+               vkvg_wired_debug ^= (1U << 0);
+               break;
+       case GLFW_KEY_F2:
+               vkvg_wired_debug ^= (1U << 1);
+               break;
+       case GLFW_KEY_F3:
+               vkvg_wired_debug ^= (1U << 2);
+               break;
+#endif
+       }
+}
+static void mouse_move_callback(GLFWwindow* window, double x, double y){
+       if (mouseDown) {
+               mouse = (vec2) {x, y};
+       }
+}
+static void scroll_callback(GLFWwindow* window, double x, double y){
+       if (y<0.f)
+               zoom *= 0.5f;
+       else
+               zoom *= 2.0f;
+}
+static void mouse_button_callback(GLFWwindow* window, int but, int state, int modif){
+       if (but != GLFW_MOUSE_BUTTON_1)
+               return;
+       if (state == GLFW_TRUE)
+               mouseDown = true;
+       else
+               mouseDown = false;
+}
+
+
+
+int main(int argc, char* argv[]) {
+
+       _parse_args (argc, argv);
+       VkEngine e;
+       e = vkengine_create (VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, VK_PRESENT_MODE_FIFO_KHR, test_width, test_height);
+
+       VkhPresenter r = e->renderer;
+       vkengine_set_key_callback (e, key_callback);
+       vkengine_set_mouse_but_callback(e, mouse_button_callback);
+       vkengine_set_cursor_pos_callback(e, mouse_move_callback);
+       vkengine_set_scroll_callback(e, scroll_callback);
+
+       bool deferredResolve = false;
+
+       device = vkvg_device_create_from_vk_multisample(vkh_app_get_inst(e->app), r->dev->phy, r->dev->dev, r->qFam, 0, samples, deferredResolve);
+       surf = vkvg_surface_create(device, test_width, test_height);
+
+       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+
+       mouse = (vec2){test_width*0.75,test_height*0.5f};
+
+       while (!vkengine_should_close (e)) {
+               glfwPollEvents();
+
+               draw ();
+
+               if (!vkh_presenter_draw (r)){
+                       vkh_presenter_get_size (r, &test_width, &test_height);
+                       vkvg_surface_destroy (surf);
+                       surf = vkvg_surface_create(device, test_width, test_height);
+                       vkh_presenter_build_blit_cmd (r, vkvg_surface_get_vk_image(surf), test_width, test_height);
+                       vkDeviceWaitIdle(r->dev->dev);
+                       continue;
+               }
+       }
+       vkDeviceWaitIdle(e->dev->dev);
+
+       vkvg_surface_destroy    (surf);
+
+       vkvg_device_destroy     (device);
+
+       vkengine_destroy (e);
+
+       return 0;
+}