Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Difference between binding VBO data in "InitializeGL" and "play time"



  • Hi All,

    I am still new to OpenGL and Qt. Thanks for clicking into my post!

    I want to draw a bunch of points inside my window (4MB). The way I did it is via QOpenGLWidget, and inherit QOpenGLFunctions_3_3_core. Firstly, I bind the data to VAO & VBO normally, and draw in "paintGL" via "glDrawArrays(GL_POINTS, 0, size)". It works like a charm, no problem.

    However, now I want to add a switch on/off option to display my points. And also bind my data dynamically. Say I implement a keyPressEvent, when I press "D", it starts "bindVertexArray, bindBuffer, bufferData" blahblah. Now it won't render anything. (sometimes a single point)

    Now my question is why that happens? Do I need to assign "glBufferData" another thread to not to block render thread?

    Thanks.
    Note: Ubuntu16.04, Qt5.6, OpenGL3.3


    One guess is that glBufferData() should be in another separated thread other than paintGL(). Since the data I bind is about 4MB, it might block the thread of paintGL(). However, even so, I think it would still be able to render something later some frames.



  • Hi I finally got it. Previously I thought glGenBuffers() has allocated some places for me. However, it didn't. Dat's why I cannot attach/update my data during render loop. I should fill in some random data with enough size length to be as a placeholder.


  • Lifetime Qt Champion

    Hi,

    You should post your code so that more people can take a look at to see what might be happening.



  • Hi thanks for reminding, there it is

    void MyGLWidget::initializeGL()
    {
        initializeOpenGLFunctions();
    
        camera_pos_ = glm::vec3(0.0f, 0.0f, 50.0f);
        camera_dir_ = glm::vec3(0.0f, 0.0f, -1.0f);
        camera_up_ = glm::vec3(1.0f, 0.0f, 0.0f);
        map_model_ = glm::mat4(1.0f);
        projection_ = glm::perspective(glm::radians(45.0f), (float)width()/(float)height(), 0.1f, 1000.0f);
        view_ = glm::lookAt(camera_pos_, camera_pos_ + camera_dir_, camera_up_);
    
        shader_points = GLShader(context()->functions(), ":/resource/points.vs", ":/resource/points.fs");
        shader_points.use();
        shader_points.setVec3("color", 1.0f, 1.0f, 0.0f);
        shader_points.setMat4("model", model_);
        shader_points.setMat4("view", view_);
        shader_points.setMat4("projection", projection_);
    
        glGenVertexArrays(1, &vao_points);
        glGenBuffers(1, &vbo_points);
        // Part 1---------------------
        glBindVertexArray(vao_points);
        glBindBuffer(GL_ARRAY_BUFFER, vbo_points);
        glBufferData(GL_ARRAY_BUFFER, sizeof(float) * points.size(), &points[0], GL_DYNAMIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
        glEnableVertexAttribArray(0);
        glBindVertexArray(0);  
        // Part 1 ends----------------
    }
    
    void MyGLWidget::paintGL()
    {
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        if(render_points){
            shader_points.use();
            glBindVertexArray(vao_points);
            glDrawArrays(GL_POINTS, 0, points.size());
        }
    }
    
    void MyGLWidget::keyPressEvent(QKeyEvent *event)
    {
        if(event->key() == Qt::Key_Q){
            std::cout << "could render" << std::endl;
            render_points = true;
            // Part 1 place holder
            // code
        }
    }
    

    Basically, I set a "Q" press event to turn on the rendered points. In "points", it is a vector of float, It's around 4MB data in total and I load it from fstream at the beginning (in constructor). The above code could normally render on my QOpenGLWidget.
    However when I move my "glBufferData()" part (Part1 in initializeGL()) to keyPressEvent() (Part1 place holder), it won't render anything.

    I think it's probably I should separate the render thread and glBufferData() thread. Perhaps what happens is that the BufferData thread blocks render thread. If so, would TheadPool in Qt help with it? I haven't wrote some real multi-thread code before...So seeking for advice, thanks a lot.



  • @SGaist May I ask if paintGL() would automatically swapBuffer()?



  • Hi I finally got it. Previously I thought glGenBuffers() has allocated some places for me. However, it didn't. Dat's why I cannot attach/update my data during render loop. I should fill in some random data with enough size length to be as a placeholder.


Log in to reply