1
0
mirror of https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git synced 2025-04-01 02:42:39 +08:00

Improve OpenGLExample

This commit is contained in:
Thibault GEFFROY 2025-03-19 12:11:25 +01:00
parent 5b6624fb85
commit f10294fe10
No known key found for this signature in database
GPG Key ID: 30B5D581E60332E7
11 changed files with 693 additions and 45 deletions

View File

@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.5)
project(OpenGLExample VERSION ${VERSION_SHORT})
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
find_package(
QT NAMES Qt6
COMPONENTS Core
@ -11,7 +15,9 @@ find_package(
OpenGLWidgets
Quick
QuickWidgets
ShaderTools
REQUIRED)
find_package(
Qt${QT_VERSION_MAJOR}
COMPONENTS Core
@ -21,12 +27,14 @@ find_package(
OpenGLWidgets
Quick
QuickWidgets
ShaderTools
REQUIRED)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(
${PROJECT_NAME} WIN32
qt_add_executable(
${PROJECT_NAME}
WIN32
main.cpp
mainwindow.cpp
mainwindow.h
@ -34,6 +42,8 @@ add_executable(
glwindow.h
glwidget.h
glwidget.cpp
fbitem.cpp
fbitem.h
logo.cpp
logo.h)
@ -42,11 +52,31 @@ target_include_directories(${PROJECT_NAME}
target_link_libraries(${PROJECT_NAME}
PRIVATE qtadvanceddocking-qt${QT_VERSION_MAJOR})
qt_add_qml_module(
${PROJECT_NAME}
URI
fbitem
QML_FILES
"test.qml"
RESOURCE_PREFIX
/openGL
NO_RESOURCE_TARGET_PATH)
qt6_add_shaders(
${PROJECT_NAME}
"shaders"
PRECOMPILE
OPTIMIZED
PREFIX
"/openGL"
FILES
"wobble.frag")
# Resources:
set(esource_files "qtlogo.png")
set(resource_files "qtlogo.png")
qt_add_resources(${PROJECT_NAME} "OpenGLExample" PREFIX "/" FILES
${esource_files})
${resource_files})
target_link_libraries(
${PROJECT_NAME}
@ -90,4 +120,16 @@ install(
qt_generate_deploy_app_script(TARGET ${PROJECT_NAME} OUTPUT_SCRIPT
deploy_script NO_UNSUPPORTED_PLATFORM_ERROR)
install(SCRIPT ${deploy_script})
qt_generate_deploy_qml_app_script(
TARGET
${PROJECT_NAME}
OUTPUT_SCRIPT
qml_deploy_script
MACOS_BUNDLE_POST_BUILD
NO_UNSUPPORTED_PLATFORM_ERROR
DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM)
install(SCRIPT ${qml_deploy_script})

239
examples/openGL/fbitem.cpp Normal file
View File

@ -0,0 +1,239 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "fbitem.h"
#include <QOpenGLFramebufferObject>
#include <QOpenGLFunctions>
#include <QMatrix4x4>
FbItem::FbItem(QQuickItem *parent)
: QQuickFramebufferObject(parent),
m_target(0, 0, -1),
m_syncState(AllNeedsSync),
m_multisample(false)
{
}
QQuickFramebufferObject::Renderer *FbItem::createRenderer() const
{
return new FbItemRenderer(m_multisample);
}
void FbItem::setEye(const QVector3D &v)
{
if (m_eye != v) {
m_eye = v;
m_syncState |= CameraNeedsSync;
update();
}
}
void FbItem::setTarget(const QVector3D &v)
{
if (m_target != v) {
m_target = v;
m_syncState |= CameraNeedsSync;
update();
}
}
void FbItem::setRotation(const QVector3D &v)
{
if (m_rotation != v) {
m_rotation = v;
m_syncState |= RotationNeedsSync;
update();
}
}
int FbItem::swapSyncState()
{
int s = m_syncState;
m_syncState = 0;
return s;
}
FbItemRenderer::FbItemRenderer(bool multisample)
: m_inited(false),
m_multisample(multisample),
m_dirty(DirtyAll)
{
m_camera.setToIdentity();
m_baseWorld.setToIdentity();
m_baseWorld.translate(0, 0, -1);
m_world = m_baseWorld;
}
void FbItemRenderer::synchronize(QQuickFramebufferObject *qfbitem)
{
FbItem *item = static_cast<FbItem *>(qfbitem);
int syncState = item->swapSyncState();
if (syncState & FbItem::CameraNeedsSync) {
m_camera.setToIdentity();
m_camera.lookAt(item->eye(), item->eye() + item->target(), QVector3D(0, 1, 0));
m_dirty |= DirtyCamera;
}
if (syncState & FbItem::RotationNeedsSync) {
m_rotation = item->rotation();
m_dirty |= DirtyWorld;
}
}
struct StateBinder
{
StateBinder(FbItemRenderer *r)
: m_r(r) {
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glEnable(GL_DEPTH_TEST);
f->glEnable(GL_CULL_FACE);
f->glDepthMask(GL_TRUE);
f->glDepthFunc(GL_LESS);
f->glFrontFace(GL_CCW);
f->glCullFace(GL_BACK);
m_r->m_program->bind();
}
~StateBinder() {
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
m_r->m_program->release();
f->glDisable(GL_CULL_FACE);
f->glDisable(GL_DEPTH_TEST);
}
FbItemRenderer *m_r;
};
void FbItemRenderer::updateDirtyUniforms()
{
if (m_dirty & DirtyProjection)
m_program->setUniformValue(m_projMatrixLoc, m_proj);
if (m_dirty & DirtyCamera)
m_program->setUniformValue(m_camMatrixLoc, m_camera);
if (m_dirty & DirtyWorld) {
m_program->setUniformValue(m_worldMatrixLoc, m_world);
QMatrix3x3 normalMatrix = m_world.normalMatrix();
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
}
if (m_dirty & DirtyLight)
m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));
m_dirty = 0;
}
void FbItemRenderer::render()
{
ensureInit();
if (m_vao.isCreated())
m_vao.bind();
else
setupVertexAttribs();
StateBinder state(this);
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glClearColor(0, 0, 0, 0);
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (m_dirty & DirtyWorld) {
m_world = m_baseWorld;
m_world.rotate(m_rotation.x(), 1, 0, 0);
m_world.rotate(m_rotation.y(), 0, 1, 0);
m_world.rotate(m_rotation.z(), 0, 0, 1);
}
updateDirtyUniforms();
f->glDrawArrays(GL_TRIANGLES, 0, m_logo.vertexCount());
if (m_vao.isCreated())
m_vao.release();
}
QOpenGLFramebufferObject *FbItemRenderer::createFramebufferObject(const QSize &size)
{
m_dirty |= DirtyProjection;
m_proj.setToIdentity();
m_proj.perspective(45.0f, GLfloat(size.width()) / size.height(), 0.01f, 100.0f);
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setSamples(m_multisample ? 4 : 0);
return new QOpenGLFramebufferObject(size, format);
}
void FbItemRenderer::ensureInit()
{
if (m_inited)
return;
m_inited = true;
initBuf();
initProgram();
}
void FbItemRenderer::initBuf()
{
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
m_logoVbo.create();
m_logoVbo.bind();
m_logoVbo.allocate(m_logo.constData(), m_logo.count() * sizeof(GLfloat));
setupVertexAttribs();
}
void FbItemRenderer::setupVertexAttribs()
{
m_logoVbo.bind();
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glEnableVertexAttribArray(0);
f->glEnableVertexAttribArray(1);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), nullptr);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
m_logoVbo.release();
}
static const char *vertexShaderSource =
"attribute vec4 vertex;\n"
"attribute vec3 normal;\n"
"varying vec3 vert;\n"
"varying vec3 vertNormal;\n"
"uniform mat4 projMatrix;\n"
"uniform mat4 camMatrix;\n"
"uniform mat4 worldMatrix;\n"
"uniform mat3 normalMatrix;\n"
"void main() {\n"
" vert = vertex.xyz;\n"
" vertNormal = normalMatrix * normal;\n"
" gl_Position = projMatrix * camMatrix * worldMatrix * vertex;\n"
"}\n";
static const char *fragmentShaderSource =
"varying highp vec3 vert;\n"
"varying highp vec3 vertNormal;\n"
"uniform highp vec3 lightPos;\n"
"void main() {\n"
" highp vec3 L = normalize(lightPos - vert);\n"
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
" highp vec3 color = vec3(0.39, 1.0, 0.0);\n"
" highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n"
" gl_FragColor = vec4(col, 1.0);\n"
"}\n";
void FbItemRenderer::initProgram()
{
m_program.reset(new QOpenGLShaderProgram);
m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
m_program->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
m_program->bindAttributeLocation("vertex", 0);
m_program->bindAttributeLocation("normal", 1);
m_program->link();
m_projMatrixLoc = m_program->uniformLocation("projMatrix");
m_camMatrixLoc = m_program->uniformLocation("camMatrix");
m_worldMatrixLoc = m_program->uniformLocation("worldMatrix");
m_normalMatrixLoc = m_program->uniformLocation("normalMatrix");
m_lightPosLoc = m_program->uniformLocation("lightPos");
}

100
examples/openGL/fbitem.h Normal file
View File

@ -0,0 +1,100 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef FBITEM_H
#define FBITEM_H
#include <QQuickFramebufferObject>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
#include <QOpenGLShaderProgram>
#include <QVector3D>
#include "logo.h"
struct StateBinder;
class FbItemRenderer : public QQuickFramebufferObject::Renderer
{
public:
FbItemRenderer(bool multisample);
void synchronize(QQuickFramebufferObject *item) override;
void render() override;
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override;
private:
void ensureInit();
void initBuf();
void setupVertexAttribs();
void initProgram();
void updateDirtyUniforms();
bool m_inited;
bool m_multisample;
QMatrix4x4 m_proj;
QMatrix4x4 m_camera;
QMatrix4x4 m_baseWorld;
QMatrix4x4 m_world;
QOpenGLVertexArrayObject m_vao;
QOpenGLBuffer m_logoVbo;
Logo m_logo;
QScopedPointer<QOpenGLShaderProgram> m_program;
int m_projMatrixLoc;
int m_camMatrixLoc;
int m_worldMatrixLoc;
int m_normalMatrixLoc;
int m_lightPosLoc;
QVector3D m_rotation;
enum Dirty {
DirtyProjection = 0x01,
DirtyCamera = 0x02,
DirtyWorld = 0x04,
DirtyLight = 0x08,
DirtyAll = 0xFF
};
int m_dirty;
friend struct StateBinder;
};
class FbItem : public QQuickFramebufferObject
{
Q_OBJECT
Q_PROPERTY(QVector3D eye READ eye WRITE setEye)
Q_PROPERTY(QVector3D target READ target WRITE setTarget)
Q_PROPERTY(QVector3D rotation READ rotation WRITE setRotation)
Q_PROPERTY(bool multisample READ multisample WRITE setMultisample)
QML_ELEMENT
public:
explicit FbItem(QQuickItem *parent = nullptr);
QQuickFramebufferObject::Renderer *createRenderer() const override;
QVector3D eye() const { return m_eye; }
void setEye(const QVector3D &v);
QVector3D target() const { return m_target; }
void setTarget(const QVector3D &v);
QVector3D rotation() const { return m_rotation; }
void setRotation(const QVector3D &v);
enum SyncState {
CameraNeedsSync = 0x01,
RotationNeedsSync = 0x02,
AllNeedsSync = 0xFF
};
int swapSyncState();
bool multisample() const { return m_multisample; }
void setMultisample(bool m) { m_multisample = m; }
private:
QVector3D m_eye;
QVector3D m_target;
QVector3D m_rotation;
int m_syncState;
bool m_multisample;
};
#endif // FBITEM_H

View File

@ -4,18 +4,32 @@
#include <QGuiApplication>
#include <QOpenGLContext>
#include <QScreen>
#include <QSurfaceFormat>
#include <QQuickWindow>
#include <glwindow.h>
#include <mainwindow.h>
int main(int argc, char* argv[])
{
// https://doc.qt.io/qt-6/qtdatavisualization-known-issues.html
// Use either `qputenv("QSG_RHI_BACKEND", "opengl");` or the following line
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
// Disable warnings when attempts are made to convert non-convertible non-native widgets
// to native widgets (such as QQuickWidget)
QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
// Enable ADS AutoHide
ads::CDockManager::setAutoHideConfigFlags(ads::CDockManager::DefaultAutoHideConfig);
QApplication a(argc, argv);
MainWindow* w = new MainWindow();
// Release memory when closing main window and quit application
w->setAttribute(Qt::WA_DeleteOnClose);
w->show();
return a.exec();

View File

@ -8,6 +8,7 @@
#include <QLineSeries>
#include <QOpenGLWidget>
#include <QPushButton>
#include <QQuickView>
#include <QQuickWidget>
#include <QTimer>
#include <QVBoxLayout>
@ -58,13 +59,11 @@ public:
~ChartWidget() {}
};
class OpenGLWidgetContainer : public QWidget
class OpenGLWindowContainer : public QWidget
{
public:
OpenGLWidgetContainer(QWidget* parent = nullptr) : QWidget(parent)
OpenGLWindowContainer(QWidget* parent = nullptr) : QWidget(parent)
{
setAttribute(Qt::WA_NativeWindow, true);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
@ -72,7 +71,40 @@ public:
layout->addWidget(widget);
}
~OpenGLWidgetContainer() {}
~OpenGLWindowContainer() {}
};
class QuickViewContainer : public QWidget
{
public:
QuickViewContainer(QWidget* parent = nullptr) : QWidget(parent)
{
QVBoxLayout* l = new QVBoxLayout(this);
l->setContentsMargins(0, 0, 0, 0);
_format.setDepthBufferSize(16);
_format.setStencilBufferSize(8);
_format.setSamples(4);
QUrl source("qrc:/openGL/test.qml");
QQuickView* quick_view = new QQuickView();
quick_view->setFormat(_format);
quick_view->setResizeMode(QQuickView::SizeRootObjectToView);
quick_view->setSource(source);
if (quick_view->status() != QQuickView::Ready)
{
qWarning() << "QQuickView error:" << quick_view->errors();
}
l->addWidget(QWidget::createWindowContainer(quick_view, parent));
}
~QuickViewContainer() {}
private:
QSurfaceFormat _format;
};
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
@ -84,44 +116,54 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
_dock_manager = new ads::CDockManager(this);
OpenGLChartWidget* openGL_chart = new OpenGLChartWidget(this);
OpenGLWidgetContainer* openGL_container = new OpenGLWidgetContainer(this);
ChartWidget* simple_chart = new ChartWidget(this);
OpenGLWindowContainer* openGL_container = new OpenGLWindowContainer(this);
GLWidget* gl_widget = new GLWidget(this);
GLWidget* gl_widget_2 = new GLWidget(this);
// Create a dock widget with the title "Chart with OpenGL" and set the created
// chart as the dock widget content
ads::CDockWidget* opengl_chart_dock_widget =
new ads::CDockWidget("Chart with OpenGL");
opengl_chart_dock_widget->setWidget(openGL_chart);
auto* area = _dock_manager->addDockWidget(ads::CenterDockWidgetArea,
opengl_chart_dock_widget);
ads::CDockWidget* chart_dock_widget = new ads::CDockWidget("Simple Chart");
chart_dock_widget->setWidget(new ChartWidget(this));
_dock_manager->addDockWidgetTabToArea(chart_dock_widget, area);
ads::CDockWidget* openGL_window_dock_widget =
new ads::CDockWidget("OpenGL window");
openGL_window_dock_widget->setWidget(openGL_container);
_dock_manager->addDockWidgetTabToArea(openGL_window_dock_widget, area);
ads::CDockWidget* openGL_widget_dock_widget =
new ads::CDockWidget("OpenGL widget");
openGL_widget_dock_widget->setWidget(gl_widget);
_dock_manager->addDockWidgetTabToArea(openGL_widget_dock_widget, area);
ads::CDockWidget* openGL_widget_dock_widget_2 =
new ads::CDockWidget("OpenGL widget 2");
openGL_widget_dock_widget_2->setWidget(gl_widget_2);
_dock_manager->addDockWidgetTabToArea(openGL_widget_dock_widget_2, area);
ads::CDockWidget* label_dock_widget = new ads::CDockWidget("Label");
QuickViewContainer* quick_view_container = new QuickViewContainer(this);
QLabel* l = new QLabel();
l->setWordWrap(true);
l->setAlignment(Qt::AlignTop | Qt::AlignLeft);
l->setText("Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ");
label_dock_widget->setWidget(l);
_dock_manager->addDockWidgetTabToArea(label_dock_widget, area);
}
QUrl source("qrc:/openGL/test.qml");
QQuickWidget* quick_widget = new QQuickWidget(this);
quick_widget->setSource(source);
quick_widget->setResizeMode(QQuickWidget::SizeRootObjectToView);
auto* center_dock_area_widget = createDockWidget(
openGL_chart, "Chart with OpenGL", ads::CenterDockWidgetArea);
createDockWidget(simple_chart, "Simple Chart", ads::CenterDockWidgetArea,
center_dock_area_widget);
createDockWidget(openGL_container, "OpenGL window", ads::CenterDockWidgetArea,
center_dock_area_widget);
createDockWidget(gl_widget, "OpenGL widget", ads::CenterDockWidgetArea,
center_dock_area_widget);
createDockWidget(gl_widget_2, "OpenGL widget 2", ads::CenterDockWidgetArea,
center_dock_area_widget);
createDockWidget(quick_view_container, "Quick View",
ads::CenterDockWidgetArea, center_dock_area_widget);
createDockWidget(quick_widget, "Quick Widget", ads::CenterDockWidgetArea,
center_dock_area_widget);
createDockWidget(l, "Label", ads::CenterDockWidgetArea,
center_dock_area_widget);
}
ads::CDockAreaWidget* MainWindow::createDockWidget(
QWidget* embedded_widget, QString dock_widget_title, ads::DockWidgetArea area,
ads::CDockAreaWidget* center_dock_area_widget)
{
ads::CDockWidget* dock_widget = new ads::CDockWidget(dock_widget_title);
dock_widget->setWidget(embedded_widget);
return _dock_manager->addDockWidget(area, dock_widget,
center_dock_area_widget);
}

