QskBasicLinesNode ( crisplines shaders ) introduced
This commit is contained in:
parent
16754b4f9d
commit
dc64f21901
@ -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
|
||||||
|
190
src/nodes/QskBasicLinesNode.cpp
Normal file
190
src/nodes/QskBasicLinesNode.cpp
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* 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
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class Material final : public QSGMaterial
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Material();
|
||||||
|
|
||||||
|
QSGMaterialShader* createShader( QSGRendererInterface::RenderMode ) const override;
|
||||||
|
|
||||||
|
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 QSGMaterialShader
|
||||||
|
{
|
||||||
|
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 ) )
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Material::Material()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QSGMaterialShader* Material::createShader( QSGRendererInterface::RenderMode ) const
|
||||||
|
{
|
||||||
|
return new ShaderRhi();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 )
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
42
src/nodes/QskBasicLinesNode.h
Normal file
42
src/nodes/QskBasicLinesNode.h
Normal file
@ -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
|
@ -22,5 +22,8 @@
|
|||||||
<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>
|
||||||
|
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
15
src/nodes/shaders/crisplines-vulkan.frag
Normal file
15
src/nodes/shaders/crisplines-vulkan.frag
Normal file
@ -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;
|
||||||
|
}
|
41
src/nodes/shaders/crisplines-vulkan.vert
Normal file
41
src/nodes/shaders/crisplines-vulkan.vert
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
}
|
BIN
src/nodes/shaders/crisplines.frag.qsb
Normal file
BIN
src/nodes/shaders/crisplines.frag.qsb
Normal file
Binary file not shown.
BIN
src/nodes/shaders/crisplines.vert.qsb
Normal file
BIN
src/nodes/shaders/crisplines.vert.qsb
Normal file
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…
x
Reference in New Issue
Block a user