From 96622e0abd1b8e999c97e3a7d7582edef88dce3f Mon Sep 17 00:00:00 2001 From: "Vogel, Rick" Date: Sat, 9 Dec 2023 19:25:07 +0100 Subject: [PATCH] add rhi support --- src/nodes/QskArcNode.cpp | 1 - src/nodes/QskArcShadowNode.cpp | 39 +++++++++++++++--- src/nodes/QskArcShadowNode.h | 4 +- src/nodes/shaders.qrc | 2 + src/nodes/shaders/arcshadow-vulkan.frag | 52 ++++++++++++++++++++++++ src/nodes/shaders/arcshadow-vulkan.vert | 16 ++++++++ src/nodes/shaders/arcshadow.frag | 6 +-- src/nodes/shaders/arcshadow.frag.qsb | Bin 0 -> 2718 bytes src/nodes/shaders/arcshadow.vert.qsb | Bin 0 -> 1360 bytes src/nodes/shaders/vulkan2qsb.sh | 3 ++ 10 files changed, 111 insertions(+), 12 deletions(-) create mode 100644 src/nodes/shaders/arcshadow-vulkan.frag create mode 100644 src/nodes/shaders/arcshadow-vulkan.vert create mode 100644 src/nodes/shaders/arcshadow.frag.qsb create mode 100644 src/nodes/shaders/arcshadow.vert.qsb diff --git a/src/nodes/QskArcNode.cpp b/src/nodes/QskArcNode.cpp index 7f1eea7a..d4e5ef0c 100644 --- a/src/nodes/QskArcNode.cpp +++ b/src/nodes/QskArcNode.cpp @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/src/nodes/QskArcShadowNode.cpp b/src/nodes/QskArcShadowNode.cpp index 05a237d7..bbd07bf9 100644 --- a/src/nodes/QskArcShadowNode.cpp +++ b/src/nodes/QskArcShadowNode.cpp @@ -73,17 +73,44 @@ namespace { class ShaderRhi final : public RhiShader { + struct UniformBuffer + { + float matrix[4][4]; + MaterialProperties properties; + float opacity = 1.0f; + + static_assert(sizeof(properties) == sizeof(float) * 11, "Layout mustn't have trailing paddings"); + }; + public: ShaderRhi() { - // TODO + const QString root( ":/qskinny/shaders/" ); + setShaderFileName( VertexStage, root + "arcshadow.vert.qsb" ); + setShaderFileName( FragmentStage, root + "arcshadow.frag.qsb" ); } bool updateUniformData( RenderState& state, - QSGMaterial* newMaterial, QSGMaterial* oldMaterial ) override + QSGMaterial* const newMaterial, QSGMaterial* const oldMaterial ) override { - // TODO - return false; + const auto matOld = static_cast< Material* >( oldMaterial ); + const auto matNew = static_cast< Material* >( newMaterial ); + + const bool dirty = matOld == nullptr || state.isOpacityDirty() || state.isMatrixDirty() || + matOld->compare( matNew ) != 0; + + UniformBuffer buffer; + + const auto dstBufferSize = state.uniformData()->size(); + const auto srcBufferSize = sizeof(buffer); + Q_ASSERT( dstBufferSize >= srcBufferSize ); + + auto* data = state.uniformData()->data(); + std::memcpy(buffer.matrix, state.combinedMatrix().constData(), sizeof(buffer.matrix)); + buffer.properties = matNew->properties; + std::memcpy(data, &buffer, sizeof(buffer)); + + return dirty; } }; } @@ -215,7 +242,7 @@ namespace return &staticType; } - int Material::compare( const QSGMaterial* other ) const + int Material::compare( const QSGMaterial* const other ) const { const auto& lhs = *static_cast< const Material* >( this ); const auto& rhs = *static_cast< const Material* >( other ); @@ -275,7 +302,7 @@ void QskArcShadowNode::update( const QRectF& rect, const QskArcMetrics& arcMetri const QColor& shadowColor, const QskShadowMetrics& shadowMetrics, const qreal borderWidth ) { Q_D( QskArcShadowNode ); - + const auto w = qMax(0.0, borderWidth); const auto shadowRect = rect.adjusted(-w, -w, +w, +w); const auto size = qMin( shadowRect.width(), shadowRect.height() ); diff --git a/src/nodes/QskArcShadowNode.h b/src/nodes/QskArcShadowNode.h index 7747a7e5..c69e3e9d 100644 --- a/src/nodes/QskArcShadowNode.h +++ b/src/nodes/QskArcShadowNode.h @@ -20,8 +20,8 @@ class QskArcShadowNode : public QSGGeometryNode QskArcShadowNode(); ~QskArcShadowNode() override; - void update( const QRectF& rect, const QskArcMetrics& metrics, const QColor& color, - const QskShadowMetrics& shadowMetrics, qreal borderWidth = 0.0 ); + void update( const QRectF& rect, const QskArcMetrics& arcMetrics, const QColor& shadowColor, + const QskShadowMetrics& shadowMetrics, qreal borderWidth ); private: Q_DECLARE_PRIVATE( QskArcShadowNode ) diff --git a/src/nodes/shaders.qrc b/src/nodes/shaders.qrc index 7f74a1ac..7d2d15a4 100644 --- a/src/nodes/shaders.qrc +++ b/src/nodes/shaders.qrc @@ -4,6 +4,8 @@ shaders/arcshadow.frag shaders/arcshadow.vert + shaders/arcshadow.frag.qsb + shaders/arcshadow.vert.qsb shaders/boxshadow.vert.qsb shaders/boxshadow.frag.qsb diff --git a/src/nodes/shaders/arcshadow-vulkan.frag b/src/nodes/shaders/arcshadow-vulkan.frag new file mode 100644 index 00000000..69a6929e --- /dev/null +++ b/src/nodes/shaders/arcshadow-vulkan.frag @@ -0,0 +1,52 @@ +#version 440 + +layout( location = 0 ) in vec2 coord; // [-1.0,+1.0]x[-1.0,+1.0] +layout( location = 0 ) out vec4 fragColor; + +layout( std140, binding = 0 ) uniform buf +{ + mat4 matrix; + vec4 color; // shadow's color + vec2 offset; // shadow's offset (x,y) : [-1.0, +1.0]x[-1.0,+1.0] + float radius; // arc's radius [0.0, 1.0] + float thickness; // arc's thickness [0.0, 1.0] + float startAngle; // arc's start angle [rad] + float spanAngle; // arc's span angle [rad] + float extend; // shadow length [0.0, 1.0] + float opacity; // overall opacity [0.0, 1.0] +} ubuf; + +float sdRing( in vec2 p, in vec2 n, in float r, in float th ) +{ + p.x = abs(p.x); + + p = mat2(n.x,n.y,-n.y,n.x)*p; + + return max( abs(length(p)-r)-th*0.5, + length(vec2(p.x,max(0.0,abs(r-p.y)-th*0.5)))*sign(p.x) ); +} + +void main() +{ + // rotation + vec2 p = coord + ubuf.offset; + float ra = -ubuf.startAngle - ubuf.spanAngle / 2.0; + { + float sin_ra = sin(ra); + float cos_ra = cos(ra); + mat2 transform = mat2 + ( + cos_ra, -sin_ra, + sin_ra, cos_ra + ); + + p = transform * p; + } + + float t = abs(ubuf.spanAngle) / 2.0; // half span angle + vec2 cs = vec2(cos(t),sin(t)); + float d = sdRing(p, cs, ubuf.radius / 2.0, ubuf.thickness); + + float a = 1.0 - smoothstep(0.0, ubuf.extend, d); + fragColor = vec4(ubuf.color.rgb, 1.0) * a * ubuf.opacity; +} \ No newline at end of file diff --git a/src/nodes/shaders/arcshadow-vulkan.vert b/src/nodes/shaders/arcshadow-vulkan.vert new file mode 100644 index 00000000..177e20d0 --- /dev/null +++ b/src/nodes/shaders/arcshadow-vulkan.vert @@ -0,0 +1,16 @@ +#version 440 + +layout( location = 0 ) in vec4 in_vertex; +layout( location = 1 ) in vec2 in_coord; +layout( location = 0 ) out vec2 coord; + +layout( std140, binding = 0 ) uniform buf +{ + mat4 matrix; +} ubuf; + +void main() +{ + coord = in_coord; + gl_Position = ubuf.matrix * in_vertex; +} diff --git a/src/nodes/shaders/arcshadow.frag b/src/nodes/shaders/arcshadow.frag index 7e2bef1c..2d44a320 100644 --- a/src/nodes/shaders/arcshadow.frag +++ b/src/nodes/shaders/arcshadow.frag @@ -1,13 +1,13 @@ -uniform lowp float opacity; -// arc +uniform lowp mat4 matrix; uniform lowp float radius; // arc's radius [0.0, 1.0] uniform lowp float thickness; // arc's thickness [0.0, 1.0] uniform lowp float startAngle; // arc's start angle [rad] uniform lowp float spanAngle; // arc's span angle [rad] -// shadow uniform lowp vec4 color; // shadow's color uniform lowp vec2 offset; // shadow's offset (x,y) : [-1.0, +1.0]x[-1.0,+1.0] uniform lowp float extend; // shadow length [0.0, 1.0] +uniform lowp float opacity; // overall opacity [0.0, 1.0] + // position varying lowp vec2 coord; // [-1.0,+1.0]x[-1.0,+1.0] diff --git a/src/nodes/shaders/arcshadow.frag.qsb b/src/nodes/shaders/arcshadow.frag.qsb new file mode 100644 index 0000000000000000000000000000000000000000..435e2fe94e0e87a49656a486f4a8d1bd0901ec4b GIT binary patch literal 2718 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 S^cne3?Zivf=j&fSIWVM&v7S}{ literal 0 HcmV?d00001 diff --git a/src/nodes/shaders/vulkan2qsb.sh b/src/nodes/shaders/vulkan2qsb.sh index 22e28e10..0ace7a2d 100755 --- a/src/nodes/shaders/vulkan2qsb.sh +++ b/src/nodes/shaders/vulkan2qsb.sh @@ -5,6 +5,9 @@ function qsbcompile { qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -b -o ${qsbfile}.qsb $1 } +qsbcompile arcshadow-vulkan.vert +qsbcompile arcshadow-vulkan.frag + qsbcompile boxshadow-vulkan.vert qsbcompile boxshadow-vulkan.frag