Using our own gradient shaders ( no dependencies from quickshapes

anymore ). shapes/Gradient has not yet been merged into QskGradient
and we still have some stupid conversions to QGradient in the way.
This commit is contained in:
Uwe Rathmann 2022-10-13 19:39:57 +02:00
parent 929c02fa0e
commit 51a7e4e589
33 changed files with 684 additions and 398 deletions

View File

@ -8,8 +8,8 @@
Gradient::Gradient( const Gradient& other ) noexcept
: m_stops( other.m_stops )
, m_values{ other.m_values[0], other.m_values[1], other.m_values[2],
other.m_values[3], other.m_values[4], other.m_values[5] }
, m_values{ other.m_values[0], other.m_values[1],
other.m_values[2], other.m_values[3], }
, m_type( other.m_type )
, m_spread( other.m_spread )
{
@ -25,8 +25,6 @@ Gradient& Gradient::operator=( const Gradient& other ) noexcept
m_values[1] = other.m_values[1];
m_values[2] = other.m_values[2];
m_values[3] = other.m_values[3];
m_values[4] = other.m_values[4];
m_values[5] = other.m_values[5];
return *this;
}
@ -46,8 +44,6 @@ bool Gradient::operator==( const Gradient& other ) const noexcept
&& ( m_values[1] == other.m_values[1] )
&& ( m_values[2] == other.m_values[2] )
&& ( m_values[3] == other.m_values[3] )
&& ( m_values[4] == other.m_values[4] )
&& ( m_values[5] == other.m_values[5] )
&& ( m_stops == other.m_stops );
}
@ -223,28 +219,11 @@ void RadialGradient::setCenter( qreal x, qreal y ) noexcept
m_values[1] = y;
}
void RadialGradient::setFocalPoint( const QPointF& focalPoint ) noexcept
{
m_values[3] = focalPoint.x();
m_values[4] = focalPoint.y();
}
void RadialGradient::setFocalPoint( qreal x, qreal y ) noexcept
{
m_values[3] = x;
m_values[4] = y;
}
void RadialGradient::setCenterRadius( qreal radius ) noexcept
void RadialGradient::setRadius( qreal radius ) noexcept
{
m_values[2] = radius;
}
void RadialGradient::setFocalRadius( qreal radius ) noexcept
{
m_values[5] = radius;
}
void ConicGradient::setCenter( const QPointF& center ) noexcept
{
m_values[0] = center.x();
@ -257,7 +236,12 @@ void ConicGradient::setCenter( qreal x, qreal y ) noexcept
m_values[1] = y;
}
void ConicGradient::setDegrees( qreal degrees ) noexcept
void ConicGradient::setStartAngle( qreal degrees ) noexcept
{
m_values[2] = degrees;
}
void ConicGradient::setSpanAngle( qreal degrees ) noexcept
{
m_values[3] = qBound( -360.0, degrees, 360.0 );
}

View File

