Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QQuickFramebufferObject rendered with modern opengl(3.3) works unnormal.

QQuickFramebufferObject rendered with modern opengl(3.3) works unnormal.

Scheduled Pinned Locked Moved Solved QML and Qt Quick
2 Posts 1 Posters 754 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • F Offline
    F Offline
    fisher103
    wrote on last edited by fisher103
    #1

    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:
    0_1540558658600_normal.png
    the next frame can not be rendered, like this
    1_1540558658600_unnormal.png

    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.

    1 Reply Last reply
    0
    • F Offline
      F Offline
      fisher103
      wrote on last edited by fisher103
      #2

      Finally, I find adding glDisable(GL_DEPTH_TEST) makes everything fine; Maybe it's depth test makes background front of the user rectangle. the true reason need explore there.

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved