Solved 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.
-
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.