arc shadow shader moved to playground shadows - the algo does not match

the arc renderer.
This commit is contained in:
Uwe Rathmann 2024-09-30 12:06:51 +02:00
parent 6a2e07339e
commit af34d7b8f2
14 changed files with 107 additions and 86 deletions

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#include "QskArcShadowNode.h"
#include "ArcShadowNode.h"
#include <qcolor.h>
#include <qsgmaterial.h>
@ -252,10 +252,10 @@ namespace
}
}
class QskArcShadowNodePrivate final : public QSGGeometryNodePrivate
class ArcShadowNodePrivate final : public QSGGeometryNodePrivate
{
public:
QskArcShadowNodePrivate()
ArcShadowNodePrivate()
: geometry( QSGGeometry::defaultAttributes_TexturedPoint2D(), 4 )
{
}
@ -265,10 +265,10 @@ class QskArcShadowNodePrivate final : public QSGGeometryNodePrivate
QRectF rect;
};
QskArcShadowNode::QskArcShadowNode()
: QSGGeometryNode( *new QskArcShadowNodePrivate )
ArcShadowNode::ArcShadowNode()
: QSGGeometryNode( *new ArcShadowNodePrivate )
{
Q_D( QskArcShadowNode );
Q_D( ArcShadowNode );
setGeometry( &d->geometry );
setMaterial( &d->material );
@ -277,9 +277,9 @@ QskArcShadowNode::QskArcShadowNode()
d->material.setFlag( QSGMaterial::Blending );
}
QskArcShadowNode::~QskArcShadowNode() = default;
ArcShadowNode::~ArcShadowNode() = default;
void QskArcShadowNode::setShadowData(
void ArcShadowNode::setShadowData(
const QRectF& rect, qreal spreadRadius, qreal blurRadius,
qreal startAngle, qreal spanAngle, const QColor& color )
{
@ -289,7 +289,7 @@ void QskArcShadowNode::setShadowData(
return;
}
Q_D( QskArcShadowNode );
Q_D( ArcShadowNode );
if ( d->rect != rect )
{
@ -351,9 +351,9 @@ void QskArcShadowNode::setShadowData(
}
}
void QskArcShadowNode::setBoundingRectangle( const QRectF& rect )
void ArcShadowNode::setBoundingRectangle( const QRectF& rect )
{
Q_D( QskArcShadowNode );
Q_D( ArcShadowNode );
if ( d->rect == rect )
return;

View File

@ -3,8 +3,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*****************************************************************************/
#ifndef QSK_ARC_SHADOW_NODE_H
#define QSK_ARC_SHADOW_NODE_H
#pragma once
#include "QskGlobal.h"
#include <qsgnode.h>
@ -12,13 +11,13 @@
class QskArcMetrics;
class QskShadowMetrics;
class QskArcShadowNodePrivate;
class ArcShadowNodePrivate;
class QskArcShadowNode : public QSGGeometryNode
class ArcShadowNode : public QSGGeometryNode
{
public:
QskArcShadowNode();
~QskArcShadowNode() override;
ArcShadowNode();
~ArcShadowNode() override;
void setShadowData( const QRectF&, qreal spreadRadius, qreal blurRadius,
qreal startAngle, qreal spanAngle, const QColor& );
@ -26,7 +25,5 @@ class QskArcShadowNode : public QSGGeometryNode
private:
void setBoundingRectangle( const QRectF& );
Q_DECLARE_PRIVATE( QskArcShadowNode )
Q_DECLARE_PRIVATE( ArcShadowNode )
};
#endif

View File

@ -3,7 +3,38 @@
# SPDX-License-Identifier: BSD-3-Clause
############################################################################
qsk_add_example(shadows
BoxPage.h BoxPage.cpp ShadowedBox.h ShadowedBox.cpp
ArcPage.h ArcPage.cpp ShadowedArc.h ShadowedArc.cpp
Slider.h Slider.cpp main.cpp)
set(target shadows)
set(SOURCES
BoxPage.h
BoxPage.cpp
ShadowedBox.h
ShadowedBox.cpp
ArcPage.h
ArcPage.cpp
ShadowedArc.h
ShadowedArc.cpp
Slider.h
Slider.cpp
main.cpp
)
list(APPEND SOURCES
ArcShadowNode.h
ArcShadowNode.cpp
)
if (QT_VERSION_MAJOR VERSION_LESS 6)
qt_add_resources(SOURCES shaders.qrc)
endif()
qsk_add_example(${target} ${SOURCES})
if (QT_VERSION_MAJOR VERSION_GREATER_EQUAL 6)
list(APPEND SHADERS
shaders/arcshadow-vulkan.vert
shaders/arcshadow-vulkan.frag
)
qsk_add_shaders( ${target} FILES ${SHADERS} OUTPUT_TARGETS shader_target)
endif()

View File

@ -4,14 +4,14 @@
*****************************************************************************/
#include "ShadowedArc.h"
#include "ArcShadowNode.h"
#include <QskSkinlet.h>
#include <QskArcNode.h>
#include <QskArcMetrics.h>
#include <QskShadowMetrics.h>
#include <QskArcNode.h>
#include <QskSGNode.h>
#include <QskRgbValue.h>
QSK_SUBCONTROL( ShadowedArc, Arc )
@ -22,7 +22,7 @@ namespace
using Inherited = QskSkinlet;
public:
enum NodeRoles { ArcRole };
enum NodeRoles { ShadowRole, ArcRole };
Skinlet( QskSkin* skin = nullptr );
@ -34,12 +34,13 @@ namespace
private:
QSGNode* updateArcNode( const ShadowedArc*, QSGNode* node ) const;
QSGNode* updateShadowNode( const ShadowedArc*, QSGNode* node ) const;
};
Skinlet::Skinlet( QskSkin* skin )
: QskSkinlet( skin )
{
setNodeRoles( { ArcRole } );
setNodeRoles( { ShadowRole, ArcRole } );
}
QRectF Skinlet::subControlRect( const QskSkinnable* skinnable,
@ -54,15 +55,49 @@ namespace
QSGNode* Skinlet::updateSubNode(
const QskSkinnable* skinnable, quint8 nodeRole, QSGNode* node ) const
{
if ( nodeRole == ArcRole )
auto arc = static_cast< const ShadowedArc* >( skinnable );
switch( nodeRole )
{
auto arc = static_cast< const ShadowedArc* >( skinnable );
return updateArcNode( arc, node );
case ShadowRole:
return updateShadowNode( arc, node );
break;
case ArcRole:
return updateArcNode( arc, node );
}
return Inherited::updateSubNode( skinnable, nodeRole, node );
}
QSGNode* Skinlet::updateShadowNode( const ShadowedArc* arc, QSGNode* node ) const
{
using Q = ShadowedArc;
const auto rect = arc->subControlRect( Q::Arc );
if ( rect.isEmpty() )
return nullptr;
const auto color = arc->shadowColorHint( Q::Arc );
if ( !QskRgb::isVisible( color ) )
return nullptr;
auto metricsArc = arc->arcMetricsHint( Q::Arc );
metricsArc = metricsArc.toAbsolute( rect.size() );
auto metrics = arc->shadowMetricsHint( Q::Arc );
metrics = metrics.toAbsolute( rect.size() );
const auto shadowRect = metrics.shadowRect( rect );
const auto spreadRadius = metrics.spreadRadius() + 0.5 * metricsArc.thickness();
auto shadowNode = QskSGNode::ensureNode< ArcShadowNode >( node );
shadowNode->setShadowData( shadowRect, spreadRadius, metrics.blurRadius(),
metricsArc.startAngle(), metricsArc.spanAngle(), color );
return shadowNode;;
}
QSGNode* Skinlet::updateArcNode( const ShadowedArc* arc, QSGNode* node ) const
{
using Q = ShadowedArc;
@ -79,11 +114,7 @@ namespace
const auto borderColor = arc->color( Q::Arc | QskAspect::Border );
const auto borderWidth = arc->metric( Q::Arc | QskAspect::Border );
const auto shadowColor = arc->shadowColorHint( Q::Arc );
const auto shadowMetrics = arc->shadowMetricsHint( Q::Arc );
arcNode->setArcData( rect, metrics, borderWidth, borderColor,
fillGradient, shadowColor, shadowMetrics);
arcNode->setArcData( rect, metrics, borderWidth, borderColor, fillGradient );
return arcNode;
}

View File

@ -0,0 +1,9 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/qskinny/">
<file>shaders/arcshadow.vert</file>
<file>shaders/arcshadow.frag</file>
</qresource>
</RCC>

View File

@ -103,7 +103,6 @@ list(APPEND HEADERS
nodes/QskArcNode.h
nodes/QskArcRenderer.h
nodes/QskArcRenderNode.h
nodes/QskArcShadowNode.h
nodes/QskBasicLinesNode.h
nodes/QskBoxNode.h
nodes/QskBoxClipNode.h
@ -144,7 +143,6 @@ list(APPEND SOURCES
nodes/QskArcNode.cpp
nodes/QskArcRenderer.cpp
nodes/QskArcRenderNode.cpp
nodes/QskArcShadowNode.cpp
nodes/QskBasicLinesNode.cpp
nodes/QskBoxNode.cpp
nodes/QskBoxClipNode.cpp
@ -180,8 +178,6 @@ if (QT_VERSION_MAJOR VERSION_LESS 6)
qt_add_resources(SOURCES nodes/shaders.qrc)
else()
list(APPEND SHADERS
nodes/shaders/arcshadow-vulkan.vert
nodes/shaders/arcshadow-vulkan.frag
nodes/shaders/boxshadow-vulkan.vert
nodes/shaders/boxshadow-vulkan.frag
nodes/shaders/crisplines-vulkan.vert

View File

@ -230,7 +230,7 @@ static inline QSGNode* qskUpdateArcNode(
return nullptr;
auto arcNode = QskSGNode::ensureNode< QskArcNode >( node );
arcNode->setArcData( rect, metrics, borderWidth, borderColor, gradient, {}, {} );
arcNode->setArcData( rect, metrics, borderWidth, borderColor, gradient );
return arcNode;
}

View File

@ -5,23 +5,17 @@
#include "QskArcNode.h"
#include "QskArcMetrics.h"
#include "QskArcShadowNode.h"
#include "QskArcRenderNode.h"
#include "QskArcRenderer.h"
#include "QskMargins.h"
#include "QskGradient.h"
#include "QskSGNode.h"
#include "QskShadowMetrics.h"
#include "QskRgbValue.h"
#include <qpainterpath.h>
namespace
{
enum NodeRole
{
ShadowRole,
/*
If possible border + filling will be displayed by ArcRole
Otherwise ArcRole displays the border and FillRole the filling
@ -34,7 +28,7 @@ namespace
static void qskUpdateChildren( QSGNode* parentNode, quint8 role, QSGNode* node )
{
static const QVector< quint8 > roles = { ShadowRole, ArcRole, FillRole };
static const QVector< quint8 > roles = { ArcRole, FillRole };
auto oldNode = QskSGNode::findChildNode( parentNode, role );
QskSGNode::replaceChildNode( roles, role, parentNode, oldNode, node );
@ -67,22 +61,14 @@ QskArcNode::~QskArcNode()
void QskArcNode::setArcData( const QRectF& rect,
const QskArcMetrics& arcMetrics, const QskGradient& gradient )
{
setArcData( rect, arcMetrics, 0.0, QColor(), gradient, {}, {} );
setArcData( rect, arcMetrics, 0.0, QColor(), gradient );
}
void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics,
const qreal borderWidth, const QColor& borderColor, const QskGradient& gradient )
{
setArcData( rect, arcMetrics, borderWidth, borderColor, gradient, {}, {} );
}
void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics,
const qreal borderWidth, const QColor& borderColor, const QskGradient& gradient,
const QColor& shadowColor, const QskShadowMetrics& shadowMetrics )
{
using namespace QskSGNode;
QskArcShadowNode* shadowNode = nullptr;
QskArcRenderNode* arcNode = nullptr;
QskArcRenderNode* fillNode = nullptr;
@ -93,26 +79,6 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
const auto hasFilling = gradient.isVisible();
const auto hasBorder = ( borderWidth > 0.0 ) && QskRgb::isVisible( borderColor );
const auto hasShadow = hasFilling && QskRgb::isVisible( shadowColor );
if ( hasShadow )
{
/*
The shader of the shadow node is for circular arcs and we have some
unwanted scaling issues for the spread/blur values when having ellipsoid
arcs. We might also want to add the spread value to the ends of the arc
and not only to its radius. TODO ...
*/
shadowNode = qskNode< QskArcShadowNode >( this, ShadowRole );
const auto sm = shadowMetrics.toAbsolute( rect.size() );
const auto shadowRect = sm.shadowRect( rect );
const auto spreadRadius = sm.spreadRadius() + 0.5 * metricsArc.thickness();
shadowNode->setShadowData( shadowRect, spreadRadius, sm.blurRadius(),
metricsArc.startAngle(), metricsArc.spanAngle(), shadowColor );
}
if ( hasBorder || hasFilling )
{
@ -142,7 +108,6 @@ void QskArcNode::setArcData( const QRectF& rect, const QskArcMetrics& arcMetrics
}
}
qskUpdateChildren( this, ShadowRole, shadowNode );
qskUpdateChildren( this, ArcRole, arcNode );
qskUpdateChildren( this, FillRole, fillNode );
}

View File

@ -11,7 +11,6 @@
class QskArcMetrics;
class QskGradient;
class QskShadowMetrics;
class QSK_EXPORT QskArcNode : public QSGNode
{
@ -23,10 +22,6 @@ class QSK_EXPORT QskArcNode : public QSGNode
void setArcData( const QRectF&, const QskArcMetrics&,
qreal borderWidth, const QColor& borderColor, const QskGradient& );
void setArcData( const QRectF&, const QskArcMetrics&,
qreal borderWidth, const QColor& borderColor, const QskGradient&,
const QColor& shadowColor, const QskShadowMetrics&);
};
#endif

View File

@ -2,9 +2,6 @@
<RCC version="1.0">
<qresource prefix="/qskinny/">
<file>shaders/arcshadow.vert</file>
<file>shaders/arcshadow.frag</file>
<file>shaders/boxshadow.vert</file>
<file>shaders/boxshadow.frag</file>