Пример #1
0
 QOpenGLFramebufferObject *createFramebufferObject(const QSize &size)
 {
     QOpenGLFramebufferObjectFormat format;
     format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
     format.setSamples(4);
     return new QOpenGLFramebufferObject(size, format);
 }
Пример #2
0
void TApplication::initializeGL() {

    // Init shaders
    if (!Shader.addShaderFromSourceFile(QGLShader::Vertex, "vert.glsl")) {
        qFatal("failed to load shader vert.glsl");
    }
    if (!Shader.addShaderFromSourceFile(QGLShader::Fragment, "frag.glsl")) {
        qFatal("failed to load shader frag.glsl");
    }
    if (!Shader.link()) {
        qFatal("failed to link shader planet");
    }
    if (!Shader.bind()) {
        qFatal("failed to bind shader");
    }

    // Init framebuffers
    QOpenGLFramebufferObjectFormat format;
    format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
    format.setSamples(8);
    Fbo.reset(new QOpenGLFramebufferObject(WINDOW_WIDTH, WINDOW_HEIGHT, format));

    QOpenGLFramebufferObjectFormat format1;
    format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
    Fbo1.reset(new QOpenGLFramebufferObject(WINDOW_WIDTH, WINDOW_HEIGHT, format1));


    // Load model and textures

    Obj = LoadJsonModel("model.json");
    ObjectSize = Obj.size();

    VertexBuff.reset(new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer));
    VertexBuff->create();
    VertexBuff->bind();
    VertexBuff->setUsagePattern(QOpenGLBuffer::StaticDraw);
    VertexBuff->allocate(Obj.data(), Obj.size() * sizeof(TVertex));
    VertexBuff->release();

    Texture.reset(new QOpenGLTexture(QImage("diffuse.jpg")));
    Texture->bind();
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    Texture->release();

    NormalMap.reset(new QOpenGLTexture(QImage("normal.jpg")));
    NormalMap->bind();
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    NormalMap->release();

    // Initial angles
    AngleX = 0;
    AngleY = 0;
    AngleZ = 0;

    Paused = false;
}
Пример #3
0
void RenderSurface::render(QPainter *painter)
{
    Q_UNUSED(painter);

    QOpenGLFramebufferObjectFormat fboFormat;
    fboFormat.setSamples(1);
    fboFormat.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);

    const QRect drawRect(0, 0, m_outWidth, m_outHeight);
    const QSize drawRectSize = drawRect.size();
    QOpenGLFramebufferObject fbo(drawRectSize, fboFormat);
    fbo.bind();

    glViewport(0, 0, m_outWidth, m_outHeight);

    glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    glEnable(GL_BLEND); 
    glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ONE);

    m_program->bind();

    int texCount = 0;
    for (size_t i = 0; i < sp.size(); ++i) {
      if (sp[i].bind == ShaderParameter::BindTextureSampler) {
        textures[sp[i].name].obj->bind(texCount);
        m_program->setUniformValue(sp[i].name.c_str(), texCount);
        texCount++;
      } else if (sp[i].bind == ShaderParameter::BindTextureResolution) {
        const QImage& image = textures[sp[i].texture].image;
        m_program->setUniformValue(sp[i].name.c_str(), QVector2D(image.width(),image.height()));
      } else if (sp[i].bind == ShaderParameter::BindGlobalTime) {
        m_program->setUniformValue(sp[i].name.c_str(), m_globalTime);
      } else if (sp[i].bind == ShaderParameter::BindOutputResolution) {
        m_program->setUniformValue(sp[i].name.c_str(), QVector2D(m_outWidth,m_outHeight));
      }
    }

    GLfloat vertices[] = {
      -1.0f,  -1.0f, 0.0f,
      1.0f, -1.0f, 0.0f,
      -1.0f, 1.0f, 0.0f,
      1.0f, 1.0f, 0.0f
    };

    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, vertices);

    glEnableVertexAttribArray(0);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glDisableVertexAttribArray(0);

    m_program->release();

    imageFrame = fbo.toImage();
}
Пример #4
0
QOpenGLFramebufferObject* COglRenderer::createFramebufferObject(const QSize &size)
{
    // create opengl FBO
    QOpenGLFramebufferObjectFormat format;
    format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
    format.setSamples(4);
    m_oglFBO = new QOpenGLFramebufferObject(size, format);

    // return opengl FBO
    return m_oglFBO;
}
Пример #5
0
std::unique_ptr<QOpenGLFramebufferObject>
_createMultisampledFBO( const QSize& size )
{
    QOpenGLFramebufferObjectFormat format;
    format.setAttachment( QOpenGLFramebufferObject::CombinedDepthStencil );
    format.setSamples( MULTI_SAMPLE_ANTI_ALIASING_SAMPLES );

    auto fbo = make_unique<QOpenGLFramebufferObject>( size, format );
    fbo->bind();
    auto gl = QOpenGLContext::currentContext()->functions();
    gl->glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
    gl->glClear( GL_COLOR_BUFFER_BIT );
    fbo->release();

    return fbo;
}
Пример #6
0
bool QGLPixelBuffer::makeCurrent()
{
    Q_D(QGLPixelBuffer);
    if (d->invalid)
        return false;
    d->qctx->makeCurrent();
    if (!d->fbo) {
        QOpenGLFramebufferObjectFormat format;
        if (d->req_format.stencil())
            format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
        else if (d->req_format.depth())
            format.setAttachment(QOpenGLFramebufferObject::Depth);
        if (d->req_format.sampleBuffers())
            format.setSamples(d->req_format.samples());
        d->fbo = new QOpenGLFramebufferObject(d->req_size, format);
        d->fbo->bind();
    }
    return true;
}
Пример #7
0
bool QGLPixelBuffer::makeCurrent()
{
    Q_D(QGLPixelBuffer);
    if (d->invalid)
        return false;
    d->qctx->makeCurrent();
    if (!d->fbo) {
        QOpenGLFramebufferObjectFormat format;
        if (d->req_format.stencil())
            format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
        else if (d->req_format.depth())
            format.setAttachment(QOpenGLFramebufferObject::Depth);
        if (d->req_format.sampleBuffers())
            format.setSamples(d->req_format.samples());
        d->fbo = new QOpenGLFramebufferObject(d->req_size, format);
        d->fbo->bind();
        d->glDevice.setFbo(d->fbo->handle());
        QOpenGLContext::currentContext()->functions()->glViewport(0, 0, d->req_size.width(), d->req_size.height());
    }
    return true;
}
static PyObject *meth_QOpenGLFramebufferObjectFormat_setSamples(PyObject *sipSelf, PyObject *sipArgs)
{
    PyObject *sipParseErr = NULL;

    {
        int a0;
        QOpenGLFramebufferObjectFormat *sipCpp;

        if (sipParseArgs(&sipParseErr, sipArgs, "Bi", &sipSelf, sipType_QOpenGLFramebufferObjectFormat, &sipCpp, &a0))
        {
            sipCpp->setSamples(a0);

            Py_INCREF(Py_None);
            return Py_None;
        }
    }

    /* Raise an exception if the arguments couldn't be parsed. */
    sipNoMethod(sipParseErr, sipName_QOpenGLFramebufferObjectFormat, sipName_setSamples, doc_QOpenGLFramebufferObjectFormat_setSamples);

    return NULL;
}
Пример #9
0
void GLWidget::paintGL()
{
    QOpenGLFunctions* f = openglContext()->functions();
    int width = this->width() * devicePixelRatio();
    int height = this->height() * devicePixelRatio();

    glDisable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);
    glViewport(0, 0, width, height);
    check_error(f);
    QColor color(KdenliveSettings::window_background()); //= QPalette().color(QPalette::Window);
    glClearColor(color.redF(), color.greenF(), color.blueF(), color.alphaF());
    glClear(GL_COLOR_BUFFER_BIT);
    check_error(f);

    if (!m_texture[0]) return;

    // Bind textures.
    for (int i = 0; i < 3; ++i) {
        if (m_texture[i]) {
            glActiveTexture(GL_TEXTURE0 + i);
            glBindTexture(GL_TEXTURE_2D, m_texture[i]);
            check_error(f);
        }
    }

    // Init shader program.
    m_shader->bind();
    if (m_glslManager) {
        m_shader->setUniformValue(m_textureLocation[0], 0);
    } else {
        m_shader->setUniformValue(m_textureLocation[0], 0);
        m_shader->setUniformValue(m_textureLocation[1], 1);
        m_shader->setUniformValue(m_textureLocation[2], 2);
        m_shader->setUniformValue(m_colorspaceLocation, m_monitorProfile->colorspace());
    }
    check_error(f);

    // Setup an orthographic projection.
    QMatrix4x4 projection;
    projection.scale(2.0f / width, 2.0f / height);
    m_shader->setUniformValue(m_projectionLocation, projection);
    check_error(f);

    // Set model view.
    QMatrix4x4 modelView;
    if (m_zoom != 1.0) {
        if (offset().x() || offset().y())
            modelView.translate(-offset().x() * devicePixelRatio(),
                                 offset().y() * devicePixelRatio());
        modelView.scale(zoom(), zoom());
    }
    m_shader->setUniformValue(m_modelViewLocation, modelView);
    check_error(f);

    // Provide vertices of triangle strip.
    QVector<QVector2D> vertices;
    width = m_rect.width() * devicePixelRatio();
    height = m_rect.height() * devicePixelRatio();
    vertices << QVector2D(float(-width)/2.0f, float(-height)/2.0f);
    vertices << QVector2D(float(-width)/2.0f, float( height)/2.0f);
    vertices << QVector2D(float( width)/2.0f, float(-height)/2.0f);
    vertices << QVector2D(float( width)/2.0f, float( height)/2.0f);
    m_shader->enableAttributeArray(m_vertexLocation);
    check_error(f);
    m_shader->setAttributeArray(m_vertexLocation, vertices.constData());
    check_error(f);

    // Provide texture coordinates.
    QVector<QVector2D> texCoord;
    texCoord << QVector2D(0.0f, 1.0f);
    texCoord << QVector2D(0.0f, 0.0f);
    texCoord << QVector2D(1.0f, 1.0f);
    texCoord << QVector2D(1.0f, 0.0f);
    m_shader->enableAttributeArray(m_texCoordLocation);
    check_error(f);
    m_shader->setAttributeArray(m_texCoordLocation, texCoord.constData());
    check_error(f);

    // Render
    glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size());
    check_error(f);

    // Render RGB frame for analysis
    if (sendFrameForAnalysis) {
        if (!m_fbo || m_fbo->size() != QSize(width, height)) {
            delete m_fbo;
            QOpenGLFramebufferObjectFormat f;
            f.setSamples(0);
            f.setInternalTextureFormat(GL_RGB); //GL_RGBA32F);  // which one is the fastest ?
            m_fbo = new QOpenGLFramebufferObject(width, height, f); //GL_TEXTURE_2D);
        }
        m_fbo->bind();
        glViewport(0, 0, width, height);
        projection.scale((double) this->width() / width, (double) this->height() / height);
        m_shader->setUniformValue(m_projectionLocation, projection);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size());
        check_error(f);
        m_fbo->release();
        emit analyseFrame(m_fbo->toImage());
    }
    // Cleanup
    m_shader->disableAttributeArray(m_vertexLocation);
    m_shader->disableAttributeArray(m_texCoordLocation);
    m_shader->release();
    for (int i = 0; i < 3; ++i) {
        if (m_texture[i]) {
            glActiveTexture(GL_TEXTURE0 + i);
            glBindTexture(GL_TEXTURE_2D, 0);
            check_error(f);
        }
    }
    glActiveTexture(GL_TEXTURE0);
    check_error(f);
}
Пример #10
0
void SSGQuickLayer::grab()
{
    if (!m_item || m_size.isNull()) {
        delete m_fbo;
        delete m_secondaryFbo;
        m_fbo = m_secondaryFbo = 0;
        m_depthStencilBuffer.clear();
        m_dirtyTexture = false;
        return;
    }
    QSGNode *root = m_item;
    while (root->firstChild() && root->type() != QSGNode::RootNodeType)
        root = root->firstChild();
    if (root->type() != QSGNode::RootNodeType)
        return;

    if (!m_renderer) {
        m_renderer = m_context->createRenderer();
        connect(m_renderer, SIGNAL(sceneGraphChanged()), this, SLOT(markDirtyTexture()));
    }
    m_renderer->setDevicePixelRatio(m_device_pixel_ratio);
    m_renderer->setRootNode(static_cast<QSGRootNode *>(root));

    QOpenGLFunctions *funcs = QOpenGLContext::currentContext()->functions();
    bool deleteFboLater = false;
    if (!m_fbo || m_fbo->size() != m_size || m_fbo->format().internalTextureFormat() != m_format
        || (!m_fbo->format().mipmap() && m_mipmap))
    {
        if (!m_multisamplingChecked) {
            if (m_context->openglContext()->format().samples() <= 1) {
                m_multisampling = false;
            } else {
                const QSet<QByteArray> extensions = m_context->openglContext()->extensions();
                m_multisampling = extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_multisample"))
                    && extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_blit"));
            }
            m_multisamplingChecked = true;
        }
        if (m_multisampling) {
            // Don't delete the FBO right away in case it is used recursively.
            deleteFboLater = true;
            delete m_secondaryFbo;
            QOpenGLFramebufferObjectFormat format;

            format.setInternalTextureFormat(m_format);
            format.setSamples(m_context->openglContext()->format().samples());
            m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format);
            m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_secondaryFbo);
        } else {
            QOpenGLFramebufferObjectFormat format;
            format.setInternalTextureFormat(m_format);
            format.setMipmap(m_mipmap);
            if (m_recursive) {
                deleteFboLater = true;
                delete m_secondaryFbo;
                m_secondaryFbo = new QOpenGLFramebufferObject(m_size, format);
                funcs->glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture());
                updateBindOptions(true);
                m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_secondaryFbo);
            } else {
                delete m_fbo;
                delete m_secondaryFbo;
                m_fbo = new QOpenGLFramebufferObject(m_size, format);
                m_secondaryFbo = 0;
                funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
                updateBindOptions(true);
                m_depthStencilBuffer = m_context->depthStencilBufferForFbo(m_fbo);
            }
        }
    }

    if (m_recursive && !m_secondaryFbo) {
        // m_fbo already created, m_recursive was just set.
        Q_ASSERT(m_fbo);
        Q_ASSERT(!m_multisampling);

        m_secondaryFbo = new QOpenGLFramebufferObject(m_size, m_fbo->format());
        funcs->glBindTexture(GL_TEXTURE_2D, m_secondaryFbo->texture());
        updateBindOptions(true);
    }

    // Render texture.
    root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip and opacity update.
    m_renderer->nodeChanged(root, QSGNode::DirtyForceUpdate); // Force render list update.

