This commit is contained in:
2020-06-27 19:45:43 -06:00
commit 5b0ba9f1db
16 changed files with 2073 additions and 0 deletions

42
src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,42 @@
find_package(Corrade REQUIRED Main)
find_package(Magnum REQUIRED GL)
find_package(Qt5 REQUIRED COMPONENTS Core Quick)
if(MAGNUM_TARGET_GLES AND NOT MAGNUM_TARGET_DESKTOP_GLES)
find_package(Magnum REQUIRED EglContext)
elseif(CORRADE_TARGET_WINDOWS)
find_package(Magnum REQUIRED WglContext)
elseif(CORRADE_TARGET_APPLE)
find_package(Magnum REQUIRED CglContext)
elseif(CORRADE_TARGET_UNIX)
find_package(Magnum REQUIRED GlxContext)
else()
message(FATAL_ERROR "Magnum context creation is not supported on this platform")
endif()
set_directory_properties(PROPERTIES CORRADE_USE_PEDANTIC_FLAGS ON)
if(ANDROID)
add_library(MyApplication SHARED
magnum_render.cpp
magnum_item.cpp
qml/main.qrc
main.cpp)
else()
add_executable(MyApplication
magnum_render.cpp
magnum_item.cpp
qml/main.qrc
main.cpp)
endif()
target_compile_definitions(MyApplication
PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_link_libraries(MyApplication PRIVATE
Corrade::Main
Magnum::GL
Magnum::GLContext
Magnum::Magnum
Qt5::Core
Qt5::Quick)

11
src/glclampf.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef GLCLAMPF_H
#define GLCLAMPF_H
#if 1
typedef GLfloat GLclampf;
#undef __glew_h__ /* shh, Qt, shh */
#undef __GLEW_H__
#include <QOpenGLFunctions>
#endif
#endif // GLCLAMPF_H

81
src/magnum_item.cpp Normal file
View File

@@ -0,0 +1,81 @@
#include <Magnum/GL/Framebuffer.h>
#include <Magnum/Platform/GLContext.h>
#include <QtCore/QRunnable>
#include <QtQuick/QQuickWindow>
#include <QOpenGLFramebufferObject>
#include "magnum_item.h"
#include "magnum_render.h"
using namespace std;
using namespace Magnum;
using namespace Math::Literals;
class MagnumFBORenderer : public QQuickFramebufferObject::Renderer {
public:
MagnumFBORenderer(QQuickWindow *window, MagnumRenderer *renderer) :
m_window(window),
m_renderer(renderer) {}
void render() override {
m_renderer->render();
m_window->resetOpenGLState();
update();
}
void synchronize(QQuickFramebufferObject *item) override {
auto mitem = static_cast<MagnumItem*>(item);
m_renderer->hue(mitem->hue());
}
QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override {
QOpenGLFramebufferObjectFormat format;
format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
format.setSamples(4);
m_fbo = new QOpenGLFramebufferObject(size, format);
if (m_ctx == nullptr)
m_ctx = new Platform::GLContext();
Platform::GLContext::makeCurrent(m_ctx);
m_renderer->reset(
m_ctx,
GL::Framebuffer::wrap(
m_fbo->handle(), {{}, {size.width(),
size.height()}}));
return m_fbo;
}
private:
QQuickWindow *m_window;
QOpenGLFramebufferObject *m_fbo;
Platform::GLContext *m_ctx{};
MagnumRenderer *m_renderer;
};
MagnumItem::MagnumItem() : m_renderer(new MagnumRenderer()) {
setMirrorVertically(true);
}
QQuickFramebufferObject::Renderer *MagnumItem::createRenderer() const {
return new MagnumFBORenderer(window(), m_renderer);
}
void MagnumItem::setHue(qreal hue) {
if (hue == m_hue) return;
m_hue = hue;
emit hueChanged();
update();
}
class CleanupJob : public QRunnable {
public:
CleanupJob(MagnumRenderer *renderer) : m_renderer(renderer) {}
void run() override { delete m_renderer; }
private:
MagnumRenderer *m_renderer;
};
void MagnumItem::releaseResources() {
window()->scheduleRenderJob(
new CleanupJob(m_renderer),
QQuickWindow::BeforeSynchronizingStage);
m_renderer = nullptr;
}

36
src/magnum_item.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef MAGNUM_ITEM_H
#define MAGNUM_ITEM_H
#include <Magnum/GL/Framebuffer.h>
#include <Magnum/Platform/GLContext.h>
#include "glclampf.h"
#include <QOpenGLFunctions>
#include <QtQuick/QQuickFramebufferObject>
// Forward declaring the renderer to avoid CMake's AUTOMOC
// to process Magnum's headers (where it fails)
class MagnumRenderer;
class MagnumItem : public QQuickFramebufferObject {
Q_OBJECT
Q_PROPERTY(qreal hue READ hue WRITE setHue NOTIFY hueChanged)
public:
MagnumItem();
Renderer *createRenderer() const override;
inline qreal hue() const { return m_hue; }
void setHue(qreal hue);
signals:
void hueChanged();
private:
void releaseResources() override;
qreal m_hue;
MagnumRenderer *m_renderer;
};
#endif // MAGNUM_ITEM_H

33
src/magnum_render.cpp Normal file
View File

@@ -0,0 +1,33 @@
#include <Magnum/GL/Framebuffer.h>
#include <Magnum/GL/Renderer.h>
#include <Magnum/Math/Color.h>
#include <Magnum/Platform/GLContext.h>
#include "magnum_render.h"
using namespace Magnum;
MagnumRenderer::MagnumRenderer() {}
MagnumRenderer::~MagnumRenderer() {}
void MagnumRenderer::hue(float hue) {
m_hue = hue;
}
void MagnumRenderer::reset(Platform::GLContext *ctx, GL::Framebuffer fbo) {
m_FBO = std::move(fbo);
m_ctx = ctx;
}
void MagnumRenderer::render() {
m_ctx->resetState(GL::Context::State::ExitExternal);
GL::Renderer::setClearColor(
Color4::fromHsv({Deg(m_hue), .3f, .9f}));
m_FBO.bind();
m_FBO.clear(GL::FramebufferClear::Color |
GL::FramebufferClear::Depth);
m_ctx->resetState(GL::Context::State::EnterExternal);
}

24
src/magnum_render.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef MAGNUM_RENDER_H
#define MAGNUM_RENDER_H
#include <Magnum/GL/Framebuffer.h>
#include <Magnum/Platform/GLContext.h>
using namespace Magnum;
class MagnumRenderer {
public:
MagnumRenderer();
~MagnumRenderer();
void render();
void reset(Platform::GLContext *ctx, GL::Framebuffer fbo);
void hue(float hue);
private:
Platform::GLContext *m_ctx{nullptr};
GL::Framebuffer m_FBO{NoCreate};
float m_hue;
};
#endif // MAGNUM_RENDER_H

36
src/main.cpp Normal file
View File

@@ -0,0 +1,36 @@
#include <Corrade/Containers/Optional.h>
#include <Magnum/GL/Framebuffer.h>
#include <Magnum/Platform/GLContext.h>
#include "magnum_item.h"
#include "glclampf.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QLoggingCategory>
int main(int argc, char *argv[]) {
// Enable AA
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication::setAttribute(Qt::AA_UseOpenGLES);
// Initialize Qt application
QGuiApplication app(argc, argv);
// Enable logging
QLoggingCategory::setFilterRules("qt.scenegraph.general=true");
// Manually register custom types
qmlRegisterType<MagnumItem>("Magnum", 1, 0, "Magnum");
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}

22
src/qml/main.qml Normal file
View File

@@ -0,0 +1,22 @@
import QtQuick 2.12
import QtQuick.Controls 2.5
import QtQuick.Layouts 1.3
import Magnum 1.0
ApplicationWindow {
id: app
visible: true
width: 640
height: 480
title: qsTr("My Application")
Shortcut {
sequence: "q"
onActivated: app.close()
}
Magnum {
anchors.fill: parent
hue: hue.value
}
}

6
src/qml/main.qrc Normal file
View File

@@ -0,0 +1,6 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>qtquickcontrols2.conf</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,9 @@
; This file can be edited to change the style of the application
; Read "Qt Quick Controls 2 Configuration File" for details:
; http://doc.qt.io/qt-5/qtquickcontrols2-configuration.html
[Controls]
Style=Fusion
[Fusion\Palette]
Highlight=#ff0000