From: Jean-Philippe Bruyère Date: Thu, 13 Jan 2022 14:03:05 +0000 (+0100) Subject: get matrix scaling to scale arcstep and curve dist limit X-Git-Tag: v0.3.0-beta~12 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=1871cbbe3955f943c85140baff271b8425ee1fdc;p=jp%2Fvkvg.git get matrix scaling to scale arcstep and curve dist limit --- diff --git a/include/vkvg.h b/include/vkvg.h index 9a62501..2da756e 100644 --- a/include/vkvg.h +++ b/include/vkvg.h @@ -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); /** @}*/ /*! diff --git a/src/vkvg_context.c b/src/vkvg_context.c index 2cb248b..7835951 100644 --- a/src/vkvg_context.c +++ b/src/vkvg_context.c @@ -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; diff --git a/src/vkvg_context_internal.c b/src/vkvg_context_internal.c index c5c6279..15e2c35 100644 --- a/src/vkvg_context_internal.c +++ b/src/vkvg_context_internal.c @@ -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, diff --git a/src/vkvg_device_internal.c b/src/vkvg_device_internal.c index fac91a5..90556a2 100644 --- a/src/vkvg_device_internal.c +++ b/src/vkvg_device_internal.c @@ -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 diff --git a/src/vkvg_matrix.c b/src/vkvg_matrix.c index d0525f0..998ece0 100644 --- a/src/vkvg_matrix.c +++ b/src/vkvg_matrix.c @@ -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 index 0000000..dd47a24 --- /dev/null +++ b/tests/getarcstep.c @@ -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; +}