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(shapes)
|
||||||
add_subdirectory(charts)
|
add_subdirectory(charts)
|
||||||
add_subdirectory(plots)
|
add_subdirectory(plots)
|
||||||
|
add_subdirectory(parrots)
|
||||||
|
|
||||||
if (BUILD_INPUTCONTEXT)
|
if (BUILD_INPUTCONTEXT)
|
||||||
add_subdirectory(inputpanel)
|
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