#include #include #include #include #include #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(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; }