#ifdef QSG_DEBUG_FBO_OVERLAY
    if (qmlFboOverlay()) {
        if (!m_debugOverlay)
            m_debugOverlay = new QSGSimpleRectNode();
        m_debugOverlay->setRect(QRectF(0, 0, m_size.width(), m_size.height()));
        m_debugOverlay->setColor(QColor(0xff, 0x00, 0x80, 0x40));
        root->appendChildNode(m_debugOverlay);
    }
#endif

    m_dirtyTexture = false;

    m_renderer->setDeviceRect(m_size);
    m_renderer->setViewportRect(m_size);
    QRectF mirrored(m_mirrorHorizontal ? m_rect.right() : m_rect.left(),
                    m_mirrorVertical ? m_rect.bottom() : m_rect.top(),
                    m_mirrorHorizontal ? -m_rect.width() : m_rect.width(),
                    m_mirrorVertical ? -m_rect.height() : m_rect.height());
    m_renderer->setProjectionMatrixToRect(mirrored);
    m_renderer->setClearColor(Qt::transparent);

    if (m_multisampling) {
        m_renderer->renderScene(BindableFbo(m_secondaryFbo, m_depthStencilBuffer.data()));

        if (deleteFboLater) {
            delete m_fbo;
            QOpenGLFramebufferObjectFormat format;
            format.setInternalTextureFormat(m_format);
            format.setAttachment(QOpenGLFramebufferObject::NoAttachment);
            format.setMipmap(m_mipmap);
            format.setSamples(0);
            m_fbo = new QOpenGLFramebufferObject(m_size, format);
            funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
            updateBindOptions(true);
        }

        QRect r(QPoint(), m_size);
        QOpenGLFramebufferObject::blitFramebuffer(m_fbo, r, m_secondaryFbo, r);
    } else {
        if (m_recursive) {
            m_renderer->renderScene(BindableFbo(m_secondaryFbo, m_depthStencilBuffer.data()));

            if (deleteFboLater) {
                delete m_fbo;
                QOpenGLFramebufferObjectFormat format;
                format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
                format.setInternalTextureFormat(m_format);
                format.setMipmap(m_mipmap);
                m_fbo = new QOpenGLFramebufferObject(m_size, format);
                funcs->glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
                updateBindOptions(true);
            }
            qSwap(m_fbo, m_secondaryFbo);
        } else {
            m_renderer->renderScene(BindableFbo(m_fbo, m_depthStencilBuffer.data()));
        }
    }

    if (m_mipmap) {
        funcs->glBindTexture(GL_TEXTURE_2D, textureId());
        funcs->glGenerateMipmap(GL_TEXTURE_2D);
    }

    root->markDirty(QSGNode::DirtyForceUpdate); // Force matrix, clip, opacity and render list update.

