QQuickFramebufferObject rendered with modern opengl(3.3) works unnormal.
-
I work as Qt example textureinsgnode does but use QOpenGLExtraFunctions as the "Renderer" instead.
//HQSmartVideo.h class HQSmartVideo : public QQuickFramebufferObject { Q_OBJECT public: explicit HQSmartVideo(QQuickItem *parent = nullptr); ~HQSmartVideo(); Renderer *createRenderer() const override; }; class HobotVideoFboRenderer : public QQuickFramebufferObject::Renderer { public: HobotVideoFboRenderer() { view.initializeGL(); } void synchronize(QQuickFramebufferObject*item){ //to do } virtual void render() override { view.paintGL(); //update(); } QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) { QOpenGLFramebufferObjectFormat format; format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil); format.setSamples(4); return new QOpenGLFramebufferObject(size, format); } private: VideoCore view; }; //HQSmartVideo.cpp HQSmartVideo::HQSmartVideo(QQuickItem *parent): QQuickFramebufferObject(parent) { } HQSmartVideo::~HQSmartVideo() { } QQuickFramebufferObject::Renderer *HQSmartVideo::createRenderer() const { return new HobotVideoFboRenderer(); } class VideoCore : protected QOpenGLExtraFunctions { public: explicit VideoCore(QWidget *parent = 0); ~VideoCore(); //QOpenGLWidget need override void initializeGL(); void paintGL(); protected: void initShader(); void initialize(); void createRectSingleVAO(); unsigned int m_vboRectSingle = 0, m_eboRectSingle = 0, m_vaoRectSingle = 0; private: Shader m_shader; }; void VideoCore::initShader() { // build and compile our shader program QFile vshader(":shader/shader/shader.vs.cc"); QFile fshader(":shader/shader/shader.fs.cc"); if (!vshader.open(QIODevice::ReadOnly)) return; if (!fshader.open(QIODevice::ReadOnly)) return; QByteArray versionHeader; if(QOpenGLContext::currentContext()->isOpenGLES()) versionHeader.append("#version 300 es\nprecision lowp float;\n"); else versionHeader.append("#version 330\n"); m_shader.setShader(versionHeader+vshader.readAll(), versionHeader+fshader.readAll()); m_shader.use(); } void VideoCore::initialize() { createRectSingleVAO(); } void VideoCore::createRectSingleVAO() { //triangle vao vbo define glGenVertexArrays(1, &m_vaoRectSingle); glGenBuffers(1, &m_vboRectSingle); glGenBuffers(1, &m_eboRectSingle); // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). glBindVertexArray(m_vaoRectSingle); glBindBuffer(GL_ARRAY_BUFFER, m_vboRectSingle); glBufferData(GL_ARRAY_BUFFER, sizeof(verticesRect), verticesRect, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_eboRectSingle); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(verticesIndices), verticesIndices, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float))); glEnableVertexAttribArray(1); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } void VideoCore::initializeGL() { initializeOpenGLFunctions(); initShader(); initialize(); } void VideoCore::paintGL() { m_shader.use();//this line makes no change if removed. glClearColor(0.f, 1.f, 0.f, 1.0f);//background with green glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //rectangle with red center in the screen glBindVertexArray(m_vaoRectSingle); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, NULL); glBindBuffer(GL_ARRAY_BUFFER, 0); }shader simple like this
//vertex shader layout (location = 0) in vec2 aPos; layout (location = 1) in vec2 para; void main() { gl_Position = vec4(aPos, 0.0, 1.0); } //fragment shader out vec4 FragColor; void main() { FragColor = vec4(1, 0, 0, 1); }//mian.cpp QSurfaceFormat fmt; fmt.setSamples(8); fmt.setVersion(3, 3);//use modern opengl fmt.setProfile(QSurfaceFormat::CoreProfile); QSurfaceFormat::setDefaultFormat(fmt); ..... QQuickView view; view.setFormat(fmt); view.setResizeMode(QQuickView::SizeRootObjectToView); view.setSource(QUrl("main.qml")); view.show();the first frame is normal like this:

the next frame can not be rendered, like this

the code above is migrated from desktop app of Qt which work normal, but with qml it breaks.
search from the internet, it may be the vao build in the intialize module not work in the QQuickFramebufferObject::Renderer::render() function. or it may be can use the simple api of gles2.0.I find example like this works well except that there are no vao and they do most their work in render() function.
can somebody give some advise.