PDA

View Full Version : Using QOpenGLWidget, swapBuffers?



Hyvok
7th March 2015, 11:06
Hey!

I developed a piece of software that displays stuff with OpenGL. I originally made the thing using GLFW and using a OpenGL 3.0 context. To get a UI I swapped the GLFW library to Qt and changed to QOpenGLWidget. I am using shaders and doing pretty much everything in shaders so to prevent rewriting most of my OpenGL code I do not want to use Qts OpenGL 2.0 ES API.

I have everything working pretty nicely except I cannot figure out why the OpenGL scene is only drawn the first time and nothing happens on successive paintGL() calls.

I have a RenderWidget which inherits from QOpenGLWidget. In its constructor I set:


QSurfaceFormat format;
format.setVersion(3,0);
format.setSamples(4);
format.setProfile(QSurfaceFormat::NoProfile);
format.setSwapBehavior(QSurfaceFormat::DoubleBuffe r);
setFormat(format);

Then in initializeGL() I do:


context_ = context();
funcs_ = context_->versionFunctions<QOpenGLFunctions_3_0>();
funcs_->initializeOpenGLFunctions();
renderer_.init(funcs_);

Where renderer_ is of type Renderer which just calls OpenGL functions through the funcs_ pointer and sets up all the shaders and VBOs and buffers and so forth.

Then in paintGL() I basically just do:


renderer_.render();

Where render() just calls glClearColor(), glClear() and then glDrawArrays(). This works when the window is created. Notice that I am NOT swapping the buffers anywhere in my code. With GLFW I called glfwSwapBuffers() at the end of render() and that worked.

However now when I try to reimplement zoom (that was working with GLFW) where I change a uniform variable in a shader the OpenGL scene does not change at all. After changing the projection matrix in a wheelEvent() function within RendererWidget I call update() (I also tried calling paintGL() directly) which then in turn schedules a call to paintGL(). I have verified that paintGL() gets called after each wheelEvent() but the scene does not change.

I tried doing:


context_->swapBuffers(context_->surface());

After renderer_.render() in paintGL() but this sounds... Somehow wrong (why give the contexts own QSurface back to it?) but this is the only function I could find that is related to swapping buffers.

What am I doing wrong? Who is supposed to swap the buffers after rendering in paintGL()? The docs say "Before invoking this function, the context and the framebuffer are bound, and the viewport is set up by a call to glViewport(). No other state is set and no clearing or drawing is performed by the framework." but then why does it draw the scene when the window is created? How do I swap the buffers with Qt? What else do I need to do to actually swap buffers and/or display changes after rendering in paintGL()? Thanks for the help!

Edit: Solved it, you do not need to explicitly call swapBuffers() or anything. The problem was that I was calling the glUniform() function from an event handler function where the OpenGL context is NOT set thus it had no effect. Changed it to be called in the paintGL() function and everything works now.

kachhadiyatushar
27th January 2016, 15:28
Hello,

I am new to QOpenGLWidget and using OpenGL ES 2.0. I have been trying to display the camera captured frame in QOpenGLWidget. I have used QGLWidget for frame display with QT 5.2.1. Now I am trying to port it to Raspberry pi and it has ES 2.0 API and QT 5.4.1. So would you please help to accomplish this task?


Thanks

Tushar

bmn
24th November 2016, 12:03
Thanks Hyvok for that Edit - saved my day and a lot of hours of work
after 20 unsuccessful hours i was about to use GLFW again ^^ but now QT is updating in 60fps