View File

@ -4,6 +4,7 @@
#include <QMainWindow>
#include <DockManager.h>
#include <DockAreaWidget.h>
class MainWindow : public QMainWindow
{
@ -13,6 +14,9 @@ public:
explicit MainWindow(QWidget* parent = 0);
~MainWindow() = default;
ads::CDockAreaWidget* createDockWidget(QWidget* embedded_widget, QString dock_widget_title, ads::DockWidgetArea area,
ads::CDockAreaWidget* DockAreaWidget = nullptr);
private:
ads::CDockManager* _dock_manager;
};

View File

@ -7,6 +7,10 @@ DESTDIR = $${ADS_OUT_ROOT}/lib
TEMPLATE = app
CONFIG += c++14
CONFIG += debug
CONFIG += qmltypes
QML_IMPORT_NAME = fbitem
QML_IMPORT_MAJOR_VERSION = 1
adsBuildStatic {
DEFINES += ADS_STATIC
}
@ -19,16 +23,20 @@ SOURCES += \
main.cpp \
mainwindow.cpp \
logo.cpp \
glwindow.cpp
glwindow.cpp \
fbitem.cpp
HEADERS += \
mainwindow.h \
glwidget.h \
logo.h \
glwindow.h
glwindow.h \
fbitem.h
RESOURCES += openGL.qrc
OTHER_FILES += test.qml
LIBS += -L$${ADS_OUT_ROOT}/lib
include(../../ads.pri)
INCLUDEPATH += ../../src