@ -37,8 +37,8 @@ class Gradient
bool isMonochrome() const;
bool isVisible() const;
void setStops( const QVector< QskGradientStop >& );
const QVector< QskGradientStop >& stops() const noexcept;
void setStops( const QskGradientStops& );
const QskGradientStops& stops() const noexcept;
void setStops( QGradient::Preset );
void setStops( const QGradientStops& );
@ -63,22 +63,28 @@ class Gradient
friend class ConicGradient;
Gradient( QGradient::Type ) noexcept;
Gradient( QGradient::Type,
qreal, qreal, qreal, qreal, qreal, qreal ) noexcept;
Gradient( QGradient::Type, qreal, qreal, qreal, qreal ) noexcept;
QVector< QskGradientStop > m_stops;
QskGradientStops m_stops;
/*
Linear: x1, y1, x2, y2, n/a, n/a
Radial: centerX, centerY, centerRadius, focalX, focalY, focalRadius
Conic: centerX, centerY, degrees, n/a, n/a, n/a
Linear: x1, y1, x2, y2
Radial: centerX, centerY, radius, n/a
Conic: centerX, centerY, startAngle, spanAngle
*/
qreal m_values[6] = {};
qreal m_values[4] = {};
QGradient::Type m_type = QGradient::NoGradient;
QGradient::Spread m_spread = QGradient::PadSpread;
};
#ifndef QT_NO_DEBUG_STREAM
class QDebug;
QDebug operator<<( QDebug, const QskGradient& );
#endif
class LinearGradient : public Gradient
{
public:
@ -96,13 +102,6 @@ class LinearGradient : public Gradient
QPointF stop() const noexcept;
};
#ifndef QT_NO_DEBUG_STREAM
class QDebug;
QDebug operator<<( QDebug, const Gradient& );
#endif
class RadialGradient : public Gradient
{
public:
@ -111,40 +110,34 @@ class RadialGradient : public Gradient
RadialGradient( const QPointF& center, qreal radius ) noexcept;
RadialGradient( qreal cx, qreal cy, qreal radius ) noexcept;
RadialGradient( const QPointF& center, qreal centerRadius,
const QPointF& focalPoint, qreal focalRadius = 0.0 ) noexcept;
RadialGradient(qreal cx, qreal cy, qreal centerRadius,
qreal fx, qreal fy, qreal focalRadius = 0.0 ) noexcept;
QPointF center() const noexcept;
void setCenter(const QPointF& center) noexcept;
void setCenter(qreal x, qreal y) noexcept;
QPointF focalPoint() const noexcept;
void setFocalPoint( const QPointF& focalPoint ) noexcept;
void setFocalPoint( qreal x, qreal y ) noexcept;
qreal centerRadius() const noexcept;
void setCenterRadius( qreal radius ) noexcept;
qreal focalRadius() const noexcept;
void setFocalRadius( qreal radius ) noexcept;
qreal radius() const noexcept;
void setRadius( qreal radius ) noexcept;
};
class ConicGradient : public Gradient
{
public:
ConicGradient() noexcept;
ConicGradient( const QPointF&, qreal degrees ) noexcept;
ConicGradient( qreal cx, qreal cy, qreal degrees ) noexcept;
ConicGradient( const QPointF&,
qreal startAngle = 0.0, qreal spanAngle = 360.0 ) noexcept;
ConicGradient( qreal cx, qreal cy,
qreal startAngle = 0.0, qreal spanAngle = 360.0 ) noexcept;
QPointF center() const noexcept;
void setCenter(const QPointF& center) noexcept;
void setCenter(qreal x, qreal y) noexcept;
qreal degrees() const noexcept;
void setDegrees(qreal ) noexcept;
qreal startAngle() const noexcept;
void setStartAngle( qreal ) noexcept;
qreal spanAngle() const noexcept;
void setSpanAngle( qreal ) noexcept;
};
inline Gradient::Gradient( QGradient::Type type ) noexcept
@ -153,9 +146,8 @@ inline Gradient::Gradient( QGradient::Type type ) noexcept
}
inline Gradient::Gradient( QGradient::Type type,
qreal v1, qreal v2, qreal v3,
qreal v4 = 0.0, qreal v5 = 0.0, qreal v6 = 0.0 ) noexcept
: m_values{ v1, v2, v3, v4, v5, v6 }
qreal v1, qreal v2, qreal v3, qreal v4 ) noexcept
: m_values{ v1, v2, v3, v4 }
, m_type( type )
{
}
@ -175,7 +167,7 @@ inline bool Gradient::isValid() const noexcept
return m_type != QGradient::NoGradient;
}
inline const QVector< QskGradientStop >& Gradient::stops() const noexcept
inline const QskGradientStops& Gradient::stops() const noexcept
{
return m_stops;
}
@ -213,15 +205,7 @@ inline QPointF LinearGradient::stop() const noexcept
}
inline RadialGradient::RadialGradient() noexcept
: Gradient( QGradient::RadialGradient, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 )
{
}
inline RadialGradient::RadialGradient(
const QPointF& center, qreal radius,
const QPointF& focalPoint, qreal focalRadius ) noexcept
: RadialGradient( center.x(), center.y(), radius,
focalPoint.x(), focalPoint.y(), focalRadius )
: Gradient( QGradient::RadialGradient, 0.5, 0.5, 0.5, 0.0 )
{
}
@ -233,14 +217,7 @@ inline RadialGradient::RadialGradient(
inline RadialGradient::RadialGradient(
qreal cx, qreal cy, qreal radius ) noexcept
: RadialGradient( cx, cy, radius, cx, cy, 0.0 )
{
}
inline RadialGradient::RadialGradient(
qreal cx, qreal cy, qreal radius,
qreal fx, qreal fy, qreal focalRadius ) noexcept
: Gradient( QGradient::RadialGradient, cx, cy, radius, fx, fy, focalRadius )
: Gradient( QGradient::RadialGradient, cx, cy, radius, 0.0 )
{
}
@ -249,35 +226,25 @@ inline QPointF RadialGradient::center() const noexcept
return QPointF( m_values[0], m_values[1] );
}
inline qreal RadialGradient::centerRadius() const noexcept
inline qreal RadialGradient::radius() const noexcept
{
return m_values[2];
}
inline QPointF RadialGradient::focalPoint() const noexcept
{
return QPointF( m_values[3], m_values[4] );
}
inline qreal RadialGradient::focalRadius() const noexcept
{
return m_values[5];
}
inline ConicGradient::ConicGradient() noexcept
: Gradient( QGradient::ConicalGradient, 0.0, 0.0, 0.0 )
: Gradient( QGradient::ConicalGradient, 0.0, 0.0, 0.0, 0.0 )
{
}
inline ConicGradient::ConicGradient(
const QPointF& center, qreal degrees ) noexcept
: ConicGradient( center.x(), center.y(), degrees )
const QPointF& center, qreal startAngle, qreal spanAngle ) noexcept
: ConicGradient( center.x(), center.y(), startAngle, spanAngle )
{
}
inline ConicGradient::ConicGradient(
qreal cx, qreal cy, qreal degrees ) noexcept
: Gradient( QGradient::ConicalGradient, cx, cy, degrees )
qreal cx, qreal cy, qreal startAngle, qreal spanAngle ) noexcept
: Gradient( QGradient::ConicalGradient, cx, cy, startAngle, spanAngle )
{
}
@ -286,7 +253,12 @@ inline QPointF ConicGradient::center() const noexcept
return QPointF( m_values[0], m_values[1] );
}
inline qreal ConicGradient::degrees() const noexcept
inline qreal ConicGradient::startAngle() const noexcept
{
return m_values[2];
}
inline qreal ConicGradient::spanAngle() const noexcept
{
return m_values[3];
}

View File

@ -67,20 +67,11 @@ namespace
{
const auto& g = gradient.asLinearGradient();
const qreal x1 = rect.left() + g.start().x() * rect.width();
const qreal y1 = rect.top() + g.start().y() * rect.height();
const qreal x2 = rect.left() + g.stop().x() * rect.width();
const qreal y2 = rect.top() + g.stop().y() * rect.height();
#if 0
QTransform t2( rect.width(), 0, 0, rect.height(), rect.x(), rect.y());
#endif
QLinearGradient qgradient( x1, y1, x2, y2 );
QLinearGradient qgradient( g.start(), g.stop() );
qgradient.setSpread( g.spread() );
qgradient.setStops( g.qtStops() );
updateNode( path, transform, &qgradient );
updateNode( path, transform, rect, &qgradient );
break;
}
@ -88,19 +79,11 @@ namespace
{
const auto& g = gradient.asRadialGradient();
const qreal x = rect.left() + g.center().x() * rect.width();
const qreal y = rect.top() + g.center().y() * rect.height();
const qreal r = g.centerRadius() * qMin( rect.width(), rect.height() );
const qreal fx = rect.left() + g.focalPoint().x() * rect.width();
const qreal fy = rect.top() + g.focalPoint().y() * rect.height();
const qreal fr = g.focalRadius() * qMin( rect.width(), rect.height() );
QRadialGradient qgradient( x, y, r, fx, fy, fr );
QRadialGradient qgradient( g.center(), g.radius() );
qgradient.setSpread( g.spread() );
qgradient.setStops( g.qtStops() );
updateNode( path, transform, &qgradient );
updateNode( path, transform, rect, &qgradient );
break;
}
@ -108,14 +91,16 @@ namespace
{
const auto& g = gradient.asConicGradient();
const qreal x = rect.left() + g.center().x() * rect.width();
const qreal y = rect.top() + g.center().y() * rect.height();
QConicalGradient qgradient( x, y, g.degrees() );
//qgradient.setSpread( g.spread() );
QConicalGradient qgradient( g.center(), g.startAngle() );
qgradient.setSpread( g.spread() );
qgradient.setStops( g.qtStops() );
updateNode( path, transform, &qgradient );
/*
Once ConicGradient has become QskConicGradient we do not
need QConicalGradient anymore and passing the spanAngle
as extra parameter can go away.
*/
updateNode( path, transform, rect, &qgradient, g.spanAngle() );
break;
}

