QskBasicLinesNode ( crisplines shaders ) introduced
This commit is contained in:
parent
16754b4f9d
commit
dc64f21901
@ -97,6 +97,7 @@ list(APPEND SOURCES
|
||||
|
||||
list(APPEND HEADERS
|
||||
nodes/QskArcNode.h
|
||||
nodes/QskBasicLinesNode.h
|
||||
nodes/QskBoxNode.h
|
||||
nodes/QskBoxClipNode.h
|
||||
nodes/QskBoxFillNode.h
|
||||
@ -133,6 +134,7 @@ list(APPEND PRIVATE_HEADERS
|
||||
|
||||
list(APPEND SOURCES
|
||||
nodes/QskArcNode.cpp
|
||||
nodes/QskBasicLinesNode.cpp
|
||||
nodes/QskBoxNode.cpp
|
||||
nodes/QskBoxClipNode.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.frag</file>
|
||||
|
||||
<file>shaders/crisplines.vert.qsb</file>
|
||||
<file>shaders/crisplines.frag.qsb</file>
|
||||
|
||||
</qresource>
|
||||
</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.frag
|
||||
|
||||
qsbcompile crisplines-vulkan.vert
|
||||
qsbcompile crisplines-vulkan.frag
|
||||
|
Loading…
x
Reference in New Issue
Block a user