QskBasicLinesNode completed

This commit is contained in:
Uwe Rathmann 2023-11-24 13:07:53 +01:00
parent f3a1de5b00
commit 534ffb41e1
7 changed files with 68 additions and 72 deletions

View File

@ -13,6 +13,21 @@ QSK_QT_PRIVATE_BEGIN
#include <private/qsgnode_p.h>
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 <QSGMaterialRhiShader>
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 );

View File

@ -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;

View File

@ -6,7 +6,7 @@ layout( std140, binding = 0 ) uniform buf
{
mat4 matrix;
vec4 color;
vec2 size;
vec2 origin;
} ubuf;
void main()

View File

@ -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;
}

View File

@ -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;
}