View File

@ -4,57 +4,64 @@
*****************************************************************************/
#include "ShapeItem.h"
#include "Gradient.h"
#include <QskObjectCounter.h>
#include <QskWindow.h>
#include <QskRgbValue.h>
#include <QskLinearBox.h>
#include <QskTabView.h>
#include <SkinnyShortcut.h>
#include <SkinnyShapeFactory.h>
#include <QGuiApplication>
#include <QBrush>
namespace
{
QPainterPath path( SkinnyShapeFactory::Shape shape )
class Page : public QskLinearBox
{
public:
Page( QQuickItem* parent = nullptr )
: QskLinearBox( Qt::Horizontal, 2, parent )
{
}
protected:
static QPen pen( const QColor& color )
{
QPen p( color );
#if 0
p.setCosmetic( true );
#endif
p.setWidth( p.isCosmetic() ? 8 : 2 );
p.setJoinStyle( Qt::MiterJoin );
#if 0
p.setStyle( Qt::DashLine );
p.setColor( QskRgb::toTransparent( color(), alpha ) );
#endif
return p;
}
static QPainterPath path( SkinnyShapeFactory::Shape shape )
{
return SkinnyShapeFactory::shapePath( shape, QSizeF( 50, 50 ) );
}
class Pen : public QPen
{
public:
Pen( const QColor& color )
: QPen( color )
{
//setCosmetic( true );
setWidth( isCosmetic() ? 8 : 2 );
setJoinStyle( Qt::MiterJoin );
//setStyle( Qt::NoPen );
//setStyle( Qt::DashLine );
//setAlpha( 100 );
}
void setAlpha( int alpha )
{
setColor( QskRgb::toTransparent( color(), alpha ) );
}
};
class Box : public QskLinearBox
class LinearGradientPage : public Page
{
public:
Box( QQuickItem* parent = nullptr )
: QskLinearBox( Qt::Horizontal, 2, parent )
LinearGradientPage( QQuickItem* parent = nullptr )
: Page( parent )
{
{
auto shapeItem = new ShapeItem( this );
shapeItem->setPath( path( SkinnyShapeFactory::Hexagon ) );
shapeItem->setPen( Pen( QColorConstants::Svg::indigo ) );
shapeItem->setPen( pen( QColorConstants::Svg::indigo ) );
LinearGradient gradient( 0.0, 0.0, 0.2, 0.5 );
gradient.setSpread( QGradient::ReflectSpread );
@ -62,14 +69,36 @@ namespace
shapeItem->setGradient( gradient );
}
}
};
class RadialGradientPage : public Page
{
public:
RadialGradientPage( QQuickItem* parent = nullptr )
: Page( parent )
{
{
auto shapeItem = new ShapeItem( this );
shapeItem->setPath( path( SkinnyShapeFactory::Rectangle ) );
shapeItem->setPen( pen( QColorConstants::Svg::indigo ) );
RadialGradient gradient( 0.5, 0.5, 0.5 );
gradient.setSpread( QGradient::PadSpread );
gradient.setStops( QColorConstants::Svg::lightyellow,
QColorConstants::Svg::midnightblue );
shapeItem->setGradient( gradient );
}
{
auto shapeItem = new ShapeItem( this );
shapeItem->setPath( path( SkinnyShapeFactory::Ellipse ) );
RadialGradient gradient( 0.5, 0.5, 0.5 );
gradient.setSpread( QGradient::RepeatSpread );
gradient.setSpread( QGradient::PadSpread );
QVector< QskGradientStop > stops;
@ -88,29 +117,101 @@ namespace
shapeItem->setGradient( gradient );
}
{
auto shapeItem = new ShapeItem( this );
shapeItem->setPath( path( SkinnyShapeFactory::Arc ) );
shapeItem->setPath( path( SkinnyShapeFactory::Rectangle ) );
shapeItem->setPen( pen( QColorConstants::Svg::indigo ) );
ConicGradient gradient( 0.5, 0.5, -60.0 );
gradient.setStops( QGradient::BurningSpring );
RadialGradient gradient( 0.5, 0.5, 0.25 );
gradient.setCenter( 0.5, 0.7 );
gradient.setSpread( QGradient::RepeatSpread );
gradient.setStops( QGradient::LilyMeadow );
shapeItem->setGradient( gradient );
}
{
auto shapeItem = new ShapeItem( this );
shapeItem->setPath( path( SkinnyShapeFactory::Rectangle ) );
shapeItem->setPen( pen( QColorConstants::Svg::indigo ) );
RadialGradient gradient( 0.6, 0.4, 0.1 );
gradient.setSpread( QGradient::ReflectSpread );
gradient.setStops( Qt::red, Qt::blue );
shapeItem->setGradient( gradient );
}
}
};
class ConicGradientPage : public Page
{
public:
ConicGradientPage( QQuickItem* parent = nullptr )
: Page( parent )
{
{
auto shapeItem = new ShapeItem( this );
shapeItem->setPath( path( SkinnyShapeFactory::Ellipse ) );
RadialGradient gradient( 0.5, 0.5, 0.5 );
gradient.setSpread( QGradient::RepeatSpread );
gradient.setStops( QGradient::DirtyBeauty );
ConicGradient gradient( 0.5, 0.5, 30.0, 60.0 );
gradient.setSpread( QGradient::ReflectSpread );
gradient.setStops( QGradient::JuicyPeach );
shapeItem->setGradient( gradient );
}
{
auto shapeItem = new ShapeItem( this );
shapeItem->setPath( path( SkinnyShapeFactory::TriangleUp ) );
ConicGradient gradient( 0.5, 0.5, 30.0, 60.0 );
gradient.setSpread( QGradient::RepeatSpread );
gradient.setStops( QGradient::WinterNeva );
shapeItem->setGradient( gradient );
}
{
auto shapeItem = new ShapeItem( this );
shapeItem->setPath( path( SkinnyShapeFactory::Arc ) );
ConicGradient gradient( 0.5, 0.5, 300.0, -240.0 );
gradient.setStops( QGradient::SpikyNaga );
shapeItem->setGradient( gradient );
}
{
auto shapeItem = new ShapeItem( this );
shapeItem->setPath( path( SkinnyShapeFactory::Diamond ) );
ConicGradient gradient( 0.5, 0.5, 45.0, 180.0 );
gradient.setStops( QGradient::FabledSunset );
gradient.setSpread( QGradient::ReflectSpread );
shapeItem->setGradient( gradient );
}
}
};
class TabView : public QskTabView
{
public:
TabView( QQuickItem* parentItem = nullptr )
: QskTabView( parentItem )
{
setMargins( 10 );
setAutoFitTabs( true );
setTabBarEdge( Qt::TopEdge );
addTab( "Radial Gradients", new RadialGradientPage() );
addTab( "Conic Gradients", new ConicGradientPage() );
addTab( "Linear Gradients", new LinearGradientPage() );
}
};
}
@ -127,7 +228,7 @@ int main( int argc, char* argv[] )
QskWindow window;
window.setColor( Qt::gray );
window.addItem( new Box() );
window.addItem( new TabView() );
window.resize( 800, 600 );
window.show();

View File

@ -1,13 +1,22 @@
/******************************************************************************
* QSkinny - Copyright (C) 2016 Uwe Rathmann
* This file may be used under the terms of the QSkinny License, Version 1.0
*****************************************************************************/
#include "QskGradientMaterial.h"
#include "QskFunctions.h"
#include "QskRgbValue.h"
#include <qcoreapplication.h>
QSK_QT_PRIVATE_BEGIN
#include <private/qrhi_p.h>
#include <private/qdrawhelper_p.h>
#include <private/qsgplaintexture_p.h>
QSK_QT_PRIVATE_END
#include <cmath>
// RHI shaders are supported by Qt 5.15 and Qt 6.x
#define SHADER_RHI
@ -23,106 +32,33 @@ QSK_QT_PRIVATE_END
using RhiShader = QSGMaterialShader;
#endif
/*
The shaders for the gradient are implemented in the quickshapes module
Beside them we do not need this module.
*/
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
QSK_QT_PRIVATE_BEGIN
#ifndef signals
#define signals Q_SIGNALS
#endif
#include <private/qquickshape_p.h>
QSK_QT_PRIVATE_END
static void QQuickShapes_initializeModule()
{
QQuickShapesModule::defineModule();
}
#else
extern void QQuickShapes_initializeModule();
#endif
Q_CONSTRUCTOR_FUNCTION( QQuickShapes_initializeModule )
namespace
{
/*
Qt offers QGradient compatible shaders in the quickshapes module.
So why reimplementing the wheel ...
Those shaders ( f.e lineargradient.frag ) want to have a lookup table
with the interpolated colors, being uploaded as a texture.
A 1 dimensional 256x1 texture is how Chrome, Firefox, and Android render
gradients - so let's do the same.
*/
class GradientImage : public QImage
{
public:
GradientImage( const QGradientStops& stops )
: QImage( 256, 1, QImage::Format_RGBA8888_Premultiplied )
{
constexpr int numColors = 256;
auto colorTable = reinterpret_cast< uint* >( bits() );
int index1, index2;
QRgb rgb1, rgb2;
index1 = index2 = qRound( stops[0].first * numColors );
rgb1 = rgb2 = stops[0].second.rgba();
if ( index1 > 0 )
{
const auto v = value( rgb1 );
for ( int i = 0; i < index1; i++ )
colorTable[i] = v;
}
for ( int i = 1; i < stops.count(); i++ )
{
const auto& stop = stops[i];
index2 = qRound( stop.first * numColors );
rgb2 = stop.second.rgba();
const auto n = index2 - index1;
for ( int j = 0; j < n; j++ )
{
const auto rgb = QskRgb::interpolated( rgb1, rgb2, qreal( j ) / n );
colorTable[ index1 + j] = value( rgb );
}
index1 = index2;
rgb1 = rgb2;
}
if ( index1 < numColors - 1 )
{
const auto v = value( rgb1 );
for ( int i = index1; i < numColors ; i++ )
colorTable[i] = v;
}
}
private:
inline uint value( const QRgb rgb ) const
{
return ARGB2RGBA( qPremultiply( rgb ) );
}
};
class GradientTexture : public QSGPlainTexture
{
public:
GradientTexture( const QGradientStops& stops, QGradient::Spread spread )
{
setImage( GradientImage( stops ) );
#if 1
/*
Once we got rid of QGradient we will have QskGradientStops
( like in the gradients branch ). For the moment we have to copy
*/
QskGradientStops qskStops;
qskStops.reserve( stops.size() );
for ( const auto& s : stops )
qskStops += QskGradientStop( s.first, s.second );
#endif
/*
Qt creates tables of 1024 colors, while Chrome, Firefox, and Android
seem to use 256 colors only ( according to maybe outdated sources
from the internet ),
*/
setImage( QskRgb::colorTable( 256, qskStops ) );
const auto wrapMode = this->wrapMode( spread );
@ -183,10 +119,9 @@ namespace
s_instance = new TextureCache();
/*
For OpenGL we coud fiddle around with QOpenGLSharedResource
while with RHI we would have QRhi::addCleanupCallback
But let's keep things simple for the moment. TODO ...
For RHI we have QRhi::addCleanupCallback, but with
OpenGL we have to fiddle around with QOpenGLSharedResource
So let's keep things simple for the moment. TODO ...
*/
qAddPostRoutine( cleanup );
}
@ -209,6 +144,17 @@ namespace
{
texture = new GradientTexture( stops, spread );
m_hashTable[ key ] = texture;
if ( rhi != nullptr )
{
auto myrhi = ( QRhi* )rhi;
if ( !m_rhiTable.contains( myrhi ) )
{
myrhi->addCleanupCallback( TextureCache::cleanupRhi );
m_rhiTable += myrhi;
}
}
}
return texture;
@ -220,7 +166,29 @@ namespace
delete instance();
}
static void cleanupRhi( const QRhi *rhi )
{
auto cache = instance();
auto& table = cache->m_hashTable;
for ( auto it = table.begin(); it != table.end(); )
{
if ( it.key().rhi == rhi )
{
delete it.value();
it = table.erase( it );
}
else
{
++it;
}
}
cache->m_rhiTable.removeAll( rhi );
}
QHash< TextureHashKey, GradientTexture* > m_hashTable;
QVector< const QRhi* > m_rhiTable;
};
}
@ -269,7 +237,7 @@ namespace
public:
void setShaderFiles( const char* name )
{
static const QString root( ":/qt-project.org/shapes/shaders/" );
static const QString root( ":/qskinny/shaders/" );
setShaderSourceFile( QOpenGLShader::Vertex, root + name + ".vert" );
setShaderSourceFile( QOpenGLShader::Fragment, root + name + ".frag" );
@ -320,7 +288,7 @@ namespace
public:
void setShaderFiles( const char* name )
{
static const QString root( ":/qt-project.org/shapes/shaders_ng/" );
static const QString root( ":/qskinny/shaders/" );
setShaderFileName( VertexStage, root + name + ".vert.qsb" );
setShaderFileName( FragmentStage, root + name + ".frag.qsb" );
@ -359,29 +327,35 @@ namespace
{
}
bool setGradient( const QLinearGradient* gradient )
bool setGradient( const QRectF& rect, const QLinearGradient& gradient )
{
bool changed = false;
if ( gradient->stops() != stops() )
if ( gradient.stops() != stops() )
{
setStops( gradient->stops() );
setStops( gradient.stops() );
changed = true;
}
if ( gradient->spread() != spread() )
if ( gradient.spread() != spread() )
{
setSpread( gradient->spread() );
setSpread( gradient.spread() );
changed = true;
}
const QVector2D start( gradient->start() );
const QVector2D stop( gradient->finalStop() );
#if 0
QTransform transform( rect.width(), 0, 0, rect.height(), rect.x(), rect.y());
#endif
if ( m_start != start || m_stop != stop )
const QVector4D gradientRect(
rect.left() + gradient.start().x() * rect.width(),
rect.top() + gradient.start().y() * rect.height(),
gradient.finalStop().x() * rect.width(),
gradient.finalStop().y() * rect.height() );
if ( m_gradientRect != gradientRect )
{
m_start = start;
m_stop = stop;
m_gradientRect = gradientRect;
changed = true;
}
@ -398,7 +372,7 @@ namespace
{
const auto mat = static_cast< const LinearMaterial* >( other );
if ( ( m_start != mat->m_start ) || ( m_stop != mat->m_stop ) )
if ( m_gradientRect != mat->m_gradientRect )
return QSGMaterial::compare( other );
else
return GradientMaterial::compare( other );
@ -406,8 +380,7 @@ namespace
QSGMaterialShader* createShader() const override;
QVector2D m_start;
QVector2D m_stop;
QVector4D m_gradientRect;
};
#ifdef SHADER_GL
@ -416,28 +389,23 @@ namespace
public:
LinearShaderGL()
{
setShaderFiles( "lineargradient" );
setShaderFiles( "gradientlinear" );
}
void initialize() override
{
GradientShaderGL::initialize();
m_startId = program()->uniformLocation( "gradStart" );
m_stopId = program()->uniformLocation( "gradEnd" );
m_rectId = program()->uniformLocation( "rect" );
}
void updateUniformValues( const GradientMaterial* newMaterial ) override
{
auto material = static_cast< const LinearMaterial* >( newMaterial );
program()->setUniformValue( m_startId, material->m_start );
program()->setUniformValue( m_stopId, material->m_stop );
program()->setUniformValue( m_rectId, material->m_gradientRect );
}
private:
int m_startId = -1;
int m_stopId = -1;
int m_rectId = -1;
};
#endif
@ -447,7 +415,7 @@ namespace
public:
LinearShaderRhi()
{
setShaderFiles( "lineargradient" );
setShaderFiles( "gradientlinear" );
}
bool updateUniformData( RenderState& state,
@ -469,15 +437,9 @@ namespace
changed = true;
}
if ( matOld == nullptr || matNew->m_start != matOld->m_start )
if ( matOld == nullptr || matNew->m_gradientRect != matOld->m_gradientRect )
{
memcpy( data + 64, &matNew->m_start, 8 );
changed = true;
}
if ( matOld == nullptr || matNew->m_stop != matOld->m_stop )
{
memcpy( data + 72, &matNew->m_stop, 8 );
memcpy( data + 64, &matNew->m_gradientRect, 16 );
changed = true;
}
@ -520,40 +482,35 @@ namespace
return &type;
}
bool setGradient( const QRadialGradient* gradient )
bool setGradient( const QRectF& rect, const QRadialGradient& gradient )
{
bool changed = false;
if ( gradient->stops() != stops() )
if ( gradient.stops() != stops() )
{
setStops( gradient->stops() );
setStops( gradient.stops() );
changed = true;
}
if ( gradient->spread() != spread() )
if ( gradient.spread() != spread() )
{
setSpread( gradient->spread() );
setSpread( gradient.spread() );
changed = true;
}
const QVector2D focalToCenter( gradient->center() - gradient->focalPoint() );
const float centerRadius = gradient->centerRadius();
const auto& center = gradient.center();
const auto r = gradient.radius();
const QVector2D focalPoint( gradient->focalPoint() );
const float focalRadius = gradient->focalRadius();
const QVector2D pos(
rect.left() + center.x() * rect.width(),
rect.top() + center.y() * rect.height() );
if ( ( focalPoint != m_focalPoint ) || ( focalRadius != m_focalRadius ) )
const QVector2D radius( r * rect.width(), r * rect.height() );
if ( ( pos != m_center ) || ( m_radius != radius ) )
{
m_focalPoint = focalPoint;
m_focalRadius = focalRadius;
changed = true;
}
if ( ( focalToCenter != m_focalToCenter ) || ( m_centerRadius != centerRadius ) )
{
m_focalToCenter = focalToCenter;
m_centerRadius = centerRadius;
m_center = pos;
m_radius = radius;
changed = true;
}
@ -565,10 +522,7 @@ namespace
{
const auto mat = static_cast< const RadialMaterial* >( other );
if ( ( m_focalPoint != mat->m_focalPoint )
|| ( m_focalToCenter != mat->m_focalToCenter )
|| qskFuzzyCompare( m_centerRadius, mat->m_centerRadius )
|| qskFuzzyCompare( m_focalRadius, mat->m_focalRadius ) )
if ( ( m_center != mat->m_center ) || ( m_radius != mat->m_radius ) )
{
return QSGMaterial::compare( other );
}
@ -580,10 +534,8 @@ namespace
QSGMaterialShader* createShader() const override;
QVector2D m_focalPoint;
QVector2D m_focalToCenter;
float m_centerRadius = 0.0;
float m_focalRadius = 0.0;
QVector2D m_center;
QVector2D m_radius;
};
#ifdef SHADER_GL
@ -592,7 +544,7 @@ namespace
public:
RadialShaderGL()
{
setShaderFiles( "radialgradient" );
setShaderFiles( "gradientradial" );
}
void initialize() override
@ -601,10 +553,8 @@ namespace
auto p = program();
m_focalPointId = p->uniformLocation( "translationPoint" );
m_focalToCenterId = p->uniformLocation( "focalToCenter" );
m_centerRadiusId = p->uniformLocation( "centerRadius" );
m_focalRadiusId = p->uniformLocation( "focalRadius" );
m_centerCoordId = p->uniformLocation( "centerCoord" );
m_radiusId = p->uniformLocation( "radius" );
}
void updateUniformValues( const GradientMaterial* newMaterial ) override
@ -613,17 +563,13 @@ namespace
auto p = program();
p->setUniformValue( m_focalToCenterId, material->m_focalToCenter );
p->setUniformValue( m_centerRadiusId, material->m_centerRadius);
p->setUniformValue( m_focalRadiusId, material->m_focalRadius);
p->setUniformValue( m_focalPointId, material->m_focalPoint);
p->setUniformValue( m_centerCoordId, material->m_center );
p->setUniformValue( m_radiusId, material->m_radius );
}
private:
int m_focalToCenterId = -1;
int m_focalPointId = -1;
int m_centerRadiusId = -1;
int m_focalRadiusId = -1;
int m_centerCoordId = -1;
int m_radiusId = -1;
};
#endif
@ -633,7 +579,7 @@ namespace
public:
RadialShaderRhi()
{
setShaderFiles( "radialgradient" );
setShaderFiles( "gradientradial" );
}
bool updateUniformData( RenderState& state,
@ -642,7 +588,7 @@ namespace
auto matNew = static_cast< RadialMaterial* >( newMaterial );
auto matOld = static_cast< RadialMaterial* >( oldMaterial );
Q_ASSERT( state.uniformData()->size() >= 92 );
Q_ASSERT( state.uniformData()->size() >= 84 );
auto data = state.uniformData()->data();
bool changed = false;
@ -655,34 +601,22 @@ namespace
changed = true;
}
if ( matOld == nullptr || matNew->m_focalPoint != matOld->m_focalPoint )
if ( matOld == nullptr || matNew->m_center != matOld->m_center )
{
memcpy( data + 64, &matNew->m_focalPoint, 8 );
memcpy( data + 64, &matNew->m_center, 8 );
changed = true;
}
if ( matOld == nullptr || matNew->m_focalToCenter != matOld->m_focalToCenter )
if ( matOld == nullptr || matNew->m_radius != matOld->m_radius )
{
memcpy( data + 72, &matNew->m_focalToCenter, 8 );
changed = true;
}
if ( matOld == nullptr || matNew->m_centerRadius != matOld->m_centerRadius )
{
memcpy( data + 80, &matNew->m_centerRadius, 4);
changed = true;
}
if ( matOld == nullptr || matNew->m_focalRadius != matOld->m_focalRadius )
{
memcpy( data + 84, &matNew->m_focalRadius, 4 );
memcpy( data + 72, &matNew->m_radius, 8 );
changed = true;
}
if ( state.isOpacityDirty() )
{
const float opacity = state.opacity();
memcpy( data + 88, &opacity, 4 );
memcpy( data + 80, &opacity, 4 );
changed = true;
}
@ -719,23 +653,44 @@ namespace
return &type;
}
bool setGradient( const QConicalGradient* gradient )
bool setGradient( const QRectF& rect, const QConicalGradient& gradient, qreal spanAngle )
{
bool changed = false;
if ( gradient->stops() != stops() )
if ( gradient.stops() != stops() )
{
setStops( gradient->stops() );
setStops( gradient.stops() );
changed = true;
}
const QVector2D center( gradient->center() );
const float radians = -qDegreesToRadians( gradient->angle() );
if ( gradient.spread() != spread() )
{
setSpread( gradient.spread() );
changed = true;
}
if ( center != m_center || radians != m_radians )
const QVector2D center(
rect.left() + gradient.center().x() * rect.width(),
rect.top() + gradient.center().y() * rect.height() );
// Angles as ratio of a rotation
float start = fmod( gradient.angle(), 360.0 ) / 360.0;
if ( start < 0.0)
start += 1.0;
const float span = fmod( spanAngle, 360.0 ) / 360.0;
if ( center != m_center )
{
m_center = center;
m_radians = radians;
changed = true;
}
if ( ( start != m_start ) || ( span != m_span ) )
{
m_start = start;
m_span = span;
changed = true;
}
@ -747,16 +702,21 @@ namespace
{
const auto mat = static_cast< const ConicMaterial* >( other );
if ( ( m_center != mat->m_center ) || qskFuzzyCompare( m_radians, mat->m_radians ) )
if ( ( m_center != mat->m_center )
|| qskFuzzyCompare( m_start, mat->m_start )
|| qskFuzzyCompare( m_span, mat->m_span ) )
{
return QSGMaterial::compare( other );
else
}
return GradientMaterial::compare( other );
}
QSGMaterialShader* createShader() const override;
QVector2D m_center;
float m_radians = 0.0;
float m_start = 0.0;
float m_span = 1.0;
};
#ifdef SHADER_GL
@ -765,28 +725,31 @@ namespace
public:
ConicShaderGL()
{
setShaderFiles( "conicalgradient" );
setShaderFiles( "gradientconic" );
}
void initialize() override
{
GradientShaderGL::initialize();
m_radiansId = program()->uniformLocation( "angle" );
m_centerPointId = program()->uniformLocation( "translationPoint" );
m_centerCoordId = program()->uniformLocation( "centerCoord" );
m_startId = program()->uniformLocation( "start" );
m_spanId = program()->uniformLocation( "span" );
}
void updateUniformValues( const GradientMaterial* newMaterial ) override
{
auto material = static_cast< const ConicMaterial* >( newMaterial );
program()->setUniformValue( m_radiansId, material->m_radians );
program()->setUniformValue( m_centerPointId, material->m_center );
program()->setUniformValue( m_centerCoordId, material->m_center );
program()->setUniformValue( m_startId, material->m_start );
program()->setUniformValue( m_spanId, material->m_span );
}
private:
int m_radiansId = -1;
int m_centerPointId = -1;
int m_centerCoordId = -1;
int m_startId = -1;
int m_spanId = -1;
};
#endif
@ -796,7 +759,7 @@ namespace
public:
ConicShaderRhi()
{
setShaderFiles( "conicalgradient" );
setShaderFiles( "gradientconic" );
}
bool updateUniformData( RenderState& state,
@ -805,7 +768,7 @@ namespace
auto matNew = static_cast< ConicMaterial* >( newMaterial );
auto matOld = static_cast< ConicMaterial* >( oldMaterial );
Q_ASSERT( state.uniformData()->size() >= 80 );
Q_ASSERT( state.uniformData()->size() >= 84 );
auto data = state.uniformData()->data();
bool changed = false;
@ -824,16 +787,22 @@ namespace
changed = true;
}
if ( matOld == nullptr || matNew->m_radians != matOld->m_radians )
if ( matOld == nullptr || matNew->m_start != matOld->m_start )
{
memcpy( data + 72, &matNew->m_radians, 4 );
memcpy( data + 72, &matNew->m_start, 4 );
changed = true;
}
if ( matOld == nullptr || matNew->m_span != matOld->m_span )
{
memcpy( data + 76, &matNew->m_span, 4 );
changed = true;
}
if ( state.isOpacityDirty() )
{
const float opacity = state.opacity();
memcpy( data + 76, &opacity, 4 );
memcpy( data + 80, &opacity, 4 );
changed = true;
}
@ -867,31 +836,42 @@ inline Material* qskEnsureMaterial( QskGradientMaterial* material )
return static_cast< Material* >( material );
}
bool QskGradientMaterial::updateGradient( const QGradient* gradient )
bool QskGradientMaterial::updateGradient(
const QRectF& rect, const QGradient* g, qreal extraValue )
{
Q_ASSERT( gradient && gradient->type() == m_gradientType );
Q_ASSERT( g );
if ( gradient == nullptr || gradient->type() != m_gradientType )
if ( g == nullptr )
return false;
switch ( static_cast< int >( gradient->type() ) )
auto& gradient = *g;
Q_ASSERT( gradient.type() == m_gradientType );
if ( gradient.type() != m_gradientType )
return false;
switch ( static_cast< int >( gradient.type() ) )
{
case QGradient::LinearGradient:
{
auto material = static_cast< LinearMaterial* >( this );
return material->setGradient( static_cast< const QLinearGradient* >( gradient ) );
return material->setGradient( rect,
*reinterpret_cast< const QLinearGradient* >( g ) );
}
case QGradient::RadialGradient:
{
auto material = static_cast< RadialMaterial* >( this );
return material->setGradient( static_cast< const QRadialGradient* >( gradient ) );
return material->setGradient( rect,
*reinterpret_cast< const QRadialGradient* >( g ) );
}
case QGradient::ConicalGradient:
{
auto material = static_cast< ConicMaterial* >( this );
return material->setGradient( static_cast< const QConicalGradient* >( gradient ) );
return material->setGradient( rect,
*reinterpret_cast< const QConicalGradient* >( g ), extraValue );
}
}

View File

@ -15,7 +15,7 @@ class QSK_EXPORT QskGradientMaterial : public QSGMaterial
public:
static QskGradientMaterial* createMaterial( QGradient::Type );
bool updateGradient( const QGradient* );
bool updateGradient( const QRectF&, const QGradient*, qreal );
QGradient::Type gradientType() const;
const QGradientStops& stops() const;

View File

@ -71,7 +71,7 @@ static inline bool qskIsGradientVisible( const QGradient* gradient )
{
if ( gradient && gradient->type() != QGradient::NoGradient )
{
for ( const auto stop : gradient->stops() )
for ( const auto& stop : gradient->stops() )
{
if ( stop.second.alpha() > 0 )
return true;
@ -166,7 +166,8 @@ void QskShapeNode::updateNode( const QPainterPath& path,
}
void QskShapeNode::updateNode( const QPainterPath& path,
const QTransform& transform, const QGradient* gradient )
const QTransform& transform, const QRectF& rect,
const QGradient* gradient, qreal extraValue )
{
Q_D( QskShapeNode );
@ -200,7 +201,7 @@ void QskShapeNode::updateNode( const QPainterPath& path,
}
auto gradientMaterial = static_cast< QskGradientMaterial* >( material() );
if ( gradientMaterial->updateGradient( gradient ) )
if ( gradientMaterial->updateGradient( rect, gradient, extraValue ) )
markDirty( QSGNode::DirtyMaterial );
}

View File

@ -20,8 +20,11 @@ class QSK_EXPORT QskShapeNode : public QSGGeometryNode
public:
QskShapeNode();
void updateNode( const QPainterPath&, const QTransform&, const QGradient* );
void updateNode( const QPainterPath&, const QTransform&, const QColor& );
void updateNode( const QPainterPath&, const QTransform&,
const QRectF&, const QGradient*, qreal = 0.0 );
void updateNode( const QPainterPath&,
const QTransform&, const QColor& );
private:
Q_DECLARE_PRIVATE( QskShapeNode )

View File

@ -1,9 +1,26 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource prefix="/qskinny/">
<file>shaders/boxshadow.vert.qsb</file>
<file>shaders/boxshadow.frag.qsb</file>
<file>shaders/boxshadow.vert</file>
<file>shaders/boxshadow.frag</file>
<file>shaders/gradientconic.vert.qsb</file>
<file>shaders/gradientconic.frag.qsb</file>
<file>shaders/gradientconic.vert</file>
<file>shaders/gradientconic.frag</file>
<file>shaders/gradientradial.vert.qsb</file>
<file>shaders/gradientradial.frag.qsb</file>
<file>shaders/gradientradial.vert</file>
<file>shaders/gradientradial.frag</file>
<file>shaders/gradientlinear.vert.qsb</file>
<file>shaders/gradientlinear.frag.qsb</file>
<file>shaders/gradientlinear.vert</file>
<file>shaders/gradientlinear.frag</file>
</qresource>
</RCC>

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,32 @@
#version 440
layout( location = 0 ) in vec2 coord;
layout( location = 0 ) out vec4 fragColor;
layout( std140, binding = 0 ) uniform buf
{
mat4 matrix;
vec2 centerCoord;
float start;
float span;
float opacity;
} ubuf;
layout( binding = 1 ) uniform sampler2D palette;
vec4 colorAt( highp float value )
{
return texture( palette, vec2( value, 0.0 ) );
}
void main()
{
/*
angles as ratio of a rotation:
start: [ 0.0, 1.0 [
span: ] -1.0, 1.0 [
*/
float v = sign( ubuf.span ) * ( atan( -coord.y, coord.x ) / 6.2831853 - ubuf.start );
fragColor = colorAt( ( v - floor( v ) ) / abs( ubuf.span ) ) * ubuf.opacity;
}

View File

@ -0,0 +1,21 @@
#version 440
layout( location = 0 ) in vec4 vertexCoord;
layout( location = 0 ) out vec2 coord;
layout( std140, binding = 0 ) uniform buf
{
mat4 matrix;
vec2 centerCoord;
float start;
float span;
float opacity;
} ubuf;
out gl_PerVertex { vec4 gl_Position; };
void main()
{
coord = vertexCoord.xy - ubuf.centerCoord;
gl_Position = ubuf.matrix * vertexCoord;
}

View File

@ -0,0 +1,24 @@
uniform sampler2D palette;
uniform lowp float opacity;
uniform highp float start;
uniform highp float span;
varying highp vec2 coord;
lowp vec4 colorAt( highp float value )
{
return texture2D( palette, vec2( value, 0.0 ) );
}
void main()
{
/*
angles as ratio of a rotation:
start: [ 0.0, 1.0 [
span: ] -1.0, 1.0 [
*/
highp float v = sign( span ) * ( atan( -coord.y, coord.x ) / 6.2831853 - start );
gl_FragColor = colorAt( ( v - floor( v ) ) / abs( span ) ) * opacity;
}

Binary file not shown.

View File

@ -0,0 +1,12 @@
attribute vec4 vertexCoord;
uniform mat4 matrix;
uniform vec2 centerCoord;
varying vec2 coord;
void main()
{
coord = vertexCoord.xy - centerCoord;
gl_Position = matrix * vertexCoord;
}

Binary file not shown.

View File

@ -0,0 +1,23 @@
#version 440
layout( location = 0 ) in float colorIndex;
layout( location = 0 ) out vec4 fragColor;
layout( std140, binding = 0 ) uniform buf
{
mat4 matrix;
vec4 rect;
float opacity;
} ubuf;
layout( binding = 1 ) uniform sampler2D palette;
vec4 colorAt( float value )
{
return texture( palette, vec2( value, 0.0 ) );
}
void main()
{
fragColor = colorAt( colorIndex ) * ubuf.opacity;
}

View File

@ -0,0 +1,22 @@
#version 440
layout( location = 0 ) in vec4 vertexCoord;
layout( location = 0 ) out float colorIndex;
layout( std140, binding = 0 ) uniform buf
{
mat4 matrix;
vec4 rect;
float opacity;
} ubuf;
out gl_PerVertex { vec4 gl_Position; };
void main()
{
vec2 l = vertexCoord.xy - ubuf.rect.xy;
vec2 size = ubuf.rect.zw;
colorIndex = dot( l, size ) / dot( size, size );
gl_Position = ubuf.matrix * vertexCoord;
}

View File

@ -0,0 +1,14 @@
uniform sampler2D palette;
uniform highp float opacity;
varying highp float colorIndex;
lowp vec4 colorAt( float value )
{
return texture2D( palette, vec2( value, 0.0 ) );
}
void main()
{
gl_FragColor = colorAt( colorIndex ) * opacity;
}

Binary file not shown.

View File

@ -0,0 +1,15 @@
attribute vec4 vertexCoord;
uniform mat4 matrix;
uniform vec4 rect;
varying float colorIndex;
void main()
{
highp vec2 l = vertexCoord.xy - rect.xy;
highp vec2 size = rect.zw;
colorIndex = dot( l, size ) / dot( size, size );
gl_Position = matrix * vertexCoord;
}

Binary file not shown.

View File

@ -0,0 +1,24 @@
#version 440
layout( location = 0 ) in vec2 coord;
layout( location = 0 ) out vec4 fragColor;
layout( std140, binding = 0 ) uniform buf
{
mat4 matrix;
vec2 centerCoord;
vec2 radius;
float opacity;
} ubuf;
layout( binding = 1 ) uniform sampler2D palette;
vec4 colorAt( float value )
{
return texture( palette, vec2( value, 0.0 ) );
}
void main()
{
fragColor = colorAt( length( coord / ubuf.radius ) ) * ubuf.opacity;
}

View File

@ -0,0 +1,20 @@
#version 440
layout( location = 0 ) in vec4 vertexCoord;
layout( location = 0 ) out vec2 coord;
layout( std140, binding = 0 ) uniform buf
{
mat4 matrix;
vec2 centerCoord;
vec2 radius;
float opacity;
} ubuf;
out gl_PerVertex { vec4 gl_Position; };
void main()
{
coord = vertexCoord.xy - ubuf.centerCoord;
gl_Position = ubuf.matrix * vertexCoord;
}

View File

@ -0,0 +1,16 @@
uniform sampler2D palette;
uniform lowp float opacity;
uniform highp vec2 radius;
varying highp vec2 coord;
lowp vec4 colorAt( highp float value )
{
return texture2D( palette, vec2( value, 0.0 ) );
}
void main()
{
gl_FragColor = colorAt( length( coord / radius ) ) * opacity;
}

Binary file not shown.

View File

@ -0,0 +1,12 @@
attribute vec4 vertexCoord;
uniform mat4 matrix;
uniform vec2 centerCoord;
varying vec2 coord;
void main()
{
coord = vertexCoord.xy - centerCoord;
gl_Position = matrix * vertexCoord;
}

Binary file not shown.

View File

@ -1,4 +1,18 @@
#! /bin/sh
qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -b -o boxshadow.vert.qsb boxshadow-vulkan.vert
qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -b -o boxshadow.frag.qsb boxshadow-vulkan.frag
function qsbcompile {
qsbfile=`echo $1 | sed 's/-vulkan//'`
qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -b -o ${qsbfile}.qsb $1
}
qsbcompile boxshadow-vulkan.vert
qsbcompile boxshadow-vulkan.frag
qsbcompile gradientconic-vulkan.vert
qsbcompile gradientconic-vulkan.frag
qsbcompile gradientradial-vulkan.vert
qsbcompile gradientradial-vulkan.frag
qsbcompile gradientlinear-vulkan.vert
qsbcompile gradientlinear-vulkan.frag

View File

@ -3,12 +3,6 @@ TARGET = $$qskLibraryTarget(qskinny)
QT += quick quick-private
# We need quickshapes for the shaders for the gradients only,
# As those shaders are more or less trivial # it might be better
# to implement our own shaders to get rid of this extra module dependency
QT += quickshapes-private
greaterThan( QT_MAJOR_VERSION, 5 ) {
QT += opengl-private
}