This commit is contained in:
朱子楚\zhuzi 2024-04-11 14:56:22 +08:00
parent a3f375c9ef
commit 96fef84c2d
3 changed files with 158 additions and 0 deletions

View File

@ -0,0 +1,32 @@
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import FluentUI 1.0
import example 1.0
import "../component"
FluContentPage{
title: qsTr("OpenGL")
FluFrame{
anchors.fill: parent
OpenGLItem{
width: 320
height: 480
SequentialAnimation on t {
NumberAnimation { to: 1; duration: 2500; easing.type: Easing.InQuad }
NumberAnimation { to: 0; duration: 2500; easing.type: Easing.OutQuad }
loops: Animation.Infinite
running: true
}
}
}
}

View File

@ -0,0 +1,93 @@
#include "OpenGLItem.h"
#include <QOpenGLFramebufferObjectFormat>
#include <QOpenGLShaderProgram>
class FBORenderer : public QQuickFramebufferObject::Renderer, protected QOpenGLFunctions {
public:
explicit FBORenderer(const OpenGLItem *item);
void render() override;
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override;
QOpenGLShaderProgram program;
const OpenGLItem *item = nullptr;
};
FBORenderer::FBORenderer(const OpenGLItem *item) {
this->item = item;
initializeOpenGLFunctions();
program.addCacheableShaderFromSourceCode(QOpenGLShader::Vertex,
"attribute highp vec4 vertices;"
"varying highp vec2 coords;"
"void main() {"
" gl_Position = vertices;"
" coords = vertices.xy;"
"}");
program.addCacheableShaderFromSourceCode(QOpenGLShader::Fragment,
"uniform lowp float t;"
"varying highp vec2 coords;"
"void main() {"
" lowp float i = 1. - (pow(abs(coords.x), 4.) + pow(abs(coords.y), 4.));"
" i = smoothstep(t - 0.8, t + 0.8, i);"
" i = floor(i * 20.) / 20.;"
" gl_FragColor = vec4(coords * .5 + .5, i, i);"
"}");
program.bindAttributeLocation("vertices", 0);
program.link();
}
QOpenGLFramebufferObject *FBORenderer::createFramebufferObject(const QSize &size) {
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setSamples(4);
return new QOpenGLFramebufferObject(size, format);
}
void FBORenderer::render() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
program.bind();
program.enableAttributeArray(0);
float values[] = {
-1, -1,
1, -1,
-1, 1,
1, 1
};
glBindBuffer(GL_ARRAY_BUFFER, 0);
program.setAttributeArray(0, GL_FLOAT, values, 2);
program.setUniformValue("t", (float) item->t());
glViewport(0, 0, qRound(item->width()), qRound(item->height()));
glDisable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
program.disableAttributeArray(0);
program.release();
}
OpenGLItem::OpenGLItem(QQuickItem *parent) : QQuickFramebufferObject(parent) {
setMirrorVertically(true);
startTimer(1);
}
void OpenGLItem::timerEvent(QTimerEvent *) {
update();
}
void OpenGLItem::setT(qreal t) {
if (t == m_t)
return;
m_t = t;
emit tChanged();
}
QQuickFramebufferObject::Renderer *OpenGLItem::createRenderer() const {
return new FBORenderer(this);
}

View File

@ -0,0 +1,33 @@
#pragma once
#pragma clang diagnostic push
#pragma ide diagnostic ignored "NotImplementedFunctions"
#include <QtQuick/QQuickItem>
#include <QOpenGLFunctions>
#include <QQuickFramebufferObject>
class FBORenderer;
class OpenGLItem : public QQuickFramebufferObject, protected QOpenGLFunctions {
Q_OBJECT
Q_PROPERTY(qreal t READ t WRITE setT NOTIFY tChanged)
public:
explicit OpenGLItem(QQuickItem *parent = nullptr);
[[nodiscard]] QQuickFramebufferObject::Renderer *createRenderer() const override;
void timerEvent(QTimerEvent *) override;
[[nodiscard]] qreal t() const { return m_t; }
void setT(qreal t);
signals:
void tChanged();
private:
qreal m_t{};
};
#pragma clang diagnostic pop