aspectRatio for conic gradients added to support f.e for filling ellipsoid arcs.
This commit is contained in:
parent
e858e15b41
commit
9e99735d2f
|
@ -171,7 +171,7 @@ QskGradient::QskGradient( const QGradient& qGradient )
|
||||||
QskGradient::QskGradient( const QskGradient& other ) noexcept
|
QskGradient::QskGradient( const QskGradient& other ) noexcept
|
||||||
: m_stops( other.m_stops )
|
: m_stops( other.m_stops )
|
||||||
, m_values{ other.m_values[0], other.m_values[1],
|
, m_values{ other.m_values[0], other.m_values[1],
|
||||||
other.m_values[2], other.m_values[3], }
|
other.m_values[2], other.m_values[3], other.m_values[4] }
|
||||||
, m_type( other.m_type )
|
, m_type( other.m_type )
|
||||||
, m_spreadMode( other.m_spreadMode )
|
, m_spreadMode( other.m_spreadMode )
|
||||||
, m_stretchMode( other.m_stretchMode )
|
, m_stretchMode( other.m_stretchMode )
|
||||||
|
@ -197,6 +197,7 @@ QskGradient& QskGradient::operator=( const QskGradient& other ) noexcept
|
||||||
m_values[1] = other.m_values[1];
|
m_values[1] = other.m_values[1];
|
||||||
m_values[2] = other.m_values[2];
|
m_values[2] = other.m_values[2];
|
||||||
m_values[3] = other.m_values[3];
|
m_values[3] = other.m_values[3];
|
||||||
|
m_values[4] = other.m_values[4];
|
||||||
|
|
||||||
m_isDirty = other.m_isDirty;
|
m_isDirty = other.m_isDirty;
|
||||||
m_isValid = other.m_isValid;
|
m_isValid = other.m_isValid;
|
||||||
|
@ -215,6 +216,7 @@ bool QskGradient::operator==( const QskGradient& other ) const noexcept
|
||||||
&& ( m_values[1] == other.m_values[1] )
|
&& ( m_values[1] == other.m_values[1] )
|
||||||
&& ( m_values[2] == other.m_values[2] )
|
&& ( m_values[2] == other.m_values[2] )
|
||||||
&& ( m_values[3] == other.m_values[3] )
|
&& ( m_values[3] == other.m_values[3] )
|
||||||
|
&& ( m_values[4] == other.m_values[4] )
|
||||||
&& ( m_stops == other.m_stops );
|
&& ( m_stops == other.m_stops );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -439,6 +441,10 @@ void QskGradient::stretchTo( const QRectF& rect )
|
||||||
case Conic:
|
case Conic:
|
||||||
{
|
{
|
||||||
transform.map( m_values[0], m_values[1], &m_values[0], &m_values[1] );
|
transform.map( m_values[0], m_values[1], &m_values[0], &m_values[1] );
|
||||||
|
|
||||||
|
if ( m_values[4] == 0.0 && !rect.isEmpty() )
|
||||||
|
m_values[4] = rect.width() / rect.height();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -657,6 +663,13 @@ void QskGradient::setConicDirection( qreal x, qreal y,
|
||||||
setConicDirection( QskConicDirection( x, y, startAngle, spanAngle ) );
|
setConicDirection( QskConicDirection( x, y, startAngle, spanAngle ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QskGradient::setConicDirection( qreal x, qreal y,
|
||||||
|
qreal startAngle, qreal spanAngle, qreal aspectRatio )
|
||||||
|
{
|
||||||
|
const QskConicDirection dir( x, y, startAngle, spanAngle, aspectRatio );
|
||||||
|
setConicDirection( dir );
|
||||||
|
}
|
||||||
|
|
||||||
void QskGradient::setConicDirection( const QskConicDirection& direction )
|
void QskGradient::setConicDirection( const QskConicDirection& direction )
|
||||||
{
|
{
|
||||||
m_type = Conic;
|
m_type = Conic;
|
||||||
|
@ -665,6 +678,7 @@ void QskGradient::setConicDirection( const QskConicDirection& direction )
|
||||||
m_values[1] = direction.center().y();
|
m_values[1] = direction.center().y();
|
||||||
m_values[2] = direction.startAngle();
|
m_values[2] = direction.startAngle();
|
||||||
m_values[3] = direction.spanAngle();
|
m_values[3] = direction.spanAngle();
|
||||||
|
m_values[4] = direction.aspectRatio();
|
||||||
}
|
}
|
||||||
|
|
||||||
QskConicDirection QskGradient::conicDirection() const
|
QskConicDirection QskGradient::conicDirection() const
|
||||||
|
@ -674,7 +688,10 @@ QskConicDirection QskGradient::conicDirection() const
|
||||||
if ( m_type != Conic )
|
if ( m_type != Conic )
|
||||||
return QskConicDirection( 0.5, 0.5, 0.0, 0.0 );
|
return QskConicDirection( 0.5, 0.5, 0.0, 0.0 );
|
||||||
|
|
||||||
return QskConicDirection( m_values[0], m_values[1], m_values[2], m_values[3] );
|
QskConicDirection dir( m_values[0], m_values[1], m_values[2], m_values[3] );
|
||||||
|
dir.setAspectRatio( m_values[4] );
|
||||||
|
|
||||||
|
return dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskGradient::setDirection( Type type )
|
void QskGradient::setDirection( Type type )
|
||||||
|
@ -702,7 +719,7 @@ void QskGradient::setDirection( Type type )
|
||||||
void QskGradient::resetDirection()
|
void QskGradient::resetDirection()
|
||||||
{
|
{
|
||||||
m_type = Stops;
|
m_type = Stops;
|
||||||
m_values[0] = m_values[1] = m_values[2] = m_values[3] = 0.0;
|
m_values[0] = m_values[1] = m_values[2] = m_values[3] = m_values[4] = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QskGradient QskGradient::effectiveGradient() const
|
QskGradient QskGradient::effectiveGradient() const
|
||||||
|
@ -803,6 +820,7 @@ QDebug operator<<( QDebug debug, const QskGradient& gradient )
|
||||||
const auto dir = gradient.conicDirection();
|
const auto dir = gradient.conicDirection();
|
||||||
|
|
||||||
debug << dir.center().x() << "," << dir.center().y()
|
debug << dir.center().x() << "," << dir.center().y()
|
||||||
|
<< ",AR:" << dir.aspectRatio()
|
||||||
<< ",[" << dir.startAngle() << "," << dir.spanAngle() << "])";
|
<< ",[" << dir.startAngle() << "," << dir.spanAngle() << "])";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,8 +97,14 @@ class QSK_EXPORT QskGradient
|
||||||
void setRadialDirection( const qreal x, qreal y, qreal radiusX, qreal radiusY );
|
void setRadialDirection( const qreal x, qreal y, qreal radiusX, qreal radiusY );
|
||||||
QskRadialDirection radialDirection() const;
|
QskRadialDirection radialDirection() const;
|
||||||
|
|
||||||
void setConicDirection( qreal, qreal );
|
void setConicDirection( qreal x, qreal y );
|
||||||
void setConicDirection( qreal, qreal, qreal, qreal = 360.0 );
|
|
||||||
|
void setConicDirection( qreal x, qreal y,
|
||||||
|
qreal startAngle, qreal spanAngle = 360.0 );
|
||||||
|
|
||||||
|
void setConicDirection( qreal x, qreal y,
|
||||||
|
qreal startAngle, qreal spanAngle, qreal aspectRatio );
|
||||||
|
|
||||||
void setConicDirection( const QskConicDirection& );
|
void setConicDirection( const QskConicDirection& );
|
||||||
QskConicDirection conicDirection() const;
|
QskConicDirection conicDirection() const;
|
||||||
|
|
||||||
|
@ -172,9 +178,9 @@ class QSK_EXPORT QskGradient
|
||||||
/*
|
/*
|
||||||
Linear: x1, y1, x2, y2
|
Linear: x1, y1, x2, y2
|
||||||
Radial: centerX, centerY, radiusX, radiusY
|
Radial: centerX, centerY, radiusX, radiusY
|
||||||
Conic: centerX, centerY, startAngle, spanAngle
|
Conic: centerX, centerY, startAngle, spanAngle, aspectRatio
|
||||||
*/
|
*/
|
||||||
qreal m_values[4] = {};
|
qreal m_values[5] = {};
|
||||||
|
|
||||||
unsigned int m_type : 3;
|
unsigned int m_type : 3;
|
||||||
unsigned int m_spreadMode : 3;
|
unsigned int m_spreadMode : 3;
|
||||||
|
|
|
@ -228,6 +228,11 @@ void QskConicDirection::setSpanAngle( qreal degrees ) noexcept
|
||||||
m_spanAngle = qBound( -360.0, degrees, 360.0 );
|
m_spanAngle = qBound( -360.0, degrees, 360.0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QskConicDirection::setAspectRatio( qreal ratio ) noexcept
|
||||||
|
{
|
||||||
|
m_aspectRatio = qMax( ratio, 0.0 );
|
||||||
|
}
|
||||||
|
|
||||||
// -- QskRadialDirection
|
// -- QskRadialDirection
|
||||||
|
|
||||||
void QskRadialDirection::setCenter( const QPointF& center ) noexcept
|
void QskRadialDirection::setCenter( const QPointF& center ) noexcept
|
||||||
|
|
|
@ -105,16 +105,19 @@ class QSK_EXPORT QskConicDirection
|
||||||
Q_PROPERTY( qreal y READ y WRITE setY )
|
Q_PROPERTY( qreal y READ y WRITE setY )
|
||||||
Q_PROPERTY( qreal startAngle READ startAngle WRITE setStartAngle )
|
Q_PROPERTY( qreal startAngle READ startAngle WRITE setStartAngle )
|
||||||
Q_PROPERTY( qreal spanAngle READ spanAngle WRITE setSpanAngle )
|
Q_PROPERTY( qreal spanAngle READ spanAngle WRITE setSpanAngle )
|
||||||
|
Q_PROPERTY( qreal aspectRatio READ aspectRatio WRITE setAspectRatio )
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// counter-clockwise
|
// counter-clockwise
|
||||||
constexpr QskConicDirection() noexcept = default;
|
constexpr QskConicDirection() noexcept = default;
|
||||||
|
|
||||||
constexpr QskConicDirection( qreal x, qreal y, qreal startAngle = 0.0 ) noexcept;
|
constexpr QskConicDirection( qreal x, qreal y, qreal startAngle = 0.0 ) noexcept;
|
||||||
constexpr QskConicDirection( qreal x, qreal y, qreal startAngle, qreal spanAngle ) noexcept;
|
constexpr QskConicDirection( qreal x, qreal y,
|
||||||
|
qreal startAngle, qreal spanAngle, qreal aspectRatio = 0.0 ) noexcept;
|
||||||
|
|
||||||
constexpr QskConicDirection( const QPointF&, qreal startAngle = 0.0 ) noexcept;
|
constexpr QskConicDirection( const QPointF&, qreal startAngle = 0.0 ) noexcept;
|
||||||
constexpr QskConicDirection( const QPointF&, qreal startAngle, qreal spanAngle ) noexcept;
|
constexpr QskConicDirection( const QPointF&,
|
||||||
|
qreal startAngle, qreal spanAngle, qreal aspectRatio = 0.0 ) noexcept;
|
||||||
|
|
||||||
constexpr QPointF center() const noexcept;
|
constexpr QPointF center() const noexcept;
|
||||||
void setCenter(const QPointF& center) noexcept;
|
void setCenter(const QPointF& center) noexcept;
|
||||||
|
@ -132,11 +135,15 @@ class QSK_EXPORT QskConicDirection
|
||||||
constexpr qreal spanAngle() const noexcept;
|
constexpr qreal spanAngle() const noexcept;
|
||||||
void setSpanAngle( qreal ) noexcept;
|
void setSpanAngle( qreal ) noexcept;
|
||||||
|
|
||||||
|
constexpr qreal aspectRatio() const noexcept;
|
||||||
|
void setAspectRatio( qreal ) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
qreal m_x = 0.5;
|
qreal m_x = 0.5;
|
||||||
qreal m_y = 0.5;
|
qreal m_y = 0.5;
|
||||||
qreal m_startAngle = 0.0;
|
qreal m_startAngle = 0.0;
|
||||||
qreal m_spanAngle = 360.0;
|
qreal m_spanAngle = 360.0;
|
||||||
|
qreal m_aspectRatio = 0.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QSK_EXPORT QskRadialDirection
|
class QSK_EXPORT QskRadialDirection
|
||||||
|
@ -299,12 +306,13 @@ inline constexpr QskConicDirection::QskConicDirection(
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline constexpr QskConicDirection::QskConicDirection(
|
inline constexpr QskConicDirection::QskConicDirection( qreal x, qreal y,
|
||||||
qreal x, qreal y, qreal startAngle, qreal spanAngle ) noexcept
|
qreal startAngle, qreal spanAngle, qreal aspectRatio ) noexcept
|
||||||
: m_x( x )
|
: m_x( x )
|
||||||
, m_y( y )
|
, m_y( y )
|
||||||
, m_startAngle( startAngle )
|
, m_startAngle( startAngle )
|
||||||
, m_spanAngle( spanAngle )
|
, m_spanAngle( spanAngle )
|
||||||
|
, m_aspectRatio( aspectRatio )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,9 +322,9 @@ inline constexpr QskConicDirection::QskConicDirection(
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline constexpr QskConicDirection::QskConicDirection(
|
inline constexpr QskConicDirection::QskConicDirection( const QPointF& pos,
|
||||||
const QPointF& pos, qreal startAngle, qreal spanAngle ) noexcept
|
qreal startAngle, qreal spanAngle, qreal apectRatio ) noexcept
|
||||||
: QskConicDirection( pos.x(), pos.y(), startAngle, spanAngle )
|
: QskConicDirection( pos.x(), pos.y(), startAngle, spanAngle, apectRatio )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,6 +353,11 @@ inline constexpr qreal QskConicDirection::y() const noexcept
|
||||||
return m_y;
|
return m_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline constexpr qreal QskConicDirection::aspectRatio() const noexcept
|
||||||
|
{
|
||||||
|
return m_aspectRatio;
|
||||||
|
}
|
||||||
|
|
||||||
inline constexpr QskRadialDirection::QskRadialDirection(
|
inline constexpr QskRadialDirection::QskRadialDirection(
|
||||||
qreal x, qreal y, qreal radius ) noexcept
|
qreal x, qreal y, qreal radius ) noexcept
|
||||||
: m_x( x )
|
: m_x( x )
|
||||||
|
|
|
@ -510,6 +510,16 @@ namespace
|
||||||
|
|
||||||
const auto dir = gradient.conicDirection();
|
const auto dir = gradient.conicDirection();
|
||||||
|
|
||||||
|
float ratio = dir.aspectRatio();
|
||||||
|
if ( ratio <= 0.0f )
|
||||||
|
ratio = 1.0f;
|
||||||
|
|
||||||
|
if ( ratio != m_aspectRatio )
|
||||||
|
{
|
||||||
|
m_aspectRatio = ratio;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
const QVector2D center( dir.x(), dir.y() );
|
const QVector2D center( dir.x(), dir.y() );
|
||||||
|
|
||||||
if ( center != m_center )
|
if ( center != m_center )
|
||||||
|
@ -555,6 +565,7 @@ namespace
|
||||||
const auto mat = static_cast< const ConicMaterial* >( other );
|
const auto mat = static_cast< const ConicMaterial* >( other );
|
||||||
|
|
||||||
if ( ( m_center != mat->m_center )
|
if ( ( m_center != mat->m_center )
|
||||||
|
|| !qskFuzzyCompare( m_aspectRatio, mat->m_aspectRatio )
|
||||||
|| !qskFuzzyCompare( m_start, mat->m_start )
|
|| !qskFuzzyCompare( m_start, mat->m_start )
|
||||||
|| !qskFuzzyCompare( m_span, mat->m_span ) )
|
|| !qskFuzzyCompare( m_span, mat->m_span ) )
|
||||||
{
|
{
|
||||||
|
@ -567,6 +578,7 @@ namespace
|
||||||
QSGMaterialShader* createShader() const override;
|
QSGMaterialShader* createShader() const override;
|
||||||
|
|
||||||
QVector2D m_center;
|
QVector2D m_center;
|
||||||
|
float m_aspectRatio = 1.0;
|
||||||
float m_start = 0.0;
|
float m_start = 0.0;
|
||||||
float m_span = 1.0;
|
float m_span = 1.0;
|
||||||
};
|
};
|
||||||
|
@ -585,6 +597,7 @@ namespace
|
||||||
GradientShaderGL::initialize();
|
GradientShaderGL::initialize();
|
||||||
|
|
||||||
m_centerCoordId = program()->uniformLocation( "centerCoord" );
|
m_centerCoordId = program()->uniformLocation( "centerCoord" );
|
||||||
|
m_aspectRatioId = program()->uniformLocation( "aspectRatio" );
|
||||||
m_startId = program()->uniformLocation( "start" );
|
m_startId = program()->uniformLocation( "start" );
|
||||||
m_spanId = program()->uniformLocation( "span" );
|
m_spanId = program()->uniformLocation( "span" );
|
||||||
}
|
}
|
||||||
|
@ -594,12 +607,14 @@ namespace
|
||||||
auto material = static_cast< const ConicMaterial* >( newMaterial );
|
auto material = static_cast< const ConicMaterial* >( newMaterial );
|
||||||
|
|
||||||
program()->setUniformValue( m_centerCoordId, material->m_center );
|
program()->setUniformValue( m_centerCoordId, material->m_center );
|
||||||
|
program()->setUniformValue( m_aspectRatioId, material->m_aspectRatio );
|
||||||
program()->setUniformValue( m_startId, material->m_start );
|
program()->setUniformValue( m_startId, material->m_start );
|
||||||
program()->setUniformValue( m_spanId, material->m_span );
|
program()->setUniformValue( m_spanId, material->m_span );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_centerCoordId = -1;
|
int m_centerCoordId = -1;
|
||||||
|
int m_aspectRatioId = -1;
|
||||||
int m_startId = -1;
|
int m_startId = -1;
|
||||||
int m_spanId = -1;
|
int m_spanId = -1;
|
||||||
};
|
};
|
||||||
|
@ -620,7 +635,7 @@ namespace
|
||||||
auto matNew = static_cast< ConicMaterial* >( newMaterial );
|
auto matNew = static_cast< ConicMaterial* >( newMaterial );
|
||||||
auto matOld = static_cast< ConicMaterial* >( oldMaterial );
|
auto matOld = static_cast< ConicMaterial* >( oldMaterial );
|
||||||
|
|
||||||
Q_ASSERT( state.uniformData()->size() >= 84 );
|
Q_ASSERT( state.uniformData()->size() >= 88 );
|
||||||
|
|
||||||
auto data = state.uniformData()->data();
|
auto data = state.uniformData()->data();
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
|
@ -639,22 +654,28 @@ namespace
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( matOld == nullptr || matNew->m_aspectRatio != matOld->m_aspectRatio )
|
||||||
|
{
|
||||||
|
memcpy( data + 72, &matNew->m_aspectRatio, 4 );
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ( matOld == nullptr || matNew->m_start != matOld->m_start )
|
if ( matOld == nullptr || matNew->m_start != matOld->m_start )
|
||||||
{
|
{
|
||||||
memcpy( data + 72, &matNew->m_start, 4 );
|
memcpy( data + 76, &matNew->m_start, 4 );
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( matOld == nullptr || matNew->m_span != matOld->m_span )
|
if ( matOld == nullptr || matNew->m_span != matOld->m_span )
|
||||||
{
|
{
|
||||||
memcpy( data + 76, &matNew->m_span, 4 );
|
memcpy( data + 80, &matNew->m_span, 4 );
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( state.isOpacityDirty() )
|
if ( state.isOpacityDirty() )
|
||||||
{
|
{
|
||||||
const float opacity = state.opacity();
|
const float opacity = state.opacity();
|
||||||
memcpy( data + 80, &opacity, 4 );
|
memcpy( data + 84, &opacity, 4 );
|
||||||
|
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ layout( std140, binding = 0 ) uniform buf
|
||||||
{
|
{
|
||||||
mat4 matrix;
|
mat4 matrix;
|
||||||
vec2 centerCoord;
|
vec2 centerCoord;
|
||||||
|
float aspectRatio;
|
||||||
float start;
|
float start;
|
||||||
float span;
|
float span;
|
||||||
float opacity;
|
float opacity;
|
||||||
|
|
|
@ -7,6 +7,7 @@ layout( std140, binding = 0 ) uniform buf
|
||||||
{
|
{
|
||||||
mat4 matrix;
|
mat4 matrix;
|
||||||
vec2 centerCoord;
|
vec2 centerCoord;
|
||||||
|
float aspectRatio;
|
||||||
float start;
|
float start;
|
||||||
float span;
|
float span;
|
||||||
float opacity;
|
float opacity;
|
||||||
|
@ -17,5 +18,7 @@ out gl_PerVertex { vec4 gl_Position; };
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
coord = vertexCoord.xy - ubuf.centerCoord;
|
coord = vertexCoord.xy - ubuf.centerCoord;
|
||||||
|
coord.y *= ubuf.aspectRatio;
|
||||||
|
|
||||||
gl_Position = ubuf.matrix * vertexCoord;
|
gl_Position = ubuf.matrix * vertexCoord;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -1,6 +1,7 @@
|
||||||
attribute vec4 vertexCoord;
|
attribute vec4 vertexCoord;
|
||||||
|
|
||||||
uniform mat4 matrix;
|
uniform mat4 matrix;
|
||||||
|
uniform highp float aspectRatio;
|
||||||
uniform vec2 centerCoord;
|
uniform vec2 centerCoord;
|
||||||
|
|
||||||
varying vec2 coord;
|
varying vec2 coord;
|
||||||
|
@ -8,5 +9,7 @@ varying vec2 coord;
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
coord = vertexCoord.xy - centerCoord;
|
coord = vertexCoord.xy - centerCoord;
|
||||||
|
coord.y *= aspectRatio;
|
||||||
|
|
||||||
gl_Position = matrix * vertexCoord;
|
gl_Position = matrix * vertexCoord;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue