From edb118a0c7ddb51f906749862f310cba6539cfcd Mon Sep 17 00:00:00 2001 From: RuiwenTang Date: Wed, 20 Dec 2023 20:51:03 +0800 Subject: [PATCH] gl_engine: fix svg gradient position not correct * change the color and stop size to 16 in shader and buffer block * calculate transform when upload gradient info to gpu pipeline --- src/renderer/gl_engine/tvgGlCommon.h | 2 +- src/renderer/gl_engine/tvgGlRenderer.cpp | 22 ++++++++-- src/renderer/gl_engine/tvgGlShaderSrc.cpp | 51 ++++++++++++++++------- 3 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/renderer/gl_engine/tvgGlCommon.h b/src/renderer/gl_engine/tvgGlCommon.h index 23022459..711e7cf6 100644 --- a/src/renderer/gl_engine/tvgGlCommon.h +++ b/src/renderer/gl_engine/tvgGlCommon.h @@ -65,7 +65,7 @@ struct GlShape unique_ptr geometry; }; -#define MAX_GRADIENT_STOPS 4 +#define MAX_GRADIENT_STOPS 16 struct GlLinearGradientBlock { diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index 287bb916..43bcda98 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -527,7 +527,8 @@ void GlRenderer::drawPrimitive(GlShape& sdata, uint8_t r, uint8_t g, uint8_t b, void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFlag flag) { const Fill::ColorStop* stops = nullptr; - auto stopCnt = fill->colorStops(&stops); + auto stopCnt = min(fill->colorStops(&stops), + static_cast(MAX_GRADIENT_STOPS)); if (stopCnt < 2) return; GlRenderTask* task = nullptr; @@ -576,7 +577,15 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFla gradientBlock.stopColors[i * 4 + 3] = stops[i].a / 255.f; } - linearFill->linear(&gradientBlock.startPos[0], &gradientBlock.startPos[1], &gradientBlock.stopPos[0], &gradientBlock.stopPos[1]); + float x1, x2, y1, y2; + linearFill->linear(&x1, &y1, &x2, &y2); + + auto transform = linearFill->transform(); + + gradientBlock.startPos[0] = x1 * transform.e11 + transform.e13; + gradientBlock.startPos[1] = y1 * transform.e22 + transform.e23; + gradientBlock.stopPos[0] = x2 * transform.e11 + transform.e13; + gradientBlock.stopPos[1] = y2 * transform.e22 + transform.e23; gradientBinding = GlBindingResource{ 1, @@ -600,7 +609,14 @@ void GlRenderer::drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFla gradientBlock.stopColors[i * 4 + 3] = stops[i].a / 255.f; } - radialFill->radial(&gradientBlock.centerPos[0], &gradientBlock.centerPos[1], &gradientBlock.radius[0]); + float x, y, r; + radialFill->radial(&x, &y, &r); + + auto transform = radialFill->transform(); + + gradientBlock.centerPos[0] = x * transform.e11 + transform.e13; + gradientBlock.centerPos[1] = y * transform.e22 + transform.e23; + gradientBlock.radius[0] = r * transform.e11; gradientBinding = GlBindingResource{ 1, diff --git a/src/renderer/gl_engine/tvgGlShaderSrc.cpp b/src/renderer/gl_engine/tvgGlShaderSrc.cpp index 1bc30997..7b673d47 100644 --- a/src/renderer/gl_engine/tvgGlShaderSrc.cpp +++ b/src/renderer/gl_engine/tvgGlShaderSrc.cpp @@ -67,7 +67,7 @@ void main() std::string STR_GRADIENT_FRAG_COMMON_VARIABLES = TVG_COMPOSE_SHADER( -const int MAX_STOP_COUNT = 4; \n +const int MAX_STOP_COUNT = 16; \n in vec2 vPos; \n in float vOpacity; \n ); @@ -80,16 +80,38 @@ float gradientStep(float edge0, float edge1, float x) return x; \n } \n \n +float gradientStop(int index) \n +{ \n + if (index >= MAX_STOP_COUNT) index = MAX_STOP_COUNT - 1; \n + int i = index / 4; \n + int j = index % 4; \n + return uGradientInfo.stopPoints[i][j]; \n +} \n + \n +float gradientWrap(float d) \n +{ \n + int i = 1; \n + while (d > 1.0) { \n + d = d - 1.0; \n + i *= -1; \n + } \n + \n + if (i == 1) \n + return smoothstep(0.0, 1.0, d); \n + else \n + return smoothstep(1.0, 0.0, d); \n +} \n + \n vec4 gradient(float t) \n { \n vec4 col = vec4(0.0); \n int i = 0; \n - int count = int(uGradientInfo.nStops[0]); \n - if (t <= uGradientInfo.stopPoints[0]) \n + int count = int(uGradientInfo.nStops[0]); \n + if (t <= gradientStop(0)) \n { \n col += uGradientInfo.stopColors[0]; \n } \n - else if (t >= uGradientInfo.stopPoints[count - 1]) \n + else if (t >= gradientStop(count - 1)) \n { \n col += uGradientInfo.stopColors[count - 1]; \n } \n @@ -97,13 +119,12 @@ vec4 gradient(float t) { \n for (i = 0; i < count - 1; ++i) \n { \n - if (t > uGradientInfo.stopPoints[i] && t < uGradientInfo.stopPoints[i + 1]) \n + float stopi = gradientStop(i); \n + float stopi1 = gradientStop(i + 1); \n + if (t > stopi && t