我做了一个简单的测试用例。我做了什么,简而言之:
QQuickFramebufferObject
子类。它使用CombinedDepthStencil
附件类型。MyItemRenderer::render()
我创建一个本地FBO并为其绘制一个三角形预期的行为是不应该向窗口绘制任何内容。但是,在第二次时间你悬停窗口(启动应用程序后),三角形将被绘制到窗口。
我的代码:
的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
机制相同。