From 534ffb41e1e7aef4238871592b5055cf479ea624 Mon Sep 17 00:00:00 2001 From: Uwe Rathmann Date: Fri, 24 Nov 2023 13:07:53 +0100 Subject: [PATCH] QskBasicLinesNode completed --- src/nodes/QskBasicLinesNode.cpp | 73 +++++++++++++---------- src/nodes/QskBasicLinesNode.h | 1 + src/nodes/shaders/crisplines-vulkan.frag | 2 +- src/nodes/shaders/crisplines-vulkan.vert | 32 ++++------ src/nodes/shaders/crisplines.frag.qsb | Bin 869 -> 871 bytes src/nodes/shaders/crisplines.vert | 32 ++++------ src/nodes/shaders/crisplines.vert.qsb | Bin 2510 -> 1865 bytes 7 files changed, 68 insertions(+), 72 deletions(-) diff --git a/src/nodes/QskBasicLinesNode.cpp b/src/nodes/QskBasicLinesNode.cpp index a9f85d4d..93414295 100644 --- a/src/nodes/QskBasicLinesNode.cpp +++ b/src/nodes/QskBasicLinesNode.cpp @@ -13,6 +13,21 @@ QSK_QT_PRIVATE_BEGIN #include QSK_QT_PRIVATE_END +static inline QVector4D qskColorVector( const QColor& c, qreal opacity) +{ + const auto a = c.alphaF() * opacity; + return QVector4D( c.redF() * a, c.greenF() * a, c.blueF() * a, a ); +} + +static inline QVector2D qskOrigin( + const QRect& rect, Qt::Orientations orientations ) +{ + return QVector2D( + ( orientations & Qt::Horizontal ) ? 0.5 * rect.width() : 0.0, + ( orientations & Qt::Vertical ) ? 0.5 * rect.height() : 0.0 + ); +} + #if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) #include using RhiShader = QSGMaterialRhiShader; @@ -37,7 +52,7 @@ namespace int compare( const QSGMaterial* other ) const override; - QVector4D m_color = QVector4D{ 0, 0, 0, 1 }; + QColor m_color = QColor( 255, 255, 255 ); Qt::Orientations m_pixelAlignment; }; @@ -72,27 +87,28 @@ namespace changed = true; } - if ( ( matOld == nullptr ) || ( matNew->m_color != matOld->m_color ) ) + if ( ( matOld == nullptr ) || ( matNew->m_color != matOld->m_color ) + || state.isOpacityDirty() ) { - // state.opacity() TODO ... - memcpy( data + 64, &matNew->m_color, 16 ); + const auto v4 = qskColorVector( matNew->m_color, state.opacity() ); + memcpy( data + 64, &v4, 16 ); changed = true; } if ( state.isMatrixDirty() || ( matOld == nullptr ) || ( matNew->m_pixelAlignment != matOld->m_pixelAlignment ) ) { - const auto r = state.viewportRect(); + /* + The shaders work with coordinates in the range[-1,1]. When knowing + the device coordinates corresponding to [0.0] we can scale a vertex + into device coordinates. - QVector2D size; + coordinates <= 0.0 indicate, that no rounding should be done. + */ + const auto origin = qskOrigin( + state.viewportRect(), matNew->m_pixelAlignment ); - if ( matNew->m_pixelAlignment & Qt::Horizontal ) - size.setX( r.width() ); - - if ( matNew->m_pixelAlignment & Qt::Vertical ) - size.setY( r.height() ); - - memcpy( data + 80, &size, 8 ); + memcpy( data + 80, &origin, 8 ); changed = true; } @@ -135,7 +151,7 @@ namespace m_matrixId = p->uniformLocation( "matrix" ); m_colorId = p->uniformLocation( "color" ); - m_sizeId = p->uniformLocation( "size" ); + m_originId = p->uniformLocation( "origin" ); } void updateState( const QSGMaterialShader::RenderState& state, @@ -157,26 +173,19 @@ namespace { auto material = static_cast< const Material* >( newMaterial ); - p->setUniformValue( m_colorId, material->m_color ); + p->setUniformValue( m_colorId, + qskColorVector( material->m_color, state.opacity() ) ); - const auto r = state.viewportRect(); - - QVector2D size; - - if ( material->m_pixelAlignment & Qt::Horizontal ) - size.setX( r.width() ); - - if ( material->m_pixelAlignment & Qt::Vertical ) - size.setY( r.height() ); - - p->setUniformValue( m_sizeId, size ); + const auto origin = qskOrigin( + state.viewportRect(), material->m_pixelAlignment );; + p->setUniformValue( m_originId, origin ); } } private: int m_matrixId = -1; int m_colorId = -1; - int m_sizeId = -1; + int m_originId = -1; }; } @@ -273,10 +282,7 @@ 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 ); - + const auto c = color.toRgb(); if ( c != d->material.m_color ) { d->material.m_color = c; @@ -284,6 +290,11 @@ void QskBasicLinesNode::setColor( const QColor& color ) } } +QColor QskBasicLinesNode::color() const +{ + return d_func()->material.m_color; +} + void QskBasicLinesNode::setLineWidth( float lineWidth ) { Q_D( QskBasicLinesNode ); diff --git a/src/nodes/QskBasicLinesNode.h b/src/nodes/QskBasicLinesNode.h index 607c9cc5..cbbe02a2 100644 --- a/src/nodes/QskBasicLinesNode.h +++ b/src/nodes/QskBasicLinesNode.h @@ -31,6 +31,7 @@ class QSK_EXPORT QskBasicLinesNode : public QSGGeometryNode Qt::Orientations pixelAlignment() const; void setColor( const QColor& ); + QColor color() const; void setLineWidth( float ); float lineWidth() const; diff --git a/src/nodes/shaders/crisplines-vulkan.frag b/src/nodes/shaders/crisplines-vulkan.frag index a4618fe9..6c6cf664 100644 --- a/src/nodes/shaders/crisplines-vulkan.frag +++ b/src/nodes/shaders/crisplines-vulkan.frag @@ -6,7 +6,7 @@ layout( std140, binding = 0 ) uniform buf { mat4 matrix; vec4 color; - vec2 size; + vec2 origin; } ubuf; void main() diff --git a/src/nodes/shaders/crisplines-vulkan.vert b/src/nodes/shaders/crisplines-vulkan.vert index e572cda7..b4e140c4 100644 --- a/src/nodes/shaders/crisplines-vulkan.vert +++ b/src/nodes/shaders/crisplines-vulkan.vert @@ -6,36 +6,28 @@ layout( std140, binding = 0 ) uniform buf { mat4 matrix; vec4 color; - vec2 size; + vec2 origin; } 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; + vec4 pos = ubuf.matrix * vertexCoord; - if ( ubuf.size.x > 0.0 ) + if ( ubuf.origin.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 ); + pos.x = ( pos.x + 1.0 ) * ubuf.origin.x; + pos.x = round( pos.x ) + 0.5; + pos.x = pos.x / ubuf.origin.x - 1.0; } - if ( ubuf.size.y > 0.0 ) + if ( ubuf.origin.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 ); + pos.y = ( pos.y + 1.0 ) * ubuf.origin.y; + pos.y = round( pos.y ) + 0.5; + pos.y = pos.y / ubuf.origin.y - 1.0; } + + gl_Position = pos; } diff --git a/src/nodes/shaders/crisplines.frag.qsb b/src/nodes/shaders/crisplines.frag.qsb index 9a0addc5d5f10383cfd457d15d579e434113d5c7..fb01e7de9c15f8fe71bad655c574129a2385816f 100644 GIT binary patch literal 871 zcmV-t1DN~(011kCoXu9-Zqq;z-6m;Eo%GJ_2^k`xL`cCzDMEx+MMYesN>mgoq^h!9 z$8i^8J6hW%QkCE6C-5OW^Fh2InAsi2D<|{`Bvx8`XZFn5nKSFOjIkxgScR!E2Xlk< znP3j{*&d770H(+gzi6--149?sDN7-ov1{yO+C4jdH2Jh$Lk_4*6+-a+YX5M* z6(_w`XUoF<6{&~PZWS=k(5Bd*N8OZFz9O42UNs&IW1Rw$MU^A_M2NxX{mRb*$% zlvkJRCGy<{+n~J)#aAi5BsEa^W|%5*F4KOEIG3f)%69|oRmulze?ayc*%-f0Smb;R zXOvj}d0<{Yz=K*phbLk;h#xt&sm4w6??A*7*+1cgC-M|lq5h)Lqc@Ik^>a_eJPOT6 zmSqfu=W=PCasO;+_6L!Zbf?@r1g8-vB6SnJ~h6y8Zk`6uuA9bbU+;cmo8x0~c zvD;=OxX;6`F$Rh>!8E^fwjH5JBaec^gPsPqCW3qc?1$bH8c>#0ZU4ZsIArE|N z3eV?p;)%womGO$`iyb(hfLGqH&Zr~lZB-V;3?27#)bGb$(r~S&s!Kr?Q07s;LW=udrw4hY`;yDVVY#Z6hh#H!z25>BYZEh6uVRt z0rr)W+PS3Dr%iW*$W)~>0-z+{vmu;Gu)fS>Ldxj*JX?;$=~XFG5aV;=fu=mcI2{qRf~HS2d|ax3(EPMT{s zojR@Gb)v$IEv({C{W?CDJPoUPa-t$}FYrPwR;?Ot6oM$B%OCy xxouvIRhCgfcl|@sgpZWoDEPdjqA#oPbxnS^8U0UG=*rZ7<}2dl_zl9k|&Uix0&KFMi75`=h$RK(a)srUi~i;*Ifa$GK( z>uK&T+)E8D`4{3Z@Q3)>U*s3jncca&LWGR77eV-+UH9L!BN zWFfPd!}eLgMli$F;};E97#Oy|`YeG^BuujPd&R2^bD4QS9RsDyCSccSZ%^@CPZt`q z3mNRG+v-?k5ip)J4(k%kLnaIRt7C!QgB&U~%B6Z070}?kYlLn<4yZ{DLh$|apm)%U z;z6skZQ%Z@&_e3A20mCCPS0|E#FrSBSr%9o<6(u^ZQ_3g_A;&Kg*~6y^~@*7s!Yn3 zVsqrTr(h+*4#j!p48yZm;eD65Qu_|sTi{g^c3D(~>l?5_v2>U>!M{r4RRmTMohegZ zU9y)5y9KsJdlibWQG7{gAoERqYQ(uh`^&_+B6OD6b+FecAFTa8+3RFu{08|V=OZ|y z#PZJq^ZEe@YW)nJ=(|b$$gx8;ZV|o<5ldwMgcBZ%Q&@%ii^hQ7IKI`-co?~XuRk;l zZ5(pj71pWioR0P3D6r!04D9*n;3IS=T>+eNyQAB|CWs`6q2)ZcV(ZvA(RYMri%6%MR;X>l z^6@#Zt!@0L`F>II{hH^y{g3hul2}F!A;*0gc}Wr3?v?rDHErkV&waPSb;v_;;1fOM zjvK{1Z1jzkHw-?Rp7jBE#m(wWI)dJmMM2EivOfmHVZ`HxZ8T+7(p5T&JPLjt)vqo6 zP=tcpc2lYXx>~Vor?jdNqycx;VK_~SBi`@33>N3J(`fREPcE?mRN^&Q=}JRU(mxGthD`~Ar7gnGwGbLEy( zpYwZ8M3}FEHT=LHpgRfR7r`?Y5DA5ftuGy5r4^b_MZuRq`dIs~(@ diff --git a/src/nodes/shaders/crisplines.vert b/src/nodes/shaders/crisplines.vert index 41d01bac..2a1e26af 100644 --- a/src/nodes/shaders/crisplines.vert +++ b/src/nodes/shaders/crisplines.vert @@ -1,17 +1,7 @@ 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; -} +uniform lowp vec2 origin; float round( in float v ) { @@ -20,19 +10,21 @@ float round( in float v ) void main() { - gl_Position = matrix * in_vertex; + vec4 pos = matrix * in_vertex; - if ( size.x > 0.0 ) + if ( origin.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 ); + pos.x = ( pos.x + 1.0 ) * origin.x; + pos.x = round( pos.x ) + 0.5; + pos.x = pos.x / origin.x - 1.0; } - if ( size.y > 0.0 ) + if ( origin.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 ); + pos.y = ( pos.y + 1.0 ) * origin.y; + pos.y = round( pos.y ) + 0.5; + pos.y = pos.y / origin.y - 1.0; } + + gl_Position = pos; } diff --git a/src/nodes/shaders/crisplines.vert.qsb b/src/nodes/shaders/crisplines.vert.qsb index 27f5213f1e69491abe0f393feb12b3de8da180d5..c25564dc76331f0b0e59e779c36330edbf3c63ff 100644 GIT binary patch literal 1865 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