add rhi support

This commit is contained in:
Vogel, Rick 2023-12-09 19:25:07 +01:00
parent eb18c58830
commit 96622e0abd
10 changed files with 111 additions and 12 deletions

View File

@ -16,7 +16,6 @@
#include <qpen.h> #include <qpen.h>
#include <qpainterpath.h> #include <qpainterpath.h>
#include <QSGSimpleMaterialShader>
#include <QFile> #include <QFile>
#include <QDebug> #include <QDebug>
#include <qmath.h> #include <qmath.h>

View File

@ -73,17 +73,44 @@ namespace
{ {
class ShaderRhi final : public RhiShader 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: public:
ShaderRhi() ShaderRhi()
{ {
// TODO const QString root( ":/qskinny/shaders/" );
setShaderFileName( VertexStage, root + "arcshadow.vert.qsb" );
setShaderFileName( FragmentStage, root + "arcshadow.frag.qsb" );
} }
bool updateUniformData( RenderState& state, bool updateUniformData( RenderState& state,
QSGMaterial* newMaterial, QSGMaterial* oldMaterial ) override QSGMaterial* const newMaterial, QSGMaterial* const oldMaterial ) override
{ {
// TODO const auto matOld = static_cast< Material* >( oldMaterial );
return false; 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; 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& lhs = *static_cast< const Material* >( this );
const auto& rhs = *static_cast< const Material* >( other ); const auto& rhs = *static_cast< const Material* >( other );

View File

@ -20,8 +20,8 @@ class QskArcShadowNode : public QSGGeometryNode
QskArcShadowNode(); QskArcShadowNode();
~QskArcShadowNode() override; ~QskArcShadowNode() override;
void update( const QRectF& rect, const QskArcMetrics& metrics, const QColor& color, void update( const QRectF& rect, const QskArcMetrics& arcMetrics, const QColor& shadowColor,
const QskShadowMetrics& shadowMetrics, qreal borderWidth = 0.0 ); const QskShadowMetrics& shadowMetrics, qreal borderWidth );
private: private:
Q_DECLARE_PRIVATE( QskArcShadowNode ) Q_DECLARE_PRIVATE( QskArcShadowNode )

View File

@ -4,6 +4,8 @@
<file>shaders/arcshadow.frag</file> <file>shaders/arcshadow.frag</file>
<file>shaders/arcshadow.vert</file> <file>shaders/arcshadow.vert</file>
<file>shaders/arcshadow.frag.qsb</file>
<file>shaders/arcshadow.vert.qsb</file>
<file>shaders/boxshadow.vert.qsb</file> <file>shaders/boxshadow.vert.qsb</file>
<file>shaders/boxshadow.frag.qsb</file> <file>shaders/boxshadow.frag.qsb</file>

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,13 +1,13 @@
uniform lowp float opacity; uniform lowp mat4 matrix;
// arc
uniform lowp float radius; // arc's radius [0.0, 1.0] 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 thickness; // arc's thickness [0.0, 1.0]
uniform lowp float startAngle; // arc's start angle [rad] uniform lowp float startAngle; // arc's start angle [rad]
uniform lowp float spanAngle; // arc's span angle [rad] uniform lowp float spanAngle; // arc's span angle [rad]
// shadow
uniform lowp vec4 color; // shadow's color 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 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 extend; // shadow length [0.0, 1.0]
uniform lowp float opacity; // overall opacity [0.0, 1.0]
// position // position
varying lowp vec2 coord; // [-1.0,+1.0]x[-1.0,+1.0] varying lowp vec2 coord; // [-1.0,+1.0]x[-1.0,+1.0]

Binary file not shown.

Binary file not shown.

View File

@ -5,6 +5,9 @@ function qsbcompile {
qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -b -o ${qsbfile}.qsb $1 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.vert
qsbcompile boxshadow-vulkan.frag qsbcompile boxshadow-vulkan.frag