#ifdef QSG_DEBUG_FBO_OVERLAY
    if (qmlFboOverlay())
        root->removeChildNode(m_debugOverlay);
#endif
    if (m_recursive)
        markDirtyTexture(); // Continuously update if 'live' and 'recursive'.
}
void QSGPainterNode::updateRenderTarget()
{
    if (!m_extensionsChecked) {
        const QSet<QByteArray> extensions = m_context->openglContext()->extensions();
        m_multisamplingSupported = extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_multisample"))
            && extensions.contains(QByteArrayLiteral("GL_EXT_framebuffer_blit"));
        m_extensionsChecked = true;
    }

    m_dirtyContents = true;

    QQuickPaintedItem::RenderTarget oldTarget = m_actualRenderTarget;
    if (m_preferredRenderTarget == QQuickPaintedItem::Image) {
        m_actualRenderTarget = QQuickPaintedItem::Image;
    } else {
        if (!m_multisamplingSupported && m_smoothPainting)
            m_actualRenderTarget = QQuickPaintedItem::Image;
        else
            m_actualRenderTarget = m_preferredRenderTarget;
    }
    if (oldTarget != m_actualRenderTarget) {
        m_image = QImage();
        delete m_fbo;
        delete m_multisampledFbo;
        delete m_gl_device;
        m_fbo = m_multisampledFbo = 0;
        m_gl_device = 0;
    }

    if (m_actualRenderTarget == QQuickPaintedItem::FramebufferObject ||
            m_actualRenderTarget == QQuickPaintedItem::InvertedYFramebufferObject) {
        const QOpenGLContext *ctx = m_context->openglContext();
        if (m_fbo && !m_dirtyGeometry && (!ctx->format().samples() || !m_multisamplingSupported))
            return;

        if (m_fboSize.isEmpty())
            updateFBOSize();

        delete m_fbo;
        delete m_multisampledFbo;
        m_fbo = m_multisampledFbo = 0;
        if (m_gl_device)
            m_gl_device->setSize(m_fboSize);

        if (m_smoothPainting && ctx->format().samples() && m_multisamplingSupported) {
            {
                QOpenGLFramebufferObjectFormat format;
                format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
                format.setSamples(8);
                m_multisampledFbo = new QOpenGLFramebufferObject(m_fboSize, format);
            }
            {
                QOpenGLFramebufferObjectFormat format;
                format.setAttachment(QOpenGLFramebufferObject::NoAttachment);
                m_fbo = new QOpenGLFramebufferObject(m_fboSize, format);
            }
        } else {
            QOpenGLFramebufferObjectFormat format;
            format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
            m_fbo = new QOpenGLFramebufferObject(m_fboSize, format);
        }
    } else {
        if (!m_image.isNull() && !m_dirtyGeometry)
            return;

        m_image = QImage(m_size, QImage::Format_ARGB32_Premultiplied);
        m_image.fill(Qt::transparent);
    }

    QSGPainterTexture *texture = new QSGPainterTexture;
    if (m_actualRenderTarget == QQuickPaintedItem::Image) {
        texture->setOwnsTexture(true);
        texture->setTextureSize(m_size);
    } else {
        texture->setTextureId(m_fbo->texture());
        texture->setOwnsTexture(false);
        texture->setTextureSize(m_fboSize);
    }

    if (m_texture)
        delete m_texture;

    texture->setTextureSize(m_size);
    m_texture = texture;
}
Пример #12
0
QPaintDevice* QQuickContext2DFBOTexture::beginPainting()
{
    QQuickContext2DTexture::beginPainting();

    if (m_canvasWindow.size().isEmpty()) {
        delete m_fbo;
        delete m_multisampledFbo;
        delete m_paint_device;
        m_fbo = 0;
        m_multisampledFbo = 0;
        m_paint_device = 0;
        return 0;
    } else if (!m_fbo || m_canvasWindowChanged) {
        delete m_fbo;
        delete m_multisampledFbo;
        delete m_paint_device;
        m_paint_device = 0;

        m_fboSize = npotAdjustedSize(m_canvasWindow.size() * m_canvasDevicePixelRatio);
        m_canvasWindowChanged = false;

        if (doMultisampling()) {
            {
                QOpenGLFramebufferObjectFormat format;
                format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
                format.setSamples(8);
                m_multisampledFbo = new QOpenGLFramebufferObject(m_fboSize, format);
            }
            {
                QOpenGLFramebufferObjectFormat format;
                format.setAttachment(QOpenGLFramebufferObject::NoAttachment);
                m_fbo = new QOpenGLFramebufferObject(m_fboSize, format);
            }
        } else {
            QOpenGLFramebufferObjectFormat format;
            format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
            QSize s = m_fboSize;
            if (m_antialiasing) { // do supersampling since multisampling is not available
                GLint max;
                QOpenGLContext::currentContext()->functions()->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
                if (s.width() * 2 <= max && s.height() * 2 <= max)
                    s = s * 2;
            }
            m_fbo = new QOpenGLFramebufferObject(s, format);
        }
    }

    if (doMultisampling())
        m_multisampledFbo->bind();
    else
        m_fbo->bind();

    if (!m_paint_device) {
        QOpenGLPaintDevice *gl_device = new QOpenGLPaintDevice(m_fbo->size());
        gl_device->setPaintFlipped(true);
        gl_device->setSize(m_fbo->size());
        gl_device->setDevicePixelRatio(m_canvasDevicePixelRatio);
        qCDebug(lcCanvas, "%s size %.1lf x %.1lf painting with size %d x %d DPR %.1lf",
                (m_item->objectName().isEmpty() ? "Canvas" : qPrintable(m_item->objectName())),
                m_item->width(), m_item->height(), m_fbo->size().width(), m_fbo->size().height(), m_canvasDevicePixelRatio);
        m_paint_device = gl_device;
    }

    return m_paint_device;
}
Пример #13
0
int main(int argc, char **argv)
{
#ifdef CONSOLE_APPLICATION
    QApplication app(argc, argv, QApplication::Tty);
#else
    QApplication app(argc, argv);
#endif
#ifdef DO_QWS_DEBUGGING
    qt_show_painter_debug_output = false;
#endif

    DeviceType type = WidgetType;
    bool checkers_background = true;

    QImage::Format imageFormat = QImage::Format_ARGB32_Premultiplied;

    QLocale::setDefault(QLocale::c());

    QStringList files;

    bool interactive = false;
    bool printdlg = false;
    bool highres = false;
    bool show_cmp = false;
    int width = 800, height = 800;
    int scaledWidth = width, scaledHeight = height;
    qreal scalefactor = 1.0;
    bool verboseMode = false;

#ifndef QT_NO_OPENGL
    QGLFormat f = QGLFormat::defaultFormat();
    f.setSampleBuffers(true);
    f.setStencil(true);
    f.setAlpha(true);
    f.setAlphaBufferSize(8);
    QGLFormat::setDefaultFormat(f);
#endif

    char *arg;
    for (int i=1; i<argc; ++i) {
        arg = argv[i];
        if (*arg == '-') {
            QString option = QString(arg + 1).toLower();
            if (option == "widget")
                type = WidgetType;
            else if (option == "bitmap")
                type = BitmapType;
            else if (option == "pixmap")
                type = PixmapType;
            else if (option == "image")
                type = ImageType;
            else if (option == "imageformat") {
                Q_ASSERT_X(i + 1 < argc, "main", "-imageformat must be followed by a value");
                QString format = QString(argv[++i]).toLower();

                imageFormat = QImage::Format_Invalid;
                static const int formatCount =
                    sizeof(imageFormats) / sizeof(imageFormats[0]);
                for (int ff = 0; ff < formatCount; ++ff) {
                    if (QLatin1String(imageFormats[ff].name) == format) {
                        imageFormat = imageFormats[ff].format;
                        break;
                    }
                }

                if (imageFormat == QImage::Format_Invalid) {
                    printf("Invalid image format.  Available formats are:\n");
                    for (int ff = 0; ff < formatCount; ++ff)
                        printf("\t%s\n", imageFormats[ff].name);
                    return -1;
                }
            } else if (option == "imagemono")
                type = ImageMonoType;
            else if (option == "imagewidget")
                type = ImageWidgetType;
#ifndef QT_NO_OPENGL
            else if (option == "opengl")
                type = OpenGLType;
            else if (option == "glbuffer")
                type = OpenGLBufferType;
#endif
#ifdef USE_CUSTOM_DEVICE
            else if (option == "customdevice")
                type = CustomDeviceType;
            else if (option == "customwidget")
                type = CustomWidgetType;
#endif
            else if (option == "pdf")
                type = PdfType;
            else if (option == "ps")
                type = PsType;
            else if (option == "picture")
                type = PictureType;
            else if (option == "printer")
                type = PrinterType;
            else if (option == "highres") {
                type = PrinterType;
                highres = true;
            } else if (option == "printdialog") {
                type = PrinterType;
                printdlg = true;
            }
            else if (option == "grab")
                type = GrabType;
            else if (option == "i")
                interactive = true;
            else if (option == "v")
                verboseMode = true;
            else if (option == "commands") {
                displayCommands();
                return 0;
            } else if (option == "w") {
                Q_ASSERT_X(i + 1 < argc, "main", "-w must be followed by a value");
                width = atoi(argv[++i]);
            } else if (option == "h") {
                Q_ASSERT_X(i + 1 < argc, "main", "-h must be followed by a value");
                height = atoi(argv[++i]);
            } else if (option == "scalefactor") {
                Q_ASSERT_X(i + 1 < argc, "main", "-scalefactor must be followed by a value");
                scalefactor = atof(argv[++i]);
            } else if (option == "cmp") {
                show_cmp = true;
            } else if (option == "bg-white") {
                checkers_background = false;
            }
        } else {
#if defined (Q_WS_WIN)
            QString input = QString::fromLocal8Bit(argv[i]);
            if (input.indexOf('*') >= 0) {
                QFileInfo info(input);
                QDir dir = info.dir();
                QFileInfoList infos = dir.entryInfoList(QStringList(info.fileName()));
                for (int ii=0; ii<infos.size(); ++ii)
                    files.append(infos.at(ii).absoluteFilePath());
            } else {
                files.append(input);
            }
#else
            files.append(QString(argv[i]));
#endif
        }
    }
    scaledWidth = width * scalefactor;
    scaledHeight = height * scalefactor;

    PaintCommands pcmd(QStringList(), 800, 800);
    pcmd.setVerboseMode(verboseMode);
    pcmd.setType(type);
    pcmd.setCheckersBackground(checkers_background);

    QWidget *activeWidget = 0;

    if (interactive) {
        runInteractive();
        if (!files.isEmpty())
            interactive_widget->load(files.at(0));
    } else if (files.isEmpty()) {
        printHelp();
        return 0;
    } else {
        for (int j=0; j<files.size(); ++j) {
            const QString &fileName = files.at(j);
            QStringList content;

            QFile file(fileName);
            QFileInfo fileinfo(file);
            if (file.open(QIODevice::ReadOnly)) {
                QTextStream textFile(&file);
                QString script = textFile.readAll();
                content = script.split("\n", QString::SkipEmptyParts);
            } else {
                printf("failed to read file: '%s'\n", qPrintable(fileinfo.absoluteFilePath()));
                continue;
            }
            pcmd.setContents(content);

            if (show_cmp) {
                QString pmFile = QString(files.at(j)).replace(".qps", "_qps") + ".png";
                qDebug() << pmFile << QFileInfo(pmFile).exists();
                QPixmap pixmap(pmFile);
                if (!pixmap.isNull()) {
                    QLabel *label = createLabel();
                    label->setWindowTitle("VERIFY: " + pmFile);
                    label->setPixmap(pixmap);
                    label->show();
                }
            }

            switch (type) {

            case WidgetType:
            {
                OnScreenWidget<QWidget> *qWidget =
                    new OnScreenWidget<QWidget>(files.at(j));
                qWidget->setVerboseMode(verboseMode);
                qWidget->setType(type);
                qWidget->setCheckersBackground(checkers_background);
                qWidget->m_commands = content;
                qWidget->resize(width, height);
                qWidget->show();
                activeWidget = qWidget;
                break;
            }

            case ImageWidgetType:
            {
                OnScreenWidget<QWidget> *qWidget = new OnScreenWidget<QWidget>(files.at(j));
                qWidget->setVerboseMode(verboseMode);
                qWidget->setType(type);
                qWidget->setCheckersBackground(checkers_background);
                qWidget->m_commands = content;
                qWidget->resize(width, height);
                qWidget->show();
                activeWidget = qWidget;
                break;

            }
#ifndef QT_NO_OPENGL
            case OpenGLBufferType:
            {
                QWindow win;
                win.setSurfaceType(QSurface::OpenGLSurface);
                win.create();
                QOpenGLFramebufferObjectFormat fmt;
                fmt.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
                fmt.setSamples(4);
                QOpenGLContext ctx;
                ctx.create();
                ctx.makeCurrent(&win);
                QOpenGLFramebufferObject fbo(width, height, fmt);
                fbo.bind();
                QOpenGLPaintDevice pdev(width, height);

                QPainter pt(&pdev);
                pcmd.setPainter(&pt);
                pcmd.setFilePath(fileinfo.absolutePath());
                pcmd.runCommands();
                pt.end();

                QImage image = fbo.toImage();

                QLabel *label = createLabel();
                label->setPixmap(QPixmap::fromImage(image));
                label->resize(label->sizeHint());
                label->show();
                activeWidget = label;
                break;
            }
            case OpenGLType:
            {
                OnScreenWidget<QGLWidget> *qGLWidget = new OnScreenWidget<QGLWidget>(files.at(j));
                qGLWidget->setVerboseMode(verboseMode);
                qGLWidget->setType(type);
                qGLWidget->setCheckersBackground(checkers_background);
                qGLWidget->m_commands = content;
                qGLWidget->resize(width, height);
                qGLWidget->show();
                activeWidget = qGLWidget;
                break;
            }
#else
            case OpenGLType:
            case OpenGLBufferType:
            {
                printf("OpenGL type not supported in this Qt build\n");
                break;
            }
#endif
#ifdef USE_CUSTOM_DEVICE
            case CustomDeviceType:
            {
                CustomPaintDevice custom(width, height);
                QPainter pt;
                pt.begin(&custom);
                pcmd.setPainter(&pt);
                pcmd.setFilePath(fileinfo.absolutePath());
                pcmd.runCommands();
                pt.end();
                QImage *img = custom.image();
                if (img) {
                    QLabel *label = createLabel();
                    label->setPixmap(QPixmap::fromImage(*img));
                    label->resize(label->sizeHint());
                    label->show();
                    activeWidget = label;
                    img->save("custom_output_pixmap.png", "PNG");
                } else {
                    custom.save("custom_output_pixmap.png", "PNG");
                }
                break;
            }
            case CustomWidgetType:
            {
                OnScreenWidget<CustomWidget> *cWidget = new OnScreenWidget<CustomWidget>;
                cWidget->setVerboseMode(verboseMode);
                cWidget->setType(type);
                cWidget->setCheckersBackground(checkers_background);
                cWidget->m_filename = files.at(j);
                cWidget->setWindowTitle(fileinfo.filePath());
                cWidget->m_commands = content;
                cWidget->resize(width, height);
                cWidget->show();
                activeWidget = cWidget;
                break;
            }
#endif
            case PixmapType:
            {
                QPixmap pixmap(scaledWidth, scaledHeight);
                pixmap.setDevicePixelRatio(scalefactor);
                pixmap.fill(Qt::white);
                QPainter pt(&pixmap);
                pcmd.setPainter(&pt);
                pcmd.setFilePath(fileinfo.absolutePath());
                pcmd.runCommands();
                pt.end();
                pixmap.save("output_pixmap.png", "PNG");
                break;
            }

            case BitmapType:
            {
                QBitmap bitmap(scaledWidth, scaledHeight);
                bitmap.setDevicePixelRatio(scalefactor);
                QPainter pt(&bitmap);
                pcmd.setPainter(&pt);
                pcmd.setFilePath(fileinfo.absolutePath());
                pcmd.runCommands();
                pt.end();
                bitmap.save("output_bitmap.png", "PNG");

                QLabel *label = createLabel();
                label->setPixmap(bitmap);
                label->resize(label->sizeHint());
                label->show();
                activeWidget = label;
                break;
            }

            case ImageMonoType:
            case ImageType:
            {
                qDebug() << "Creating image";
                QImage image(scaledWidth, scaledHeight, type == ImageMonoType
                             ? QImage::Format_MonoLSB
                             : imageFormat);
                image.setDevicePixelRatio(scalefactor);
                image.fill(0);
                QPainter pt(&image);
                pcmd.setPainter(&pt);
                pcmd.setFilePath(fileinfo.absolutePath());
                pcmd.runCommands();
                pt.end();
                image.convertToFormat(QImage::Format_ARGB32).save("output_image.png", "PNG");
                image.setDevicePixelRatio(1.0); // reset scale factor: display "large" image.
#ifndef CONSOLE_APPLICATION
                QLabel *label = createLabel();
                label->setPixmap(QPixmap::fromImage(image));
                label->resize(label->sizeHint());
                label->show();
                activeWidget = label;
#endif
                break;
            }

            case PictureType:
            {
                QPicture pic;
                QPainter pt(&pic);
                pcmd.setPainter(&pt);
                pcmd.setFilePath(fileinfo.absolutePath());
                pcmd.runCommands();
                pt.end();

                QImage image(width, height, QImage::Format_ARGB32_Premultiplied);
                image.fill(0);
                pt.begin(&image);
                pt.drawPicture(0, 0, pic);
                pt.end();
                QLabel *label = createLabel();
                label->setWindowTitle(fileinfo.absolutePath());
                label->setPixmap(QPixmap::fromImage(image));
                label->resize(label->sizeHint());
                label->show();
                activeWidget = label;
                break;
            }

            case PrinterType:
            {
#ifndef QT_NO_PRINTER
                PaintCommands pcmd(QStringList(), 800, 800);
                pcmd.setVerboseMode(verboseMode);
                pcmd.setType(type);
                pcmd.setCheckersBackground(checkers_background);
                pcmd.setContents(content);
                QString file = QString(files.at(j)).replace(".", "_") + ".ps";

                QPrinter p(highres ? QPrinter::HighResolution : QPrinter::ScreenResolution);
                if (printdlg) {
                    QPrintDialog printDialog(&p, 0);
                    if (printDialog.exec() != QDialog::Accepted)
                        break;
                } else {
                    p.setOutputFileName(file);
                }

                QPainter pt(&p);
                pcmd.setPainter(&pt);
                pcmd.setFilePath(fileinfo.absolutePath());
                pcmd.runCommands();
                pt.end();

                if (!printdlg) {
                    printf("wrote file: %s\n", qPrintable(file));
                }

                Q_ASSERT(!p.paintingActive());
#endif
                break;
            }
            case PsType:
            case PdfType:
            {
#ifndef QT_NO_PRINTER
                PaintCommands pcmd(QStringList(), 800, 800);
                pcmd.setVerboseMode(verboseMode);
                pcmd.setType(type);
                pcmd.setCheckersBackground(checkers_background);
                pcmd.setContents(content);
                QPrinter p(highres ? QPrinter::HighResolution : QPrinter::ScreenResolution);
                QFileInfo input(files.at(j));
                const QString file = input.baseName() + QLatin1Char('_')
                                     + input.suffix() + QStringLiteral(".pdf");
                p.setOutputFormat(QPrinter::PdfFormat);
                p.setOutputFileName(file);
                p.setPageSize(QPrinter::A4);
                QPainter pt(&p);
                pcmd.setPainter(&pt);
                pcmd.setFilePath(fileinfo.absolutePath());
                pcmd.runCommands();
                pt.end();

                printf("write file: %s\n", qPrintable(file));
#endif
                break;
            }
            case GrabType:
            {
                QImage image(width, height, QImage::Format_ARGB32_Premultiplied);
                image.fill(QColor(Qt::white).rgb());
                QPainter pt(&image);
                pcmd.setPainter(&pt);
                pcmd.setFilePath(fileinfo.absolutePath());
                pcmd.runCommands();
                pt.end();
                QImage image1(width, height, QImage::Format_RGB32);
                image1.fill(QColor(Qt::white).rgb());
                QPainter pt1(&image1);
                pt1.drawImage(QPointF(0, 0), image);
                pt1.end();

                QString filename = QString(files.at(j)).replace(".qps", "_qps") + ".png";
                image1.save(filename, "PNG");
                printf("%s grabbed to %s\n", qPrintable(files.at(j)), qPrintable(filename));
                break;
            }
            default:
                break;
            }
        }
    }
#ifndef CONSOLE_APPLICATION
    if (activeWidget || interactive) {
        QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
        app.exec();
    }
    delete activeWidget;
#endif
    delete interactive_widget;
    return 0;
}