QT OpenGL application does not update main window when doing multiple render calls (MAC OS version:10.12.2)
-
I am pretty new with working with QT and I tried to adapt a program, which I wrote in Xcode to QT, for developing it on multiple platforms. On Xcode this code works, thats why there must be something with QT what I do not understand, why it is not working.
As explanation my code loads images and render them to a screen (That works). I have also a checkbox, where I can check which image the application should render to screen, the color or the depth image of the currently loaded image. When I press a button, the application should load a new image and does two render steps(which are only for calculations), which are rendered to a FBO:
glBindFramebuffer(GL_FRAMEBUFFER, _fbo_1); glBindVertexArray(_vao); glUseProgram(_program_D); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, color); glUniform1i(glGetUniformLocation(_program_D, "_colorImage"), 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, depth); glUniform1i(glGetUniformLocation(_program_D, "_depthImage"), 1); glDrawArrays(GL_TRIANGLES, 0, 6);
This is an example of one of these render calls. This render call is actually nothing special, it just copies two textures (color, depth) to two textures hooded by the FBO(_fbo_1).
I used a breakpoint to follow the code, and actually everything seems to work great. If I do not call the two render calls, the application normally loads the new image, and with the checkboxes I can switch between color and depth image. But If the application now does such a render call, doesn't mather which, he seems to freeze.
I can not see the new loader image, the checkboxes are not been recognized anymore. I have no idea what is going wrong there. -
Ok, I think I have solved it now. But I do not know why. I called the render function from the main window, in the pressButton function.
What I changed now was, that i only set a boolean, for button was pressed. And in the function paintGL() the if statement to render the addition render calls, if the button was pressed.Can it be that I can only do render calls in the paintGL() function? or what can it be?
-
I don't know if this is your problem but I had similar stability problems when I was working with QOpenglWidgets. It worked fine on Xcode but was crash-happy on windows. It was bad enough that I stuck with the older QGlWidget for a while.
After a lot of tracking I found that Qt did not set the CS_OWNDC when it registers it internal class structure used for QOpenglWidgets. This makes it unstable as the OpenGl rendering context is associated with the windows device context.
My fix was simple. When you create the QOpenGlWidget make sure to pass the window flag Qt::MSWindowsOwnDC. Once I did it ran like a champ.
You didn't mention what OS your program didn't work on. If it is Windows this is a possible reason for your problems (assuming you didn't already add this flag).
-
I am working with MAC OS version:10.12.2. I added it to the title. I don't believe that this is the same problem. Because I create a context and render the loaded image to that context without any problems. Only if I start using the a second render pass, the hole main window does not update somehow.
I found out, if I set a breakpoint int the pressButton section, it still get's called when I press this button. But somehow still the context does not get updated even a different image is loaded to the GPU. and the checkbox icons do not recognize if I clicked them, so changes the symbol. And the button stays in the color for (pressed).
I suppose the program does not find the way back and gets stuck in an infinite loop or something. Because If I follow with breakpoints the application goes through every step he has to in the press button function. But after this function I have no idea what he is doing.Also if I set breakpoints to the paintGL() it still get's called.
-
Ok, I think I have solved it now. But I do not know why. I called the render function from the main window, in the pressButton function.
What I changed now was, that i only set a boolean, for button was pressed. And in the function paintGL() the if statement to render the addition render calls, if the button was pressed.Can it be that I can only do render calls in the paintGL() function? or what can it be?
-
Hi,
Because paintGL is called with everything ready for your widget to execute OpenGL code. Doing it freely like that from another method means that the OpenGL context is likely not current and it might even be happening in a different thread.
I'd recommend taking a look at the various OpenGL examples in Qt's documentation, you'll see that there's almost always the same pattern: everything that can be modified is stored and checked before the painting happens.