Qt4 / Opengl bindTexture in a separate branch

I'm trying to implement CoverFlow effect using QGLWidget, the problem is loading the texture.

I have a worker (QThread) for loading images from disk, and the main thread checks for new downloaded images, if it finds, then uses bindTexture to load them into QGLContext. While the texture is bound, the main thread is blocked, so I have a drop in fps.

What is the right way to do this?

0
qt qt4 opengl qthread
source share
2 answers

Binding in the main thread (one QGLWidget solution):

  • Select the maximum texture size. You can solve this based on the maximum size of the widget, for example. Let's say you know that a widget can be no more than (approximately) 800x600 pixels, and the largest visible cover has a 30x margin up and down and the aspect ratio is 1: 2 β†’ 600-2 * 30 = 540 β†’ the maximum cover size is 270x540, for example stored in m_maxCoverSize .

  • scale incoming images to this size in the bootloader stream. It makes no sense to bind large textures, and the more it will be, the longer it will take to load on a graphics card. Use QImage::scaled(m_maxCoverSize, Qt::KeepAspectRatio) to scale the loaded image and transfer it to the main stream.

  • limit the number of textures or the best time taken to snap them to the frame. That is, remember the time when you started linking textures (for example, QTime bindStartTime ;) and after binding each texture do:

    if (bindStartTime.elapsed ()> BIND_TIME_LIMIT) break;

BIND_TIME_LIMIT will depend on the frame rate that you want to keep. But, of course, if snapping each texture takes much longer than BIND_TIME_LIMIT , you haven’t decided anything.

Still, frames may drop when loading images, albeit on slower machines / video cards. The rest of the code should be prepared to live with it (for example, use the actual time to animate the disks).


An alternative solution is to bind in a separate thread (using the second invisible QGLWidget , see the documentation ):

2. Loading the texture into the stream.

Performing texture loading in a stream can be very useful for applications that process a large number of images that need to be displayed, for example, for example, a photo gallery application. This is supported in Qt through the existing bindTexture () API. An easy way to do this is to create two sections of QGLWidgets. One of them runs in the main thread of the graphical user interface, and the other in the texture load stream. The widget in the download stream is never displayed, it is used only for sharing textures with the main stream. For each texture associated with bindTexture (), notify the main thread so that it can start using the texture.

0
source share

I found that the default behavior of bindTexture in Qt4 is extremely slow:

 bindTexture(image,target,format,LinearFilteringBindOption | InvertedYBindOption | MipmapBindOption) 

using only LinearFilteringBindOption in binding options speeds up a lot, this is my current call:

 bindTexture(image, GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption); 

more details here : loading time for the 3800x2850 bmp file has been reduced from 2 seconds to 34 milliseconds

Of course, if you need mipmapping, this is not a solution. In this case, I think the path is the pixel objects of the buffer.

+2
source share

All Articles