我绑定了一个自定义FBO,但我画的不仅仅是它

时间:2017-07-19 18:51:49

标签: qt opengl qml qtquick2 fbo

我做了一个简单的测试用例。我做了什么,简而言之:

  • 我有一个名为MyItem的QQuickFramebufferObject子类。它使用CombinedDepthStencil附件类型。
  • 我在窗口悬停上创建一个MyItem实例,并在取消窗口
  • 上销毁它
  • MyItemRenderer::render()我创建一个本地FBO并为其绘制一个三角形
  • 此本地FBO使用自定义FBO包装类而不是QOpenGLFramebufferObject来缩小问题范围。但是,QOpenGLFramebufferObject也会出现问题。

预期的行为是不应该向窗口绘制任何内容。但是,在第二次时间你悬停窗口(启动应用程序后),三角形将被绘制到窗口。

我的代码:

的main.cpp

#include <QGuiApplication>
#include <QQuickView>
#include <QQuickWindow>
#include <QQuickFramebufferObject>
#include <QOpenGLFramebufferObject>
#include <QOpenGLShaderProgram>
#include <QOpenGLFunctions>
#include <QOpenGLTexture>
#include "fbo.h"

class MyItem : public QQuickFramebufferObject {
    Q_OBJECT

public:
    Renderer* createRenderer() const;
};

class MyItemRenderer : public QQuickFramebufferObject::Renderer, protected QOpenGLFunctions {
public:
    MyItemRenderer() {
        initializeOpenGLFunctions();

        m_program.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shader.vert.glsl");
        m_program.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shader.frag.glsl");
        m_program.link();
    }

    void render() {
        glClearColor(0, 0, 0, 0);
        glDisable(GL_DEPTH_TEST);

        Fbo fbo(m_size);

        m_program.bind();
        fbo.bind();
        glClear(GL_COLOR_BUFFER_BIT);
        paintGeometry();

        framebufferObject()->bind();

        m_window->resetOpenGLState();
    }

    void paintGeometry() {
        QVector<QVector2D> vertices = { QVector2D(0, 0), QVector2D(1, 0), QVector2D(1, 1) };

        m_program.enableAttributeArray("aPos");
        m_program.setAttributeArray("aPos", vertices.constData());
        glDrawArrays(GL_TRIANGLES, 0, vertices.size());
        m_program.disableAttributeArray("aPos");
    }

    QOpenGLFramebufferObject* createFramebufferObject(const QSize &size) {
        QOpenGLFramebufferObjectFormat format;
        format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
        return new QOpenGLFramebufferObject(size, format);
    }

private:
    QOpenGLShaderProgram m_program;
    QQuickWindow* m_window;
    QSize m_size;

protected:
    void synchronize(QQuickFramebufferObject* qqfbo) {
        MyItem* parentItem = (MyItem*)qqfbo;
        m_window = parentItem->window();
        m_size = QSize(parentItem->width(), parentItem->height());
    }
};

QQuickFramebufferObject::Renderer* MyItem::createRenderer() const {
    return new MyItemRenderer();
}

int main(int argc, char **argv) {
    QGuiApplication app(argc, argv);

    qmlRegisterType<MyItem>("MyItem", 1, 0, "MyItem");

    QQuickView view;
    view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
    view.show();

    return app.exec();
}

#include "main.moc"

main.qml

import QtQuick 2.0
import MyItem 1.0

Item {
    width: 400
    height: 400
    id: root

    Loader {
        active: mouseArea.containsMouse
        sourceComponent: MyItem {
            parent: root
            anchors.fill: parent
        }
    }
    MouseArea {
        id: mouseArea
        hoverEnabled: true
        anchors.fill: parent
    }
}

shader.frag.glsl

void main() {
    gl_FragColor = vec4(0.40, 1.0, 0.0, 1.0);
}

shader.vert.glsl

attribute highp vec2 aPos;

void main() {
    gl_Position = vec4(aPos, 0.0, 1.0);
}

fbo.h

#ifndef FBO_H
#define FBO_H

#include <QOpenGLFunctions>
#include <QOpenGLTexture>

class Fbo : public QOpenGLFunctions {
public:
    Fbo(const QSize &size)
        : m_colorAttachment(QOpenGLTexture::Target2D)
    {
        initializeOpenGLFunctions();

        glGenFramebuffers(1, &m_id);

        m_colorAttachment.setSize(size.width(), size.height());
        m_colorAttachment.setFormat(QOpenGLTexture::RGBA8_UNorm);
        m_colorAttachment.allocateStorage();
        bind();
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorAttachment.textureId(), 0);
    }
    ~Fbo() {
        glDeleteFramebuffers(1, &m_id);
    }

    void bind() {
        glBindFramebuffer(GL_FRAMEBUFFER, m_id);
    }

private:
    GLuint m_id;
    QOpenGLTexture m_colorAttachment;
};

#endif

有什么想法吗?

请注意,我在CodeXL OpenGL调试器中运行了测试用例,但没有发现OpenGL错误。与Qt的QOpenGLDebugLogger机制相同。

0 个答案:

没有答案