Merge branch 'master' into features/drawer
This commit is contained in:
commit
d7425ac541
|
|
@ -97,6 +97,7 @@ list(APPEND SOURCES
|
||||||
|
|
||||||
list(APPEND HEADERS
|
list(APPEND HEADERS
|
||||||
nodes/QskArcNode.h
|
nodes/QskArcNode.h
|
||||||
|
nodes/QskBasicLinesNode.h
|
||||||
nodes/QskBoxNode.h
|
nodes/QskBoxNode.h
|
||||||
nodes/QskBoxClipNode.h
|
nodes/QskBoxClipNode.h
|
||||||
nodes/QskBoxFillNode.h
|
nodes/QskBoxFillNode.h
|
||||||
|
|
@ -133,6 +134,7 @@ list(APPEND PRIVATE_HEADERS
|
||||||
|
|
||||||
list(APPEND SOURCES
|
list(APPEND SOURCES
|
||||||
nodes/QskArcNode.cpp
|
nodes/QskArcNode.cpp
|
||||||
|
nodes/QskBasicLinesNode.cpp
|
||||||
nodes/QskBoxNode.cpp
|
nodes/QskBoxNode.cpp
|
||||||
nodes/QskBoxClipNode.cpp
|
nodes/QskBoxClipNode.cpp
|
||||||
nodes/QskBoxFillNode.cpp
|
nodes/QskBoxFillNode.cpp
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,301 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "QskBasicLinesNode.h"
|
||||||
|
|
||||||
|
#include <qsgmaterial.h>
|
||||||
|
#include <qsggeometry.h>
|
||||||
|
#include <QTransform>
|
||||||
|
|
||||||
|
QSK_QT_PRIVATE_BEGIN
|
||||||
|
#include <private/qsgnode_p.h>
|
||||||
|
QSK_QT_PRIVATE_END
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||||
|
#include <QSGMaterialRhiShader>
|
||||||
|
using RhiShader = QSGMaterialRhiShader;
|
||||||
|
#else
|
||||||
|
using RhiShader = QSGMaterialShader;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class Material final : public QSGMaterial
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Material();
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||||
|
QSGMaterialShader* createShader() const override;
|
||||||
|
#else
|
||||||
|
QSGMaterialShader* createShader( QSGRendererInterface::RenderMode ) const override;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QSGMaterialType* type() const override;
|
||||||
|
|
||||||
|
int compare( const QSGMaterial* other ) const override;
|
||||||
|
|
||||||
|
QVector4D m_color = QVector4D{ 0, 0, 0, 1 };
|
||||||
|
Qt::Orientations m_pixelAlignment;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShaderRhi final : public RhiShader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ShaderRhi()
|
||||||
|
{
|
||||||
|
const QString root( ":/qskinny/shaders/" );
|
||||||
|
|
||||||
|
setShaderFileName( VertexStage, root + "crisplines.vert.qsb" );
|
||||||
|
setShaderFileName( FragmentStage, root + "crisplines.frag.qsb" );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool updateUniformData( RenderState& state,
|
||||||
|
QSGMaterial* newMaterial, QSGMaterial* oldMaterial ) override
|
||||||
|
{
|
||||||
|
auto matOld = static_cast< Material* >( oldMaterial );
|
||||||
|
auto matNew = static_cast< Material* >( newMaterial );
|
||||||
|
|
||||||
|
Q_ASSERT( state.uniformData()->size() >= 88 );
|
||||||
|
|
||||||
|
auto data = state.uniformData()->data();
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
const auto matrix = state.combinedMatrix();
|
||||||
|
|
||||||
|
if ( state.isMatrixDirty() )
|
||||||
|
{
|
||||||
|
memcpy( data + 0, matrix.constData(), 64 );
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ( matOld == nullptr ) || ( matNew->m_color != matOld->m_color ) )
|
||||||
|
{
|
||||||
|
// state.opacity() TODO ...
|
||||||
|
memcpy( data + 64, &matNew->m_color, 16 );
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( state.isMatrixDirty() || ( matOld == nullptr )
|
||||||
|
|| ( matNew->m_pixelAlignment != matOld->m_pixelAlignment ) )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We do not need to upload the size as it is available
|
||||||
|
from the matrix. But the shader needs to know wether to
|
||||||
|
round or not TODO ...
|
||||||
|
*/
|
||||||
|
QVector2D size;
|
||||||
|
|
||||||
|
if ( matNew->m_pixelAlignment & Qt::Horizontal )
|
||||||
|
size.setX( 2.0 / matrix( 0, 0 ) );
|
||||||
|
|
||||||
|
if ( matNew->m_pixelAlignment & Qt::Vertical )
|
||||||
|
size.setY( -2.0 / matrix( 1, 1 ) );
|
||||||
|
|
||||||
|
memcpy( data + 80, &size, 8 );
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// the old type of shader - spcific for OpenGL
|
||||||
|
|
||||||
|
class ShaderGL final : public QSGMaterialShader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ShaderGL()
|
||||||
|
{
|
||||||
|
const QString root( ":/qskinny/shaders/" );
|
||||||
|
|
||||||
|
setShaderSourceFile( QOpenGLShader::Vertex,
|
||||||
|
":/qskinny/shaders/crisplines.vert" );
|
||||||
|
|
||||||
|
setShaderSourceFile( QOpenGLShader::Fragment,
|
||||||
|
":/qt-project.org/scenegraph/shaders/flatcolor.frag" );
|
||||||
|
}
|
||||||
|
|
||||||
|
char const* const* attributeNames() const override
|
||||||
|
{
|
||||||
|
static char const* const names[] = { "in_vertex", nullptr };
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
void initialize() override
|
||||||
|
{
|
||||||
|
QSGMaterialShader::initialize();
|
||||||
|
|
||||||
|
auto p = program();
|
||||||
|
|
||||||
|
m_matrixId = p->uniformLocation( "matrix" );
|
||||||
|
m_colorId = p->uniformLocation( "color" );
|
||||||
|
m_sizeId = p->uniformLocation( "size" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateState( const QSGMaterialShader::RenderState& state,
|
||||||
|
QSGMaterial* newMaterial, QSGMaterial* oldMaterial) override
|
||||||
|
{
|
||||||
|
auto p = program();
|
||||||
|
|
||||||
|
const auto matrix = state.combinedMatrix();
|
||||||
|
|
||||||
|
if ( state.isMatrixDirty() )
|
||||||
|
p->setUniformValue( m_matrixId, matrix );
|
||||||
|
|
||||||
|
bool updateMaterial = ( oldMaterial == nullptr )
|
||||||
|
|| newMaterial->compare( oldMaterial ) != 0;
|
||||||
|
|
||||||
|
updateMaterial |= state.isCachedMaterialDataDirty();
|
||||||
|
|
||||||
|
if ( updateMaterial )
|
||||||
|
{
|
||||||
|
auto material = static_cast< const Material* >( newMaterial );
|
||||||
|
|
||||||
|
p->setUniformValue( m_colorId, material->m_color );
|
||||||
|
|
||||||
|
QVector2D size;
|
||||||
|
|
||||||
|
if ( material->m_pixelAlignment & Qt::Horizontal )
|
||||||
|
size.setX( 2.0 / matrix( 0, 0 ) );
|
||||||
|
|
||||||
|
if ( material->m_pixelAlignment & Qt::Vertical )
|
||||||
|
size.setY( -2.0 / matrix( 1, 1 ) );
|
||||||
|
|
||||||
|
p->setUniformValue( m_sizeId, size );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_matrixId = -1;
|
||||||
|
int m_colorId = -1;
|
||||||
|
int m_sizeId = -1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Material::Material()
|
||||||
|
{
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||||
|
setFlag( QSGMaterial::SupportsRhiShader, true );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||||
|
|
||||||
|
QSGMaterialShader* Material::createShader() const
|
||||||
|
{
|
||||||
|
if ( !( flags() & QSGMaterial::RhiShaderWanted ) )
|
||||||
|
return new ShaderGL();
|
||||||
|
|
||||||
|
return new ShaderRhi();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
QSGMaterialShader* Material::createShader( QSGRendererInterface::RenderMode ) const
|
||||||
|
{
|
||||||
|
return new ShaderRhi();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QSGMaterialType* Material::type() const
|
||||||
|
{
|
||||||
|
static QSGMaterialType staticType;
|
||||||
|
return &staticType;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Material::compare( const QSGMaterial* other ) const
|
||||||
|
{
|
||||||
|
auto material = static_cast< const Material* >( other );
|
||||||
|
|
||||||
|
if ( ( material->m_color == m_color )
|
||||||
|
&& ( material->m_pixelAlignment == m_pixelAlignment ) )
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSGMaterial::compare( other );
|
||||||
|
}
|
||||||
|
|
||||||
|
class QskBasicLinesNodePrivate final : public QSGGeometryNodePrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QskBasicLinesNodePrivate()
|
||||||
|
: geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
|
||||||
|
{
|
||||||
|
geometry.setDrawingMode( QSGGeometry::DrawLines );
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGGeometry geometry;
|
||||||
|
Material material;
|
||||||
|
};
|
||||||
|
|
||||||
|
QskBasicLinesNode::QskBasicLinesNode()
|
||||||
|
: QSGGeometryNode( *new QskBasicLinesNodePrivate )
|
||||||
|
{
|
||||||
|
Q_D( QskBasicLinesNode );
|
||||||
|
|
||||||
|
setGeometry( &d->geometry );
|
||||||
|
setMaterial( &d->material );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskBasicLinesNode::~QskBasicLinesNode()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskBasicLinesNode::setPixelAlignment( Qt::Orientations orientations )
|
||||||
|
{
|
||||||
|
Q_D( QskBasicLinesNode );
|
||||||
|
|
||||||
|
if ( orientations != d->material.m_pixelAlignment )
|
||||||
|
{
|
||||||
|
d->material.m_pixelAlignment = orientations;
|
||||||
|
markDirty( QSGNode::DirtyMaterial );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::Orientations QskBasicLinesNode::pixelAlignment() const
|
||||||
|
{
|
||||||
|
return d_func()->material.m_pixelAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskBasicLinesNode::setColor( const QColor& color )
|
||||||
|
{
|
||||||
|
Q_D( QskBasicLinesNode );
|
||||||
|
|
||||||
|
const auto a = color.alphaF();
|
||||||
|
|
||||||
|
const QVector4D c( color.redF() * a, color.greenF() * a, color.blueF() * a, a );
|
||||||
|
|
||||||
|
if ( c != d->material.m_color )
|
||||||
|
{
|
||||||
|
d->material.m_color = c;
|
||||||
|
markDirty( QSGNode::DirtyMaterial );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QskBasicLinesNode::setLineWidth( float lineWidth )
|
||||||
|
{
|
||||||
|
Q_D( QskBasicLinesNode );
|
||||||
|
|
||||||
|
lineWidth = std::max( lineWidth, 0.0f );
|
||||||
|
if( lineWidth != d->geometry.lineWidth() )
|
||||||
|
d->geometry.setLineWidth( lineWidth );
|
||||||
|
}
|
||||||
|
|
||||||
|
float QskBasicLinesNode::lineWidth() const
|
||||||
|
{
|
||||||
|
return d_func()->geometry.lineWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#ifndef QSK_BASIC_LINES_NODE_H
|
||||||
|
#define QSK_BASIC_LINES_NODE_H
|
||||||
|
|
||||||
|
#include "QskGlobal.h"
|
||||||
|
|
||||||
|
#include <qsgnode.h>
|
||||||
|
#include <qnamespace.h>
|
||||||
|
|
||||||
|
class QColor;
|
||||||
|
|
||||||
|
class QskBasicLinesNodePrivate;
|
||||||
|
|
||||||
|
/*
|
||||||
|
A node for stippled or solid lines.
|
||||||
|
For the moment limited to horizontal/vertical lines: TODO
|
||||||
|
*/
|
||||||
|
class QSK_EXPORT QskBasicLinesNode : public QSGGeometryNode
|
||||||
|
{
|
||||||
|
using Inherited = QSGGeometryNode;
|
||||||
|
|
||||||
|
public:
|
||||||
|
QskBasicLinesNode();
|
||||||
|
~QskBasicLinesNode() override;
|
||||||
|
|
||||||
|
void setPixelAlignment( Qt::Orientations );
|
||||||
|
Qt::Orientations pixelAlignment() const;
|
||||||
|
|
||||||
|
void setColor( const QColor& );
|
||||||
|
|
||||||
|
void setLineWidth( float );
|
||||||
|
float lineWidth() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Q_DECLARE_PRIVATE( QskBasicLinesNode )
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -9,17 +9,9 @@
|
||||||
#include "QskStippledLineRenderer.h"
|
#include "QskStippledLineRenderer.h"
|
||||||
#include "QskSGNode.h"
|
#include "QskSGNode.h"
|
||||||
|
|
||||||
#include <qsgflatcolormaterial.h>
|
|
||||||
#include <qsgvertexcolormaterial.h>
|
|
||||||
#include <qtransform.h>
|
#include <qtransform.h>
|
||||||
#include <qquickitem.h>
|
|
||||||
#include <qquickwindow.h>
|
|
||||||
#include <qline.h>
|
#include <qline.h>
|
||||||
|
|
||||||
QSK_QT_PRIVATE_BEGIN
|
|
||||||
#include <private/qsgnode_p.h>
|
|
||||||
QSK_QT_PRIVATE_END
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
inline qreal mapX( const QTransform& t, qreal x )
|
inline qreal mapX( const QTransform& t, qreal x )
|
||||||
|
|
@ -114,115 +106,14 @@ static QSGGeometry::Point2D* qskAddLines( const QTransform& transform,
|
||||||
return reinterpret_cast< QSGGeometry::Point2D* >( vlines );
|
return reinterpret_cast< QSGGeometry::Point2D* >( vlines );
|
||||||
}
|
}
|
||||||
|
|
||||||
class QskLinesNodePrivate final : public QSGGeometryNodePrivate
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QskLinesNodePrivate()
|
|
||||||
: geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
|
|
||||||
{
|
|
||||||
geometry.setDrawingMode( QSGGeometry::DrawLines );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline qreal round( bool isHorizontal, qreal v ) const
|
|
||||||
{
|
|
||||||
if ( !doRound )
|
|
||||||
return v;
|
|
||||||
|
|
||||||
const auto r2 = 2.0 * devicePixelRatio;
|
|
||||||
const qreal v0 = isHorizontal ? p0.x() : p0.y();
|
|
||||||
|
|
||||||
const int d = qRound( r2 * ( v + v0 ) );
|
|
||||||
const auto f = ( d % 2 ? d : d - 1 ) / r2;
|
|
||||||
|
|
||||||
return f / devicePixelRatio - v0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void setLineAttributes( QskLinesNode* node,
|
|
||||||
const QColor& color, float lineWidth )
|
|
||||||
{
|
|
||||||
if ( color != material.color() )
|
|
||||||
{
|
|
||||||
material.setColor( color );
|
|
||||||
node->markDirty( QSGNode::DirtyMaterial );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( lineWidth != geometry.lineWidth() )
|
|
||||||
geometry.setLineWidth( lineWidth );
|
|
||||||
}
|
|
||||||
|
|
||||||
QSGGeometry geometry;
|
|
||||||
QSGFlatColorMaterial material;
|
|
||||||
|
|
||||||
// position of [0,0] in device coordinates
|
|
||||||
QPointF p0;
|
|
||||||
qreal devicePixelRatio = 1.0;
|
|
||||||
|
|
||||||
QskHashValue hash = 0.0;
|
|
||||||
|
|
||||||
bool dirty = true;
|
|
||||||
bool doRound = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
QskLinesNode::QskLinesNode()
|
QskLinesNode::QskLinesNode()
|
||||||
: QSGGeometryNode( *new QskLinesNodePrivate )
|
|
||||||
{
|
{
|
||||||
Q_D( QskLinesNode );
|
|
||||||
|
|
||||||
setGeometry( &d->geometry );
|
|
||||||
setMaterial( &d->material );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QskLinesNode::~QskLinesNode()
|
QskLinesNode::~QskLinesNode()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskLinesNode::setGlobalPosition( const QQuickItem* item )
|
|
||||||
{
|
|
||||||
QPointF p0;
|
|
||||||
qreal devicePixelRatio = 1.0;
|
|
||||||
|
|
||||||
if ( item )
|
|
||||||
{
|
|
||||||
p0 = item->mapToGlobal( QPointF() );
|
|
||||||
|
|
||||||
if ( auto w = item->window() )
|
|
||||||
devicePixelRatio = w->devicePixelRatio();
|
|
||||||
}
|
|
||||||
|
|
||||||
setGlobalPosition( p0, devicePixelRatio );
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskLinesNode::setGlobalPosition(
|
|
||||||
const QPointF& pos, qreal devicePixelRatio )
|
|
||||||
{
|
|
||||||
Q_D( QskLinesNode );
|
|
||||||
|
|
||||||
if ( d->doRound == false )
|
|
||||||
{
|
|
||||||
d->doRound = true;
|
|
||||||
d->dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( pos != d->p0 || devicePixelRatio != d->devicePixelRatio )
|
|
||||||
{
|
|
||||||
d->p0 = pos;
|
|
||||||
d->devicePixelRatio = devicePixelRatio;
|
|
||||||
|
|
||||||
d->dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskLinesNode::resetGlobalPosition()
|
|
||||||
{
|
|
||||||
Q_D( QskLinesNode );
|
|
||||||
|
|
||||||
if ( d->doRound == true )
|
|
||||||
{
|
|
||||||
d->doRound = false;
|
|
||||||
d->dirty = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QskLinesNode::updateRect( const QColor& color,
|
void QskLinesNode::updateRect( const QColor& color,
|
||||||
qreal lineWidth, const QskStippleMetrics& stippleMetrics,
|
qreal lineWidth, const QskStippleMetrics& stippleMetrics,
|
||||||
const QTransform& transform, const QRectF& rect )
|
const QTransform& transform, const QRectF& rect )
|
||||||
|
|
@ -272,8 +163,6 @@ void QskLinesNode::updateLines( const QColor& color,
|
||||||
qreal lineWidth, const QskStippleMetrics& stippleMetrics,
|
qreal lineWidth, const QskStippleMetrics& stippleMetrics,
|
||||||
const QTransform& transform, int count, const QLineF* lines )
|
const QTransform& transform, int count, const QLineF* lines )
|
||||||
{
|
{
|
||||||
Q_D( QskLinesNode );
|
|
||||||
|
|
||||||
if ( !stippleMetrics.isValid() || !color.isValid()
|
if ( !stippleMetrics.isValid() || !color.isValid()
|
||||||
|| color.alpha() == 0 || count == 0 )
|
|| color.alpha() == 0 || count == 0 )
|
||||||
{
|
{
|
||||||
|
|
@ -287,22 +176,18 @@ void QskLinesNode::updateLines( const QColor& color,
|
||||||
hash = qHash( transform, hash );
|
hash = qHash( transform, hash );
|
||||||
hash = qHashBits( lines, count * sizeof( QLineF ) );
|
hash = qHashBits( lines, count * sizeof( QLineF ) );
|
||||||
|
|
||||||
if ( hash != d->hash )
|
if ( hash != m_hash )
|
||||||
{
|
{
|
||||||
d->dirty = true;
|
m_hash = hash;
|
||||||
d->hash = hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( d->dirty )
|
|
||||||
{
|
|
||||||
updateGeometry( stippleMetrics, transform, count, lines );
|
updateGeometry( stippleMetrics, transform, count, lines );
|
||||||
|
|
||||||
d->geometry.markVertexDataDirty();
|
geometry()->markVertexDataDirty();
|
||||||
markDirty( QSGNode::DirtyGeometry );
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
d->dirty = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d->setLineAttributes( this, color, lineWidth );
|
setLineWidth( lineWidth );
|
||||||
|
setColor( color );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskLinesNode::updateGrid( const QColor& color,
|
void QskLinesNode::updateGrid( const QColor& color,
|
||||||
|
|
@ -310,8 +195,6 @@ void QskLinesNode::updateGrid( const QColor& color,
|
||||||
const QTransform& transform, const QRectF& rect,
|
const QTransform& transform, const QRectF& rect,
|
||||||
const QVector< qreal >& xValues, const QVector< qreal >& yValues )
|
const QVector< qreal >& xValues, const QVector< qreal >& yValues )
|
||||||
{
|
{
|
||||||
Q_D( QskLinesNode );
|
|
||||||
|
|
||||||
if ( !stippleMetrics.isValid() || !color.isValid() || color.alpha() == 0 )
|
if ( !stippleMetrics.isValid() || !color.isValid() || color.alpha() == 0 )
|
||||||
{
|
{
|
||||||
QskSGNode::resetGeometry( this );
|
QskSGNode::resetGeometry( this );
|
||||||
|
|
@ -326,30 +209,24 @@ void QskLinesNode::updateGrid( const QColor& color,
|
||||||
hash = qHash( xValues, hash );
|
hash = qHash( xValues, hash );
|
||||||
hash = qHash( yValues, hash );
|
hash = qHash( yValues, hash );
|
||||||
|
|
||||||
if ( hash != d->hash )
|
if ( hash != m_hash )
|
||||||
{
|
{
|
||||||
d->dirty = true;
|
m_hash = hash;
|
||||||
d->hash = hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( d->dirty )
|
|
||||||
{
|
|
||||||
updateGeometry( stippleMetrics, transform, rect, xValues, yValues );
|
updateGeometry( stippleMetrics, transform, rect, xValues, yValues );
|
||||||
|
|
||||||
d->geometry.markVertexDataDirty();
|
geometry()->markVertexDataDirty();
|
||||||
markDirty( QSGNode::DirtyGeometry );
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
d->dirty = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d->setLineAttributes( this, color, lineWidth );
|
setLineWidth( lineWidth );
|
||||||
|
setColor( color );
|
||||||
}
|
}
|
||||||
|
|
||||||
void QskLinesNode::updateGeometry( const QskStippleMetrics& stippleMetrics,
|
void QskLinesNode::updateGeometry( const QskStippleMetrics& stippleMetrics,
|
||||||
const QTransform& transform, int count, const QLineF* lines )
|
const QTransform& transform, int count, const QLineF* lines )
|
||||||
{
|
{
|
||||||
Q_D( QskLinesNode );
|
auto& geom = *geometry();
|
||||||
|
|
||||||
auto& geom = d->geometry;
|
|
||||||
|
|
||||||
QSGGeometry::Point2D* points = nullptr;
|
QSGGeometry::Point2D* points = nullptr;
|
||||||
|
|
||||||
|
|
@ -382,8 +259,8 @@ void QskLinesNode::updateGeometry( const QskStippleMetrics& stippleMetrics,
|
||||||
lineCount += renderer.dashCount( p1, p2 );
|
lineCount += renderer.dashCount( p1, p2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
d->geometry.allocate( 2 * lineCount );
|
geometry()->allocate( 2 * lineCount );
|
||||||
points = d->geometry.vertexDataAsPoint2D();
|
points = geometry()->vertexDataAsPoint2D();
|
||||||
|
|
||||||
points = qskAddDashes( transform,
|
points = qskAddDashes( transform,
|
||||||
count, lines, stippleMetrics, points );
|
count, lines, stippleMetrics, points );
|
||||||
|
|
@ -397,9 +274,7 @@ void QskLinesNode::updateGeometry(
|
||||||
const QTransform& transform, const QRectF& rect,
|
const QTransform& transform, const QRectF& rect,
|
||||||
const QVector< qreal >& xValues, const QVector< qreal >& yValues )
|
const QVector< qreal >& xValues, const QVector< qreal >& yValues )
|
||||||
{
|
{
|
||||||
Q_D( QskLinesNode );
|
auto& geom = *geometry();
|
||||||
|
|
||||||
auto& geom = d->geometry;
|
|
||||||
|
|
||||||
const auto y1 = mapY( transform, rect.top() );
|
const auto y1 = mapY( transform, rect.top() );
|
||||||
const auto y2 = mapY( transform, rect.bottom() );
|
const auto y2 = mapY( transform, rect.bottom() );
|
||||||
|
|
@ -430,8 +305,8 @@ void QskLinesNode::updateGeometry(
|
||||||
const auto countY = renderer.dashCount( x1, 0.0, x2, 0.0 );
|
const auto countY = renderer.dashCount( x1, 0.0, x2, 0.0 );
|
||||||
const auto count = xValues.count() * countX + yValues.count() * countY;
|
const auto count = xValues.count() * countX + yValues.count() * countY;
|
||||||
|
|
||||||
d->geometry.allocate( 2 * count );
|
geometry()->allocate( 2 * count );
|
||||||
points = d->geometry.vertexDataAsPoint2D();
|
points = geometry()->vertexDataAsPoint2D();
|
||||||
|
|
||||||
points = setStippledLines( Qt::Vertical, y1, y2,
|
points = setStippledLines( Qt::Vertical, y1, y2,
|
||||||
transform, xValues.count(), xValues.constData(),
|
transform, xValues.count(), xValues.constData(),
|
||||||
|
|
@ -450,8 +325,6 @@ QSGGeometry::Point2D* QskLinesNode::setStippledLines(
|
||||||
const QTransform& transform, int count, const qreal* values,
|
const QTransform& transform, int count, const qreal* values,
|
||||||
const QskStippleMetrics& stippleMetrics, QSGGeometry::Point2D* points ) const
|
const QskStippleMetrics& stippleMetrics, QSGGeometry::Point2D* points ) const
|
||||||
{
|
{
|
||||||
Q_D( const QskLinesNode );
|
|
||||||
|
|
||||||
if ( count <= 0 )
|
if ( count <= 0 )
|
||||||
return points;
|
return points;
|
||||||
|
|
||||||
|
|
@ -464,16 +337,14 @@ QSGGeometry::Point2D* QskLinesNode::setStippledLines(
|
||||||
|
|
||||||
if ( orientation == Qt::Vertical )
|
if ( orientation == Qt::Vertical )
|
||||||
{
|
{
|
||||||
auto x = mapX( transform, values[0] );
|
const auto x = mapX( transform, values[0] );
|
||||||
x = d->round( true, x );
|
|
||||||
|
|
||||||
points = renderer.addDashes( points, x, v1, x, v2 );
|
points = renderer.addDashes( points, x, v1, x, v2 );
|
||||||
dashCount = points - line0;
|
dashCount = points - line0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto y = mapY( transform, values[0] );
|
const auto y = mapY( transform, values[0] );
|
||||||
y = d->round( false, y );
|
|
||||||
|
|
||||||
points = renderer.addDashes( points, v1, y, v2, y );
|
points = renderer.addDashes( points, v1, y, v2, y );
|
||||||
dashCount = points - line0;
|
dashCount = points - line0;
|
||||||
|
|
@ -485,8 +356,7 @@ QSGGeometry::Point2D* QskLinesNode::setStippledLines(
|
||||||
{
|
{
|
||||||
for ( int i = 1; i < count; i++ )
|
for ( int i = 1; i < count; i++ )
|
||||||
{
|
{
|
||||||
auto x = mapX( transform, values[i] );
|
const auto x = mapX( transform, values[i] );
|
||||||
x = d->round( true, x );
|
|
||||||
|
|
||||||
for ( int j = 0; j < dashCount; j++ )
|
for ( int j = 0; j < dashCount; j++ )
|
||||||
points++->set( x, line0[j].y );
|
points++->set( x, line0[j].y );
|
||||||
|
|
@ -496,8 +366,7 @@ QSGGeometry::Point2D* QskLinesNode::setStippledLines(
|
||||||
{
|
{
|
||||||
for ( int i = 1; i < count; i++ )
|
for ( int i = 1; i < count; i++ )
|
||||||
{
|
{
|
||||||
auto y = mapY( transform, values[i] );
|
const auto y = mapY( transform, values[i] );
|
||||||
y = d->round( false, y );
|
|
||||||
|
|
||||||
for ( int j = 0; j < dashCount; j++ )
|
for ( int j = 0; j < dashCount; j++ )
|
||||||
points++->set( line0[j].x, y );
|
points++->set( line0[j].x, y );
|
||||||
|
|
@ -512,8 +381,6 @@ QSGGeometry::Point2D* QskLinesNode::setSolidLines(
|
||||||
const QTransform& transform, int count, const qreal* values,
|
const QTransform& transform, int count, const qreal* values,
|
||||||
QSGGeometry::Point2D* points ) const
|
QSGGeometry::Point2D* points ) const
|
||||||
{
|
{
|
||||||
Q_D( const QskLinesNode );
|
|
||||||
|
|
||||||
if ( count <= 0 )
|
if ( count <= 0 )
|
||||||
return points;
|
return points;
|
||||||
|
|
||||||
|
|
@ -523,9 +390,7 @@ QSGGeometry::Point2D* QskLinesNode::setSolidLines(
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < count; i++ )
|
for ( int i = 0; i < count; i++ )
|
||||||
{
|
{
|
||||||
auto x = mapX( transform, values[i] );
|
const auto x = mapX( transform, values[i] );
|
||||||
x = d->round( true, x );
|
|
||||||
|
|
||||||
lines++->setVLine( x, v1, v2 );
|
lines++->setVLine( x, v1, v2 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -533,9 +398,7 @@ QSGGeometry::Point2D* QskLinesNode::setSolidLines(
|
||||||
{
|
{
|
||||||
for ( int i = 0; i < count; i++ )
|
for ( int i = 0; i < count; i++ )
|
||||||
{
|
{
|
||||||
auto y = mapY( transform, values[i] );
|
const auto y = mapY( transform, values[i] );
|
||||||
y = d->round( false, y );
|
|
||||||
|
|
||||||
lines++->setHLine( v1, v2, y );
|
lines++->setHLine( v1, v2, y );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -552,13 +415,11 @@ void QskLinesNode::updatePolygon( const QColor& color, qreal lineWidth,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_D( QskLinesNode );
|
|
||||||
|
|
||||||
if ( true ) // for the moment we always update the geometry. TODO ...
|
if ( true ) // for the moment we always update the geometry. TODO ...
|
||||||
{
|
{
|
||||||
d->geometry.allocate( polygon.count() + 1 );
|
geometry()->allocate( polygon.count() + 1 );
|
||||||
|
|
||||||
auto points = d->geometry.vertexDataAsPoint2D();
|
auto points = geometry()->vertexDataAsPoint2D();
|
||||||
|
|
||||||
if ( transform.isIdentity() )
|
if ( transform.isIdentity() )
|
||||||
{
|
{
|
||||||
|
|
@ -579,9 +440,10 @@ void QskLinesNode::updatePolygon( const QColor& color, qreal lineWidth,
|
||||||
|
|
||||||
points[ polygon.count() ] = points[0];
|
points[ polygon.count() ] = points[0];
|
||||||
|
|
||||||
d->geometry.markVertexDataDirty();
|
geometry()->markVertexDataDirty();
|
||||||
markDirty( QSGNode::DirtyGeometry );
|
markDirty( QSGNode::DirtyGeometry );
|
||||||
}
|
}
|
||||||
|
|
||||||
d->setLineAttributes( this, color, lineWidth );
|
setLineWidth( lineWidth );
|
||||||
|
setColor( color );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,9 +6,7 @@
|
||||||
#ifndef QSK_LINES_NODE_H
|
#ifndef QSK_LINES_NODE_H
|
||||||
#define QSK_LINES_NODE_H
|
#define QSK_LINES_NODE_H
|
||||||
|
|
||||||
#include "QskGlobal.h"
|
#include "QskBasicLinesNode.h"
|
||||||
|
|
||||||
#include <qsgnode.h>
|
|
||||||
#include <qvector.h>
|
#include <qvector.h>
|
||||||
|
|
||||||
class QskIntervalF;
|
class QskIntervalF;
|
||||||
|
|
@ -17,26 +15,19 @@ class QTransform;
|
||||||
class QPointF;
|
class QPointF;
|
||||||
class QLineF;
|
class QLineF;
|
||||||
class QPolygonF;
|
class QPolygonF;
|
||||||
class QQuickItem;
|
|
||||||
|
|
||||||
class QskLinesNodePrivate;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A node for stippled or solid lines.
|
A node for stippled or solid lines.
|
||||||
For the moment limited to horizontal/vertical lines: TODO
|
For the moment limited to horizontal/vertical lines: TODO
|
||||||
*/
|
*/
|
||||||
class QSK_EXPORT QskLinesNode : public QSGGeometryNode
|
class QSK_EXPORT QskLinesNode : public QskBasicLinesNode
|
||||||
{
|
{
|
||||||
using Inherited = QSGGeometryNode;
|
using Inherited = QskBasicLinesNode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QskLinesNode();
|
QskLinesNode();
|
||||||
~QskLinesNode() override;
|
~QskLinesNode() override;
|
||||||
|
|
||||||
void setGlobalPosition( const QPointF&, qreal devicePixelRatio );
|
|
||||||
void setGlobalPosition( const QQuickItem* );
|
|
||||||
void resetGlobalPosition();
|
|
||||||
|
|
||||||
void updateGrid( const QColor&, qreal lineWidth,
|
void updateGrid( const QColor&, qreal lineWidth,
|
||||||
const QskStippleMetrics&, const QTransform&, const QRectF&,
|
const QskStippleMetrics&, const QTransform&, const QRectF&,
|
||||||
const QVector< qreal >&, const QVector< qreal >& );
|
const QVector< qreal >&, const QVector< qreal >& );
|
||||||
|
|
@ -80,7 +71,7 @@ class QSK_EXPORT QskLinesNode : public QSGGeometryNode
|
||||||
const QTransform&, int count, const qreal* values,
|
const QTransform&, int count, const qreal* values,
|
||||||
const QskStippleMetrics&, QSGGeometry::Point2D* ) const;
|
const QskStippleMetrics&, QSGGeometry::Point2D* ) const;
|
||||||
|
|
||||||
Q_DECLARE_PRIVATE( QskLinesNode )
|
QskHashValue m_hash = 0.0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -22,5 +22,9 @@
|
||||||
<file>shaders/gradientlinear.vert</file>
|
<file>shaders/gradientlinear.vert</file>
|
||||||
<file>shaders/gradientlinear.frag</file>
|
<file>shaders/gradientlinear.frag</file>
|
||||||
|
|
||||||
|
<file>shaders/crisplines.vert.qsb</file>
|
||||||
|
<file>shaders/crisplines.frag.qsb</file>
|
||||||
|
<file>shaders/crisplines.vert</file>
|
||||||
|
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,15 @@
|
||||||
|
#version 440
|
||||||
|
|
||||||
|
layout( location = 0 ) out vec4 fragColor;
|
||||||
|
|
||||||
|
layout( std140, binding = 0 ) uniform buf
|
||||||
|
{
|
||||||
|
mat4 matrix;
|
||||||
|
vec4 color;
|
||||||
|
vec2 size;
|
||||||
|
} ubuf;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
fragColor = ubuf.color;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
#version 440
|
||||||
|
|
||||||
|
layout( location = 0 ) in vec4 vertexCoord;
|
||||||
|
|
||||||
|
layout( std140, binding = 0 ) uniform buf
|
||||||
|
{
|
||||||
|
mat4 matrix;
|
||||||
|
vec4 color;
|
||||||
|
vec2 size;
|
||||||
|
} ubuf;
|
||||||
|
|
||||||
|
out gl_PerVertex { vec4 gl_Position; };
|
||||||
|
|
||||||
|
float normalized( in float pos, in float scale, in float size )
|
||||||
|
{
|
||||||
|
return ( ( pos / size - 0.5 ) / 0.5 ) * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
float denormalized( in float pos, in float scale, in float size )
|
||||||
|
{
|
||||||
|
return ( ( pos / scale ) * 0.5 + 0.5 ) * size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = ubuf.matrix * vertexCoord;
|
||||||
|
|
||||||
|
if ( ubuf.size.x > 0.0 )
|
||||||
|
{
|
||||||
|
gl_Position.x = denormalized( gl_Position.x, gl_Position.w, ubuf.size.x );
|
||||||
|
gl_Position.x = round( gl_Position.x ) + 0.5;
|
||||||
|
gl_Position.x = normalized( gl_Position.x, gl_Position.w, ubuf.size.x );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ubuf.size.y > 0.0 )
|
||||||
|
{
|
||||||
|
gl_Position.y = denormalized( gl_Position.y, gl_Position.w, ubuf.size.y );
|
||||||
|
gl_Position.y = round( gl_Position.y ) + 0.5;
|
||||||
|
gl_Position.y = normalized( gl_Position.y, gl_Position.w, ubuf.size.y );
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,38 @@
|
||||||
|
attribute highp vec4 in_vertex;
|
||||||
|
uniform highp mat4 matrix;
|
||||||
|
|
||||||
|
uniform lowp vec2 size;
|
||||||
|
|
||||||
|
float normalized( in float pos, in float scale, in float size )
|
||||||
|
{
|
||||||
|
return ( ( pos / size - 0.5 ) / 0.5 ) * scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
float denormalized( in float pos, in float scale, in float size )
|
||||||
|
{
|
||||||
|
return ( ( pos / scale ) * 0.5 + 0.5 ) * size;
|
||||||
|
}
|
||||||
|
|
||||||
|
float round( in float v )
|
||||||
|
{
|
||||||
|
return floor( v + 0.5 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = matrix * in_vertex;
|
||||||
|
|
||||||
|
if ( size.x > 0.0 )
|
||||||
|
{
|
||||||
|
gl_Position.x = denormalized( gl_Position.x, gl_Position.w, size.x );
|
||||||
|
gl_Position.x = round( gl_Position.x ) + 0.5;
|
||||||
|
gl_Position.x = normalized( gl_Position.x, gl_Position.w, size.x );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( size.y > 0.0 )
|
||||||
|
{
|
||||||
|
gl_Position.y = denormalized( gl_Position.y, gl_Position.w, size.y );
|
||||||
|
gl_Position.y = round( gl_Position.y ) + 0.5;
|
||||||
|
gl_Position.y = normalized( gl_Position.y, gl_Position.w, size.y );
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -16,3 +16,6 @@ qsbcompile gradientradial-vulkan.frag
|
||||||
|
|
||||||
qsbcompile gradientlinear-vulkan.vert
|
qsbcompile gradientlinear-vulkan.vert
|
||||||
qsbcompile gradientlinear-vulkan.frag
|
qsbcompile gradientlinear-vulkan.frag
|
||||||
|
|
||||||
|
qsbcompile crisplines-vulkan.vert
|
||||||
|
qsbcompile crisplines-vulkan.frag
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue