summaryrefslogtreecommitdiff
path: root/examples/widgets/painting/shared/fbopaintdevice.cpp
blob: 305f4f2c2ccc934ca41fccfab65c5682d9270d87 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

#include "fbopaintdevice.h"

#include <QOffscreenSurface>
#include <QOpenGLFunctions>

QFboPaintDevice::QFboPaintDevice(const QSize &size, bool flipped, bool clearOnInit,
                                 QOpenGLFramebufferObject::Attachment attachment)
        : QOpenGLPaintDevice(size)
{
    QOpenGLFramebufferObjectFormat format;
    format.setAttachment(attachment);
    format.setSamples(4);
    m_framebufferObject = new QOpenGLFramebufferObject(size, format);
    QOffscreenSurface *surface = new QOffscreenSurface();
    surface->create();
    m_surface = surface;
    setPaintFlipped(flipped);
    if (clearOnInit) {
        m_framebufferObject->bind();

        context()->functions()->glClearColor(0, 0, 0, 0);
        context()->functions()->glClear(GL_COLOR_BUFFER_BIT);
    }
}

QFboPaintDevice::~QFboPaintDevice()
{
    delete m_framebufferObject;
    delete m_surface;
}

void QFboPaintDevice::ensureActiveTarget()
{
    if (QOpenGLContext::currentContext() != context())
        context()->makeCurrent(m_surface);

    m_framebufferObject->bind();
}

GLuint QFboPaintDevice::takeTexture()
{
    // We have multisamples so we can't just forward takeTexture().
    QOpenGLFramebufferObject resolvedFbo(m_framebufferObject->size(), m_framebufferObject->attachment());
    QOpenGLFramebufferObject::blitFramebuffer(&resolvedFbo, m_framebufferObject);
    return resolvedFbo.takeTexture();
}

QImage QFboPaintDevice::toImage() const
{
    QOpenGLContext *currentContext = QOpenGLContext::currentContext();
    QSurface *currentSurface = currentContext ? currentContext->surface() : nullptr;

    context()->makeCurrent(m_surface);

    QImage image = m_framebufferObject->toImage(!paintFlipped());

    if (currentContext)
        currentContext->makeCurrent(currentSurface);
    else
        context()->doneCurrent();

    return image;
}