6#include "QskBasicLinesNode.h"
8#include <qsgmaterial.h>
9#include <qsggeometry.h>
13#include <private/qsgnode_p.h>
16static inline QVector4D qskColorVector(
const QColor& c, qreal opacity)
18 const auto a = c.alphaF() * opacity;
19 return QVector4D( c.redF() * a, c.greenF() * a, c.blueF() * a, a );
22static inline QVector2D qskOrigin(
23 const QRect& rect, Qt::Orientations orientations )
26 ( orientations & Qt::Horizontal ) ? 0.5 * rect.width() : 0.0,
27 ( orientations & Qt::Vertical ) ? 0.5 * rect.height() : 0.0
31#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
32 #include <QSGMaterialRhiShader>
33 using RhiShader = QSGMaterialRhiShader;
35 using RhiShader = QSGMaterialShader;
40 class Material final :
public QSGMaterial
45#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
46 QSGMaterialShader* createShader()
const override;
48 QSGMaterialShader* createShader( QSGRendererInterface::RenderMode )
const override;
51 QSGMaterialType* type()
const override;
53 int compare(
const QSGMaterial* other )
const override;
55 QColor m_color = QColor( 255, 255, 255 );
56 Qt::Orientations m_pixelAlignment;
59 class ShaderRhi final :
public RhiShader
65 const QString root(
":/qskinny/shaders/" );
67 setShaderFileName( VertexStage, root +
"crisplines.vert.qsb" );
68 setShaderFileName( FragmentStage, root +
"crisplines.frag.qsb" );
71 bool updateUniformData( RenderState& state,
72 QSGMaterial* newMaterial, QSGMaterial* oldMaterial )
override
74 auto matOld =
static_cast< Material*
>( oldMaterial );
75 auto matNew =
static_cast< Material*
>( newMaterial );
77 Q_ASSERT( state.uniformData()->size() >= 88 );
79 auto data = state.uniformData()->data();
82 const auto matrix = state.combinedMatrix();
84 if ( state.isMatrixDirty() )
86 memcpy( data + 0, matrix.constData(), 64 );
90 if ( ( matOld ==
nullptr ) || ( matNew->m_color != matOld->m_color )
91 || state.isOpacityDirty() )
93 const auto v4 = qskColorVector( matNew->m_color, state.opacity() );
94 memcpy( data + 64, &v4, 16 );
98 if ( state.isMatrixDirty() || ( matOld ==
nullptr )
99 || ( matNew->m_pixelAlignment != matOld->m_pixelAlignment ) )
108 const auto origin = qskOrigin(
109 state.viewportRect(), matNew->m_pixelAlignment );
111 memcpy( data + 80, &origin, 8 );
120#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
126 class ShaderGL final :
public QSGMaterialShader
131 const QString root(
":/qskinny/shaders/" );
133 setShaderSourceFile( QOpenGLShader::Vertex,
134 ":/qskinny/shaders/crisplines.vert" );
136 setShaderSourceFile( QOpenGLShader::Fragment,
137 ":/qt-project.org/scenegraph/shaders/flatcolor.frag" );
140 char const*
const* attributeNames()
const override
142 static char const*
const names[] = {
"in_vertex",
nullptr };
146 void initialize()
override
148 QSGMaterialShader::initialize();
152 m_matrixId = p->uniformLocation(
"matrix" );
153 m_colorId = p->uniformLocation(
"color" );
154 m_originId = p->uniformLocation(
"origin" );
157 void updateState(
const QSGMaterialShader::RenderState& state,
158 QSGMaterial* newMaterial, QSGMaterial* oldMaterial)
override
162 const auto matrix = state.combinedMatrix();
164 if ( state.isMatrixDirty() )
165 p->setUniformValue( m_matrixId, matrix );
167 bool updateMaterial = ( oldMaterial == nullptr )
168 || newMaterial->compare( oldMaterial ) != 0;
170 updateMaterial |= state.isCachedMaterialDataDirty();
172 if ( updateMaterial )
174 auto material =
static_cast< const Material*
>( newMaterial );
176 p->setUniformValue( m_colorId,
177 qskColorVector( material->m_color, state.opacity() ) );
179 const auto origin = qskOrigin(
180 state.viewportRect(), material->m_pixelAlignment );;
181 p->setUniformValue( m_originId, origin );
196#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
197 setFlag( QSGMaterial::SupportsRhiShader,
true );
201#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
203QSGMaterialShader* Material::createShader()
const
205 if ( !( flags() & QSGMaterial::RhiShaderWanted ) )
206 return new ShaderGL();
208 return new ShaderRhi();
213QSGMaterialShader* Material::createShader( QSGRendererInterface::RenderMode )
const
215 return new ShaderRhi();
220QSGMaterialType* Material::type()
const
222 static QSGMaterialType staticType;
226int Material::compare(
const QSGMaterial* other )
const
228 auto material =
static_cast< const Material*
>( other );
230 if ( ( material->m_color == m_color )
231 && ( material->m_pixelAlignment == m_pixelAlignment ) )
236 return QSGMaterial::compare( other );
239class QskBasicLinesNodePrivate final :
public QSGGeometryNodePrivate
242 QskBasicLinesNodePrivate()
243 : geometry( QSGGeometry::defaultAttributes_Point2D(), 0 )
245 geometry.setDrawingMode( QSGGeometry::DrawLines );
248 QSGGeometry geometry;
252QskBasicLinesNode::QskBasicLinesNode()
253 : QSGGeometryNode( *new QskBasicLinesNodePrivate )
257 setGeometry( &d->geometry );
258 setMaterial( &d->material );
261QskBasicLinesNode::~QskBasicLinesNode()
265void QskBasicLinesNode::setPixelAlignment( Qt::Orientations orientations )
269 if ( orientations != d->material.m_pixelAlignment )
271 d->material.m_pixelAlignment = orientations;
272 markDirty( QSGNode::DirtyMaterial );
276Qt::Orientations QskBasicLinesNode::pixelAlignment()
const
278 return d_func()->material.m_pixelAlignment;
281void QskBasicLinesNode::setColor(
const QColor& color )
285 const auto c = color.toRgb();
286 if ( c != d->material.m_color )
288 d->material.m_color = c;
289 markDirty( QSGNode::DirtyMaterial );
293QColor QskBasicLinesNode::color()
const
295 return d_func()->material.m_color;
298void QskBasicLinesNode::setLineWidth(
float lineWidth )
302 lineWidth = std::max( lineWidth, 0.0f );
303 if( lineWidth != d->geometry.lineWidth() )
304 d->geometry.setLineWidth( lineWidth );
307float QskBasicLinesNode::lineWidth()
const
309 return d_func()->geometry.lineWidth();