Compare commits
61 Commits
master
...
features/e
Author | SHA1 | Date |
---|---|---|
|
d1153d3707 | |
|
3834597d51 | |
|
4438498e6f | |
|
92a8c7e395 | |
|
e8657d72ff | |
|
c5bdecce00 | |
|
9cedf5f71b | |
|
f0c8de601f | |
|
621923c5dd | |
|
c3aea9a4a3 | |
|
fb4494bdbb | |
|
3121f0b5c7 | |
|
cb583abc38 | |
|
242f063925 | |
|
d397e4f26a | |
|
02a63cdd76 | |
|
e49da68ab3 | |
|
dd1136a32b | |
|
bba0a680bf | |
|
56b1ecf707 | |
|
cb9b83bbca | |
|
ccb79967f4 | |
|
a79650a76e | |
|
ac2ee95962 | |
|
880ae2abdf | |
|
6ad68a6da8 | |
|
e1069d9292 | |
|
ec5bb05f4a | |
|
0b0933122c | |
|
5e0eaf9f6d | |
|
4184e4ccf8 | |
|
583cf4e87f | |
|
f3ee4749b8 | |
|
f9674760c0 | |
|
717960f15f | |
|
862e566507 | |
|
361b5d532e | |
|
0df5775e3e | |
|
d9ebaa8b03 | |
|
7f410a0781 | |
|
a286603676 | |
|
26a05e9b7b | |
|
450d20ec5a | |
|
908d302236 | |
|
06a32bf29b | |
|
e75445e17d | |
|
e0acd82619 | |
|
3e32a14264 | |
|
7837ff6c8c | |
|
728dffd1df | |
|
f4fdc125e6 | |
|
dda2525970 | |
|
245491724d | |
|
048e76d021 | |
|
7615cffdd4 | |
|
162534c13c | |
|
ff1b479938 | |
|
725500fdaf | |
|
7f6e77d53d | |
|
0392f8ea36 | |
|
a90f1c4439 |
|
@ -9,6 +9,7 @@ add_subdirectory(shadows)
|
|||
add_subdirectory(shapes)
|
||||
add_subdirectory(charts)
|
||||
add_subdirectory(plots)
|
||||
add_subdirectory(parrots)
|
||||
|
||||
if (BUILD_INPUTCONTEXT)
|
||||
add_subdirectory(inputpanel)
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
############################################################################
|
||||
# QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
############################################################################
|
||||
|
||||
set(SOURCES
|
||||
Overlay.h Overlay.cpp
|
||||
TextureFilterMaterial.h TextureFilterMaterial.cpp
|
||||
TextureFilterNode.h TextureFilterNode.cpp
|
||||
main.cpp)
|
||||
|
||||
qt_add_resources(SOURCES images.qrc)
|
||||
|
||||
if (QT_VERSION_MAJOR VERSION_LESS 6)
|
||||
qt_add_resources(SOURCES shaders.qrc)
|
||||
endif()
|
||||
|
||||
qsk_add_example(parrots ${SOURCES})
|
||||
|
||||
if (QT_VERSION_MAJOR VERSION_GREATER_EQUAL 6)
|
||||
|
||||
qt6_add_shaders(parrots "shaders"
|
||||
|
||||
BATCHABLE
|
||||
PRECOMPILE
|
||||
|
||||
QUIET
|
||||
|
||||
PREFIX
|
||||
"/shaders"
|
||||
|
||||
FILES
|
||||
shaders/blur-vulkan.vert
|
||||
shaders/blur-vulkan.frag
|
||||
shaders/rgbswap-vulkan.frag
|
||||
|
||||
OUTPUTS
|
||||
blur.vert.qsb
|
||||
blur.frag.qsb
|
||||
rgbswap.vert.qsb
|
||||
)
|
||||
|
||||
endif()
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "Overlay.h"
|
||||
#include "TextureFilterNode.h"
|
||||
#include "TextureFilterMaterial.h"
|
||||
|
||||
#include <QskSkinlet.h>
|
||||
#include <QskQuick.h>
|
||||
#include <QskBoxShapeMetrics.h>
|
||||
#include <QskBoxBorderMetrics.h>
|
||||
#include <QskBoxBorderColors.h>
|
||||
#include <QskGradient.h>
|
||||
#include <QskSceneTexture.h>
|
||||
#include <QskSGNode.h>
|
||||
#include <QskRgbValue.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
class Material final : public TextureFilterMaterial
|
||||
{
|
||||
public:
|
||||
using TextureFilterMaterial::TextureFilterMaterial;
|
||||
|
||||
QSGMaterialType* type() const override
|
||||
{
|
||||
static QSGMaterialType staticType;
|
||||
return &staticType;
|
||||
}
|
||||
};
|
||||
|
||||
class FilterNode final : public TextureFilterNode
|
||||
{
|
||||
public:
|
||||
FilterNode( bool useRhi, QSGTexture* texture )
|
||||
{
|
||||
QString shaders[] = { ":/shaders/blur.vert", ":/shaders/blur.frag" };
|
||||
|
||||
if ( useRhi )
|
||||
{
|
||||
shaders[0] += ".qsb";
|
||||
shaders[1] += ".qsb";
|
||||
}
|
||||
|
||||
setFlag( QSGNode::OwnsMaterial, true );
|
||||
setTextureMaterial( new Material( shaders[0], shaders[1] ) );
|
||||
|
||||
setOwnsTexture( true );
|
||||
setTexture( texture );
|
||||
}
|
||||
};
|
||||
|
||||
class Skinlet final : public QskSkinlet
|
||||
{
|
||||
using Inherited = QskSkinlet;
|
||||
|
||||
public:
|
||||
enum NodeRole { FillRole, BorderRole };
|
||||
|
||||
Skinlet()
|
||||
{
|
||||
setNodeRoles( { FillRole, BorderRole } );
|
||||
}
|
||||
|
||||
QRectF subControlRect( const QskSkinnable*,
|
||||
const QRectF& contentsRect, QskAspect::Subcontrol ) const override
|
||||
{
|
||||
return contentsRect;
|
||||
}
|
||||
|
||||
QSGNode* updateSubNode( const QskSkinnable* skinnable,
|
||||
quint8 nodeRole, QSGNode* node ) const override
|
||||
{
|
||||
const auto overlay = static_cast< const Overlay* >( skinnable );
|
||||
|
||||
switch ( nodeRole )
|
||||
{
|
||||
case FillRole:
|
||||
return updateFillNode( overlay, node );
|
||||
|
||||
case BorderRole:
|
||||
return updateBoxNode( skinnable, node, Overlay::Panel );
|
||||
};
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
QSGNode* updateFillNode( const Overlay* overlay, QSGNode* node ) const
|
||||
{
|
||||
/*
|
||||
There should be a way to avoid the clip node by passing the
|
||||
vertex list directly to the texture node. TODO ...
|
||||
*/
|
||||
using Q = Overlay;
|
||||
|
||||
QSGNode* clipNode = nullptr;
|
||||
QSGNode* textureNode = nullptr;
|
||||
|
||||
if ( node )
|
||||
{
|
||||
if ( node->firstChild() )
|
||||
{
|
||||
clipNode = node;
|
||||
textureNode = node->firstChild();
|
||||
}
|
||||
else
|
||||
{
|
||||
textureNode = node;
|
||||
}
|
||||
}
|
||||
|
||||
textureNode = updateTextureNode( overlay, textureNode );
|
||||
|
||||
if ( overlay->boxShapeHint( Q::Panel ).isRectangle() )
|
||||
{
|
||||
delete clipNode;
|
||||
clipNode = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
clipNode = updateBoxClipNode( overlay, clipNode, Q::Panel );
|
||||
QskSGNode::setParentNode( textureNode, clipNode );
|
||||
}
|
||||
|
||||
return clipNode ? clipNode : textureNode;
|
||||
}
|
||||
|
||||
QSGNode* updateTextureNode( const Overlay* overlay, QSGNode* node ) const
|
||||
{
|
||||
const auto window = overlay->window();
|
||||
|
||||
const auto rect = overlay->subControlRect( Overlay::Panel );
|
||||
if ( rect.isEmpty() )
|
||||
return nullptr;
|
||||
|
||||
auto rootNode = qskScenegraphAnchorNode( window );
|
||||
if ( rootNode == nullptr )
|
||||
return nullptr;
|
||||
|
||||
auto textureNode = static_cast< FilterNode* >( node );
|
||||
if ( textureNode == nullptr )
|
||||
{
|
||||
auto texture = new QskSceneTexture( window );
|
||||
QObject::connect( texture, &QskSceneTexture::updateRequested,
|
||||
overlay, &QQuickItem::update );
|
||||
|
||||
const bool useRhi = qskRenderingHardwareInterface( window );
|
||||
|
||||
textureNode = new FilterNode( useRhi, texture );
|
||||
}
|
||||
|
||||
auto texture = qobject_cast< QskSceneTexture* >( textureNode->texture() );
|
||||
Q_ASSERT( texture );
|
||||
|
||||
if ( texture->isDirty() || rect != textureNode->rect() )
|
||||
{
|
||||
texture->setFiltering(
|
||||
overlay->smooth() ? QSGTexture::Linear : QSGTexture::Nearest );
|
||||
|
||||
auto finalNode = const_cast< QSGTransformNode* >( qskItemNode( overlay ) );
|
||||
|
||||
texture->render( rootNode, finalNode,
|
||||
rect.translated( overlay->position() ) );
|
||||
|
||||
textureNode->markDirty( QSGNode::DirtyMaterial );
|
||||
}
|
||||
|
||||
textureNode->setRect( rect );
|
||||
|
||||
return textureNode;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
QSK_SUBCONTROL( Overlay, Panel )
|
||||
|
||||
Overlay::Overlay( QQuickItem* parent )
|
||||
: Inherited( parent )
|
||||
{
|
||||
setSkinlet( new Skinlet() );
|
||||
|
||||
setBoxBorderMetricsHint( Panel, 1 );
|
||||
setBoxBorderColorsHint( Panel, QskRgb::toTransparent( QskRgb::DarkGrey, 100 ) );
|
||||
setBoxShapeHint( Panel, QskBoxShapeMetrics( 25, Qt::RelativeSize ) );
|
||||
}
|
||||
|
||||
Overlay::~Overlay()
|
||||
{
|
||||
}
|
||||
|
||||
QRectF Overlay::layoutRectForSize( const QSizeF& size ) const
|
||||
{
|
||||
return subControlContentsRect( size, Panel );
|
||||
}
|
||||
|
||||
void Overlay::geometryChange(
|
||||
const QRectF& newGeometry, const QRectF& oldGeometry )
|
||||
{
|
||||
Inherited::geometryChange( newGeometry, oldGeometry );
|
||||
update();
|
||||
}
|
||||
|
||||
#include "moc_Overlay.cpp"
|
|
@ -0,0 +1,26 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QskControl.h>
|
||||
|
||||
class Overlay : public QskControl
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
using Inherited = QskControl;
|
||||
|
||||
public:
|
||||
QSK_SUBCONTROLS( Panel )
|
||||
|
||||
Overlay( QQuickItem* = nullptr );
|
||||
~Overlay() override;
|
||||
|
||||
QRectF layoutRectForSize( const QSizeF& ) const override;
|
||||
|
||||
protected:
|
||||
void geometryChange( const QRectF&, const QRectF& ) override;
|
||||
};
|
|
@ -0,0 +1,216 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "TextureFilterMaterial.h"
|
||||
|
||||
#include <qsgmaterial.h>
|
||||
#include <qsgmaterialshader.h>
|
||||
#include <qsgtexture.h>
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
#include <qsgmaterialrhishader.h>
|
||||
using RhiShader = QSGMaterialRhiShader;
|
||||
#else
|
||||
using RhiShader = QSGMaterialShader;
|
||||
#endif
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
|
||||
namespace
|
||||
{
|
||||
class ShaderGL : public QSGMaterialShader
|
||||
{
|
||||
public:
|
||||
void setSource( QOpenGLShader::ShaderType type, const QString& fileName )
|
||||
{
|
||||
setShaderSourceFile( type, fileName );
|
||||
}
|
||||
|
||||
char const* const* attributeNames() const override
|
||||
{
|
||||
static char const* const names[] = { "in_vertex", "in_coord", nullptr };
|
||||
return names;
|
||||
}
|
||||
|
||||
void initialize() override
|
||||
{
|
||||
QSGMaterialShader::initialize();
|
||||
|
||||
auto p = program();
|
||||
|
||||
m_matrixId = p->uniformLocation( "matrix" );
|
||||
m_opacityId = p->uniformLocation( "opacity" );
|
||||
}
|
||||
|
||||
void updateState( const QSGMaterialShader::RenderState& state,
|
||||
QSGMaterial* newMaterial, QSGMaterial* oldMaterial ) override
|
||||
{
|
||||
auto p = program();
|
||||
|
||||
if ( state.isMatrixDirty() )
|
||||
p->setUniformValue( m_matrixId, state.combinedMatrix() );
|
||||
|
||||
if ( state.isOpacityDirty() )
|
||||
p->setUniformValue( m_opacityId, state.opacity() );
|
||||
|
||||
auto material = static_cast< TextureFilterMaterial* >( newMaterial );
|
||||
|
||||
if ( auto texture = material->texture() )
|
||||
{
|
||||
auto textureId = -1;
|
||||
|
||||
if ( auto oldMat = static_cast< TextureFilterMaterial* >( oldMaterial ) )
|
||||
{
|
||||
if ( oldMat->texture() )
|
||||
textureId = oldMat->texture()->textureId();
|
||||
}
|
||||
|
||||
if ( texture->textureId() != textureId )
|
||||
texture->bind();
|
||||
else
|
||||
texture->updateBindOptions();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int m_matrixId = -1;
|
||||
int m_opacityId = -1;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
class ShaderRhi : public RhiShader
|
||||
{
|
||||
public:
|
||||
ShaderRhi()
|
||||
{
|
||||
setFlag( UpdatesGraphicsPipelineState, true );
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
void setSource( QOpenGLShader::ShaderType type, const QString& fileName )
|
||||
{
|
||||
setShaderSourceFile( type, fileName );
|
||||
}
|
||||
#endif
|
||||
|
||||
void setSource( Stage stage, const QString& filename )
|
||||
{
|
||||
setShaderFileName( stage, filename );
|
||||
}
|
||||
|
||||
bool updateUniformData( RenderState& state,
|
||||
QSGMaterial*, QSGMaterial* ) override
|
||||
{
|
||||
Q_ASSERT( state.uniformData()->size() >= 68 );
|
||||
|
||||
auto data = state.uniformData()->data();
|
||||
bool changed = false;
|
||||
|
||||
if ( state.isMatrixDirty() )
|
||||
{
|
||||
const auto matrix = state.combinedMatrix();
|
||||
memcpy( data + 0, matrix.constData(), 64 );
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if ( state.isOpacityDirty() )
|
||||
{
|
||||
const float opacity = state.opacity();
|
||||
memcpy( data + 64, &opacity, 4 );
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void updateSampledImage( RenderState& state, int binding,
|
||||
QSGTexture** texture, QSGMaterial* newMaterial, QSGMaterial* ) override
|
||||
{
|
||||
Q_UNUSED( binding );
|
||||
Q_ASSERT( binding == 1 );
|
||||
|
||||
auto mat = dynamic_cast< TextureFilterMaterial* >( newMaterial );
|
||||
if ( auto txt = mat->texture() )
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
txt->updateRhiTexture( state.rhi(), state.resourceUpdateBatch() );
|
||||
#else
|
||||
txt->commitTextureOperations( state.rhi(), state.resourceUpdateBatch() );
|
||||
#endif
|
||||
*texture = txt;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
|
||||
QSGMaterialShader* TextureFilterMaterial::createShader() const
|
||||
{
|
||||
if ( flags() & QSGMaterial::RhiShaderWanted )
|
||||
{
|
||||
auto shader = new ShaderRhi();
|
||||
|
||||
shader->setSource( ShaderRhi::VertexStage, m_shaderFiles[ 0 ] );
|
||||
shader->setSource( ShaderRhi::FragmentStage, m_shaderFiles[ 1 ] );
|
||||
|
||||
return shader;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto shader = new ShaderGL();
|
||||
|
||||
shader->setSource( QOpenGLShader::Vertex, m_shaderFiles[ 0 ] );
|
||||
shader->setSource( QOpenGLShader::Fragment, m_shaderFiles[ 1 ] );
|
||||
|
||||
return shader;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
QSGMaterialShader* TextureFilterMaterial::createShader(
|
||||
QSGRendererInterface::RenderMode ) const
|
||||
{
|
||||
auto shader = new ShaderRhi();
|
||||
|
||||
shader->setSource( ShaderRhi::VertexStage, m_shaderFiles[ 0 ] );
|
||||
shader->setSource( ShaderRhi::FragmentStage, m_shaderFiles[ 1 ] );
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TextureFilterMaterial::TextureFilterMaterial(
|
||||
const QString& vertexShaderFile, const QString& fragmentShaderFile )
|
||||
: m_shaderFiles{ vertexShaderFile, fragmentShaderFile }
|
||||
{
|
||||
setFlag( Blending | RequiresFullMatrix, true );
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
setFlag( SupportsRhiShader, true );
|
||||
#endif
|
||||
}
|
||||
|
||||
TextureFilterMaterial::~TextureFilterMaterial()
|
||||
{
|
||||
}
|
||||
|
||||
int TextureFilterMaterial::compare( const QSGMaterial* other ) const
|
||||
{
|
||||
auto material = static_cast< const TextureFilterMaterial* >( other );
|
||||
|
||||
const auto key1 = texture()->comparisonKey();
|
||||
const auto key2 = material->texture()->comparisonKey();
|
||||
|
||||
return ( key1 == key2 ) ? 0 : ( ( key1 > key2 ) ? 1 : -1 );
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <qsgmaterial.h>
|
||||
#include <qstring.h>
|
||||
|
||||
class QSGTexture;
|
||||
|
||||
class TextureFilterMaterial : public QSGMaterial
|
||||
{
|
||||
public:
|
||||
TextureFilterMaterial( const QString& vertexShaderSourceFile,
|
||||
const QString& fragmentShaderSourceFile );
|
||||
|
||||
~TextureFilterMaterial() override;
|
||||
|
||||
int compare( const QSGMaterial* other ) const override;
|
||||
|
||||
void setTexture( QSGTexture* texture ) { m_texture = texture; }
|
||||
QSGTexture* texture() const { return m_texture; }
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QSGMaterialShader* createShader(
|
||||
QSGRendererInterface::RenderMode ) const override final;
|
||||
#else
|
||||
QSGMaterialShader* createShader() const override final;
|
||||
#endif
|
||||
|
||||
private:
|
||||
QSGTexture* m_texture = nullptr;
|
||||
const QString m_shaderFiles[ 2 ];
|
||||
};
|
|
@ -0,0 +1,104 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include "TextureFilterNode.h"
|
||||
#include "TextureFilterMaterial.h"
|
||||
|
||||
#include <qsgtexture.h>
|
||||
#include <private/qsgnode_p.h>
|
||||
|
||||
class TextureFilterNodePrivate final : public QSGGeometryNodePrivate
|
||||
{
|
||||
public:
|
||||
TextureFilterNodePrivate()
|
||||
: geometry( QSGGeometry::defaultAttributes_TexturedPoint2D(), 4 )
|
||||
{
|
||||
}
|
||||
|
||||
QSGGeometry geometry;
|
||||
QRectF rect;
|
||||
|
||||
bool ownsTexture = false;
|
||||
};
|
||||
|
||||
TextureFilterNode::TextureFilterNode()
|
||||
: QSGGeometryNode( *new TextureFilterNodePrivate )
|
||||
{
|
||||
Q_D( TextureFilterNode );
|
||||
|
||||
setGeometry( &d->geometry );
|
||||
setFlag( QSGNode::OwnsMaterial, true );
|
||||
}
|
||||
|
||||
TextureFilterNode::~TextureFilterNode()
|
||||
{
|
||||
setTexture( nullptr );
|
||||
}
|
||||
|
||||
void TextureFilterNode::setTextureMaterial( TextureFilterMaterial* material )
|
||||
{
|
||||
QSGTexture* texture = nullptr;
|
||||
if ( auto oldMaterial = textureMaterial() )
|
||||
texture = oldMaterial->texture();
|
||||
|
||||
Inherited::setMaterial( material );
|
||||
|
||||
if ( material )
|
||||
material->setTexture( texture );
|
||||
}
|
||||
|
||||
TextureFilterMaterial* TextureFilterNode::textureMaterial() const
|
||||
{
|
||||
return dynamic_cast< TextureFilterMaterial* >( material() );
|
||||
}
|
||||
|
||||
void TextureFilterNode::setTexture( QSGTexture* texture )
|
||||
{
|
||||
if ( auto mat = textureMaterial() )
|
||||
{
|
||||
if ( ownsTexture() && mat->texture() != texture )
|
||||
delete mat->texture();
|
||||
|
||||
mat->setTexture( texture );
|
||||
markDirty( QSGNode::DirtyMaterial );
|
||||
}
|
||||
}
|
||||
|
||||
QSGTexture* TextureFilterNode::texture() const
|
||||
{
|
||||
auto mat = textureMaterial();
|
||||
return mat ? mat->texture() : nullptr;
|
||||
}
|
||||
|
||||
void TextureFilterNode::setRect( const QRectF& rect )
|
||||
{
|
||||
Q_D( TextureFilterNode );
|
||||
|
||||
if ( rect != d->rect )
|
||||
{
|
||||
d->rect = rect;
|
||||
|
||||
QSGGeometry::updateTexturedRectGeometry(
|
||||
&d->geometry, rect, QRectF( 0, 0, 1, 1 ) );
|
||||
|
||||
d->geometry.markVertexDataDirty();
|
||||
markDirty( QSGNode::DirtyGeometry );
|
||||
}
|
||||
}
|
||||
|
||||
QRectF TextureFilterNode::rect() const
|
||||
{
|
||||
return d_func()->rect;
|
||||
}
|
||||
|
||||
void TextureFilterNode::setOwnsTexture( bool on )
|
||||
{
|
||||
d_func()->ownsTexture = on;
|
||||
}
|
||||
|
||||
bool TextureFilterNode::ownsTexture() const
|
||||
{
|
||||
return d_func()->ownsTexture;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <qsgnode.h>
|
||||
|
||||
class TextureFilterMaterial;
|
||||
class TextureFilterNodePrivate;
|
||||
|
||||
class QSGTexture;
|
||||
|
||||
class TextureFilterNode : public QSGGeometryNode
|
||||
{
|
||||
using Inherited = QSGGeometryNode;
|
||||
|
||||
public:
|
||||
TextureFilterNode();
|
||||
~TextureFilterNode();
|
||||
|
||||
void setTexture( QSGTexture* );
|
||||
QSGTexture* texture() const;
|
||||
|
||||
void setOwnsTexture( bool );
|
||||
bool ownsTexture() const;
|
||||
|
||||
void setRect( const QRectF& );
|
||||
QRectF rect() const;
|
||||
|
||||
void setTextureMaterial( TextureFilterMaterial* );
|
||||
TextureFilterMaterial* textureMaterial() const;
|
||||
|
||||
private:
|
||||
void setMaterial( QSGMaterial* ) = delete;
|
||||
|
||||
Q_DECLARE_PRIVATE( TextureFilterNode )
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE RCC>
|
||||
<RCC version="1.0">
|
||||
|
||||
<qresource>
|
||||
<file>images/parrots.jpg</file>
|
||||
</qresource>
|
||||
|
||||
</RCC>
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 45 KiB |
|
@ -0,0 +1,179 @@
|
|||
/******************************************************************************
|
||||
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*****************************************************************************/
|
||||
|
||||
#include <SkinnyNamespace.h>
|
||||
|
||||
#include <QskFunctions.h>
|
||||
#include <QskLinearBox.h>
|
||||
#include <QskPushButton.h>
|
||||
#include <QskQuick.h>
|
||||
#include <QskWindow.h>
|
||||
#include <QskGraphicLabel.h>
|
||||
#include <QskGraphic.h>
|
||||
#include <QskEvent.h>
|
||||
#include <QskRgbValue.h>
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QDebug>
|
||||
|
||||
#include <SkinnyShortcut.h>
|
||||
#include <qmath.h>
|
||||
|
||||
#include "Overlay.h"
|
||||
|
||||
class Image : public QskGraphicLabel
|
||||
{
|
||||
public:
|
||||
Image( QQuickItem* parent = nullptr )
|
||||
: QskGraphicLabel( parent )
|
||||
{
|
||||
const QImage image( ":/images/parrots.jpg" );
|
||||
setGraphic( QskGraphic::fromImage( image ) );
|
||||
}
|
||||
};
|
||||
|
||||
class ForegroundItem : public QskLinearBox
|
||||
{
|
||||
public:
|
||||
ForegroundItem( QQuickItem* parent = nullptr )
|
||||
: QskLinearBox( Qt::Vertical, parent )
|
||||
{
|
||||
setMargins( 20 );
|
||||
|
||||
#if 0
|
||||
auto label = new Image( this );
|
||||
label->setSizePolicy( QskSizePolicy::Fixed, QskSizePolicy::Fixed );
|
||||
label->setLayoutAlignmentHint( Qt::AlignCenter );
|
||||
label->setObjectName( "miniParrots" );
|
||||
#endif
|
||||
|
||||
auto button = new QskPushButton( "Button", this );
|
||||
button->setLayoutAlignmentHint( Qt::AlignHCenter | Qt::AlignBottom );
|
||||
|
||||
button->setObjectName( "button" );
|
||||
setObjectName( "foreground" );
|
||||
}
|
||||
};
|
||||
|
||||
class BackgroundItem : public QskControl
|
||||
{
|
||||
using Inherited = QskControl;
|
||||
|
||||
public:
|
||||
BackgroundItem( QQuickItem* parent = nullptr )
|
||||
: QskControl( parent )
|
||||
{
|
||||
setObjectName( "background" );
|
||||
|
||||
m_label = new Image( this );
|
||||
m_label->setFillMode( QskGraphicLabel::Stretch );
|
||||
m_label->setObjectName( "parrots" );
|
||||
|
||||
startTimer( 20 );
|
||||
}
|
||||
|
||||
protected:
|
||||
void timerEvent( QTimerEvent* ) override
|
||||
{
|
||||
updateLabel();
|
||||
}
|
||||
|
||||
void geometryChange( const QRectF& newGeometry,
|
||||
const QRectF& oldGeometry ) override
|
||||
{
|
||||
Inherited::geometryChange( newGeometry, oldGeometry );
|
||||
updateLabel();
|
||||
}
|
||||
|
||||
private:
|
||||
void updateLabel()
|
||||
{
|
||||
static int counter = 0;
|
||||
|
||||
const auto angle = counter++ / 50.0 * M_PI * 2.0;
|
||||
|
||||
const auto x = std::cos( angle );
|
||||
const auto y = std::sin( angle );
|
||||
|
||||
const qreal margin = 20;
|
||||
|
||||
auto labelRect = rect();
|
||||
labelRect.adjust( margin, margin, -margin, -margin );
|
||||
labelRect.translate( margin * x, margin * y );
|
||||
|
||||
if ( m_label )
|
||||
m_label->setGeometry( labelRect );
|
||||
}
|
||||
|
||||
private:
|
||||
QskGraphicLabel* m_label = nullptr;
|
||||
};
|
||||
|
||||
class MainView : public QskControl
|
||||
{
|
||||
public:
|
||||
MainView( QQuickItem* parent = nullptr )
|
||||
: QskControl( parent )
|
||||
{
|
||||
setPolishOnResize( true );
|
||||
|
||||
m_background = new BackgroundItem( this );
|
||||
#if 0
|
||||
{
|
||||
auto box = new QskBox( m_background );
|
||||
box->setGeometry( 20, 20, 600, 400 );
|
||||
box->setFillGradient( QskRgb::SaddleBrown );
|
||||
box->setObjectName( "redBox" );
|
||||
}
|
||||
#endif
|
||||
m_overlay = new Overlay( m_background );
|
||||
m_overlay->setAutoLayoutChildren( true );
|
||||
m_overlay->setObjectName( "overlay" );
|
||||
|
||||
(void )new ForegroundItem( m_overlay );
|
||||
|
||||
#if 0
|
||||
{
|
||||
auto box = new QskBox( m_background );
|
||||
box->setGeometry( 50, 50, 400, 200 );
|
||||
box->setFillGradient( QskRgb::PaleGreen );
|
||||
box->setObjectName( "blueBox" );
|
||||
}
|
||||
#endif
|
||||
setObjectName( "mainView" );
|
||||
}
|
||||
|
||||
protected:
|
||||
void updateLayout() override
|
||||
{
|
||||
if ( m_background )
|
||||
m_background->setGeometry( rect() );
|
||||
|
||||
QRectF blurredRect( QPointF(), 0.7 * size() );
|
||||
blurredRect.moveCenter( rect().center() );
|
||||
|
||||
if ( m_overlay )
|
||||
qskSetItemGeometry( m_overlay, blurredRect );
|
||||
}
|
||||
|
||||
private:
|
||||
BackgroundItem* m_background = nullptr;
|
||||
Overlay* m_overlay = nullptr;
|
||||
};
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
QGuiApplication app( argc, argv );
|
||||
|
||||
SkinnyShortcut::enable( SkinnyShortcut::AllShortcuts );
|
||||
|
||||
QskWindow window;
|
||||
window.setColor( Qt::darkGray );
|
||||
window.addItem( new MainView( window.contentItem() ) );
|
||||
window.resize( 800, 600 );
|
||||
window.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE RCC>
|
||||
<RCC version="1.0">
|
||||
<qresource>
|
||||
<file>shaders/blur.vert</file>
|
||||
<file>shaders/blur.frag</file>
|
||||
<file>shaders/rgbswap.frag</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -0,0 +1,25 @@
|
|||
#version 440
|
||||
|
||||
layout( location = 0 ) in vec2 coord;
|
||||
layout( location = 0 ) out vec4 fragColor;
|
||||
|
||||
layout( binding = 1 ) uniform sampler2D source;
|
||||
|
||||
layout( std140, binding = 0 ) uniform buf
|
||||
{
|
||||
mat4 matrix;
|
||||
float opacity;
|
||||
} ubuf;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 delta = vec2( 0.01, 0.01 );
|
||||
|
||||
fragColor =(
|
||||
0.0538 * texture( source, coord - 3.182 * delta )
|
||||
+ 0.3229 * texture( source, coord - 1.364 * delta )
|
||||
+ 0.2466 * texture( source, coord )
|
||||
+ 0.3229 * texture( source, coord + 1.364 * delta )
|
||||
+ 0.0538 * texture( source, coord + 3.182 * delta )
|
||||
) * ubuf.opacity;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#version 440
|
||||
|
||||
layout( location = 0 ) in vec4 in_vertex;
|
||||
layout( location = 1 ) in vec2 in_coord;
|
||||
|
||||
layout( location = 0 ) out vec2 coord;
|
||||
|
||||
layout( std140, binding = 0 ) uniform buf
|
||||
{
|
||||
mat4 matrix;
|
||||
float opacity;
|
||||
} ubuf;
|
||||
|
||||
out gl_PerVertex { vec4 gl_Position; };
|
||||
|
||||
void main()
|
||||
{
|
||||
coord = in_coord;
|
||||
gl_Position = ubuf.matrix * in_vertex;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
uniform sampler2D source;
|
||||
uniform lowp float opacity;
|
||||
|
||||
varying highp vec2 coord;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 delta = vec2( 0.01, 0.01 );
|
||||
|
||||
gl_FragColor =(
|
||||
0.0538 * texture2D( source, coord - 3.182 * delta )
|
||||
+ 0.3229 * texture2D( source, coord - 1.364 * delta )
|
||||
+ 0.2466 * texture2D( source, coord )
|
||||
+ 0.3229 * texture2D( source, coord + 1.364 * delta )
|
||||
+ 0.0538 * texture2D( source, coord + 3.182 * delta)
|
||||
) * opacity;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
uniform highp mat4 matrix;
|
||||
|
||||
attribute highp vec4 in_vertex;
|
||||
attribute highp vec2 in_coord;
|
||||
|
||||
varying highp vec2 coord;
|
||||
|
||||
void main()
|
||||
{
|
||||
coord = in_coord;
|
||||
gl_Position = matrix * in_vertex;
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#version 440
|
||||
|
||||
layout( location = 0 ) in vec2 coord;
|
||||
layout( location = 0 ) out vec4 fragColor;
|
||||
|
||||
layout( binding = 1 ) uniform sampler2D source;
|
||||
|
||||
layout( std140, binding = 0 ) uniform buf
|
||||
{
|
||||
mat4 matrix;
|
||||
float opacity;
|
||||
} ubuf;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c = texture( source, coord );
|
||||
fragColor = c.yzxw * ubuf.opacity;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
uniform sampler2D source;
|
||||
uniform lowp float opacity;
|
||||
|
||||
varying highp vec2 coord;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 c = texture2D( source, coord );
|
||||
gl_FragColor = c.yzxw * opacity;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#! /bin/sh
|
||||
|
||||
function qsbcompile {
|
||||
qsbfile=`echo $1 | sed 's/-vulkan//'`
|
||||
qsb --glsl 100es,120,150 --hlsl 50 --msl 12 -b -o ${qsbfile}.qsb $1
|
||||
}
|
||||
|
||||
qsbcompile blur-vulkan.vert
|
||||
qsbcompile blur-vulkan.frag
|
||||
qsbcompile rgbswap-vulkan.frag
|
Loading…
Reference in New Issue