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. QOpenGLFramebufferObject renders only first frame
QtWS25 Last Chance

QOpenGLFramebufferObject renders only first frame

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qtquickopenglframebuffer
2 Posts 1 Posters 1.1k 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.
  • K Offline
    K Offline
    Kyroaku
    wrote on 3 Nov 2019, 18:01 last edited by Kyroaku 11 Mar 2019, 18:03
    #1

    HI!

    I am trying to use OpenGL with QtQuick, with use of QQuickFramebufferObject. Generally, everything seems to be working, but only on the first frame. Every other redraw (resizing window or calling 'update()') gives empty widget filled with color set by glClearColor(...). I was trying to manipulate with OpenGL's state, disabling everything that could potentially make scene invisible, but nothing solved the problem. I can't find similar problem in web so i'm asking for help here.

    I'm guessing the problem can be with context state after Qt done some stuff on other widgets but i have no idea what could go wrong with this code :/

    Or maybe I am trying something very weird here? I don't know. I have seen couple of ways to use OpenGL with Qt but do not exacly know which way is the preffered one.

    I will be grateful for any kind of help.

    first frame
    c0190420-540d-455b-aabf-a4322c2f49ea-image.png

    redrawed window after resize (update() gives same effect)
    23c015b2-d9da-45d3-a6a2-7035685be17b-image.png

    qml

    import QtQuick 2.12
    import QtQuick.Window 2.12
    
    import OpenGLItem 1.0
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        OpenGLItem {
            anchors.fill: parent
        }
    }
    

    createRenderer()

    QQuickFramebufferObject::Renderer *OpenGLItem::createRenderer() const
    {
        return new OpenGLRenderer();
    }
    

    Renderer

    #include "openglitem.h"
    
    #include <QOpenGLFramebufferObjectFormat>
    #include <QOpenGLFunctions>
    #include <QQuickWindow>
    
    class OpenGLRenderer : public QQuickFramebufferObject::Renderer
    {
    private:
        GLuint m_VBO;
        GLuint m_ShaderProgram;
        QQuickWindow *m_Window = nullptr;
    
    public:
        OpenGLRenderer()
        {
            QOpenGLFunctions *ogl = QOpenGLContext::currentContext()->functions();
    
            float verts[] = {
                -1.0f, -1.0f, 0.0f,
                1.0f, -1.0f, 0.0f,
                0.0f, 1.0f, 0.0f
            };
    
            const char *vertexShaderSource =
                    "#version 330 core\n"
                    "layout(location=0) in vec3 a_Position;\n"
                    "void main() {\n"
                    " gl_Position = vec4(a_Position, 1.0);\n"
                    "}\n\0";
    
            const char *fragmentShaderSource =
                    "#version 330 core\n"
                    "out vec4 FragColor;\n"
                    "void main() {\n"
                    " FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
                    "}\n\0";
    
            char infoLog[1024];
    
            ogl->glGenBuffers(1, &m_VBO);
            ogl->glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
            ogl->glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
            ogl->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
            ogl->glEnableVertexAttribArray(0);
            ogl->glBindBuffer(GL_ARRAY_BUFFER, 0);
    
            m_ShaderProgram = ogl->glCreateProgram();
    
            GLuint vertexShader = ogl->glCreateShader(GL_VERTEX_SHADER);
            ogl->glShaderSource(vertexShader, 1, &vertexShaderSource, 0);
            ogl->glCompileShader(vertexShader);
            ogl->glAttachShader(m_ShaderProgram, vertexShader);
            ogl->glGetShaderInfoLog(vertexShader, 1024, 0, infoLog);
            qDebug() << infoLog;
            ogl->glDeleteShader(vertexShader);
    
            GLuint fragmentShader = ogl->glCreateShader(GL_FRAGMENT_SHADER);
            ogl->glShaderSource(fragmentShader, 1, &fragmentShaderSource, 0);
            ogl->glCompileShader(fragmentShader);
            ogl->glAttachShader(m_ShaderProgram, fragmentShader);
            ogl->glGetShaderInfoLog(fragmentShader, 1024, 0, infoLog);
            qDebug() << infoLog;
            ogl->glDeleteShader(fragmentShader);
    
            ogl->glLinkProgram(m_ShaderProgram);
            ogl->glGetProgramInfoLog(m_ShaderProgram, 1024, 0, infoLog);
            qDebug() << infoLog;
    
            ogl->glUseProgram(m_ShaderProgram);
        }
    
        virtual void render() override
        {
            static bool firstTime = true;
    
            QOpenGLFunctions *ogl = QOpenGLContext::currentContext()->functions();
    
            ogl->glDisable(GL_DEPTH_TEST);
            ogl->glDisable(GL_CULL_FACE);
            ogl->glDisable(GL_SCISSOR_TEST);
            ogl->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
            ogl->glDisable(GL_BLEND);
            ogl->glDisable(GL_TEXTURE_2D);
    
            if(firstTime) {
                firstTime = false;
                ogl->glClearColor(1.0f, 1.0f,0.0f,1.0f);
            }
            else
                ogl->glClearColor(1.0f, 0.0f,1.0f,1.0f);
            ogl->glClear(GL_COLOR_BUFFER_BIT);
    
            ogl->glUseProgram(m_ShaderProgram);
            ogl->glBindBuffer(GL_ARRAY_BUFFER, m_VBO);
            ogl->glDrawArrays(GL_TRIANGLES, 0, 3);
            ogl->glBindBuffer(GL_ARRAY_BUFFER, 0);
    
            ogl->glFlush();
            ogl->glFinish();
    
            ogl->glUseProgram(0);
    
            update();
            if(m_Window)
                m_Window->resetOpenGLState();
    
        }
    
        virtual QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) override
        {
            QOpenGLFramebufferObjectFormat format;
            format.setAttachment(QOpenGLFramebufferObject::Attachment::Depth);
            format.setSamples(1);
            return new QOpenGLFramebufferObject(size, format);
        }
    
        virtual void synchronize(QQuickFramebufferObject *item) override
        {
            m_Window = item->window();
        }
    };
    

    main

    #include "openglitem.h"
    
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        qmlRegisterType<OpenGLItem>("OpenGLItem", 1, 0, "OpenGLItem");
    
        QQmlApplicationEngine engine;
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.load(url);
    
        return app.exec();
    }
    
    1 Reply Last reply
    0
    • K Offline
      K Offline
      Kyroaku
      wrote on 7 Nov 2019, 21:57 last edited by
      #2

      'Client vertex and index arrays - all vertex array attribute and element array
      index pointers must refer to buffer objects. The default vertex array object
      (the name zero) is also deprecated
      . Calling VertexAttribPointer when no
      buffer object or no vertex array object is bound will generate an INVALID_-
      OPERATION error, as will calling any array drawing command when no vertex array object is bound.'

      source: https://www.khronos.org/registry/OpenGL/specs/gl/glspec33.core.pdf
      page 344

      1 Reply Last reply
      0

      2/2

      7 Nov 2019, 21:57

      • Login

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