View File

@ -1,4 +1,9 @@
<RCC>
<qresource prefix="/openGL">
<file>test.qml</file>
<file>wobble.frag</file>
<file>wobble.frag.qsb</file>
</qresource>
<qresource>
<file>qtlogo.png</file>
</qresource>

171
examples/openGL/test.qml Normal file
View File

@ -0,0 +1,171 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Particles
import fbitem
Rectangle {
id: root
property alias currentText: edit.text
property alias multisample: fbitem.multisample
property bool translucency: false
gradient: Gradient {
id: grad
GradientStop { position: 0; color: "steelblue" }
GradientStop { position: 1; color: "black" }
}
onTranslucencyChanged: {
if (translucency) {
root.color = "transparent";
root.gradient = null;
} else {
root.color = "white";
root.gradient = grad;
}
}
ParticleSystem {
anchors.fill: parent
running: true
ImageParticle {
source: "qrc:///particleresources/glowdot.png"
alpha: 0
colorVariation: 1
}
Emitter {
anchors.fill: parent
lifeSpan: 3000
emitRate: 30
size: 50
sizeVariation: 10
velocity: PointDirection { xVariation: 10; yVariation: 10; }
acceleration: PointDirection {
y: -10
xVariation: 5
yVariation: 5
}
}
}
Rectangle {
y: 10
width: parent.width / 2
height: edit.contentHeight + 4
anchors.horizontalCenter: parent.horizontalCenter
border.color: "gray"
border.width: 2
radius: 8
color: "lightGray"
clip: true
TextInput {
id: edit
anchors.horizontalCenter: parent.horizontalCenter
maximumLength: 30
focus: true
font.pointSize: 20
}
}
FbItem {
id: fbitem
anchors.fill: parent
SequentialAnimation on eye.y {
loops: Animation.Infinite
NumberAnimation {
from: 0
to: 0.15
duration: 1000
}
NumberAnimation {
from: 0.15
to: 0
duration: 2000
}
}
SequentialAnimation on eye.x {
loops: Animation.Infinite
NumberAnimation {
from: 0
to: -0.5
duration: 3000
}
NumberAnimation {
from: -0.5
to: 0.5
duration: 3000
easing.type: Easing.OutQuad
}
NumberAnimation {
from: 0.5
to: 0
duration: 1000
}
}
SequentialAnimation on rotation.y {
loops: Animation.Infinite
NumberAnimation {
from: 0
to: 360
duration: 5000
}
NumberAnimation {
from: 360
to: 0
duration: 2500
}
}
SequentialAnimation on rotation.x {
loops: Animation.Infinite
NumberAnimation {
from: 0
to: 360
duration: 6000
}
NumberAnimation {
from: 360
to: 0
duration: 3000
}
}
}
Text {
id: effText
text: edit.text
anchors.centerIn: parent
font.pointSize: 60
style: Text.Outline
styleColor: "green"
}
ShaderEffectSource {
id: effSource
sourceItem: effText
hideSource: true
}
ShaderEffect {
SequentialAnimation on scale {
loops: Animation.Infinite
NumberAnimation { from: 1.0; to: 2.0; duration: 1000; easing.type: Easing.InCirc }
PauseAnimation { duration: 1000 }
NumberAnimation { from: 2.0; to: 0.5; duration: 1000; easing.type: Easing.OutExpo }
NumberAnimation { from: 0.5; to: 1.0; duration: 500 }
PauseAnimation { duration: 1000 }
}
width: effText.width
height: effText.height
anchors.centerIn: parent
property variant source: effSource
property real amplitude: 0.002
property real frequency: 10
property real time: 0
NumberAnimation on time { loops: Animation.Infinite; from: 0; to: Math.PI * 2; duration: 1000 }
fragmentShader: "wobble.frag.qsb"
}
}

View File

@ -0,0 +1,23 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#version 440
layout(location = 0) in vec2 qt_TexCoord0;
layout(location = 0) out vec4 fragColor;
layout(binding = 1) uniform sampler2D source;
layout(std140, binding = 0) uniform buf {
mat4 qt_Matrix;
float qt_Opacity;
float amplitude;
float frequency;
float time;
};
void main()
{
vec2 p = sin(time + frequency * qt_TexCoord0);
fragColor = texture(source, qt_TexCoord0 + amplitude * vec2(p.y, -p.x)) * qt_Opacity;
}

Binary file not shown.