我正在尝试使用QGLWidget实现CoverFlow效果,问题在于纹理加载过程。Qt4/Opengl bindTexture在分离线程中
我有一个工作(QThread)从磁盘加载图像,主线程检查新加载的图像,如果它发现任何然后使用bindTexture将它们加载到QGLContext中。当纹理被绑定时,主线程被阻塞,所以我有一个fps的下降。
这样做的正确方法是什么?
我正在尝试使用QGLWidget实现CoverFlow效果,问题在于纹理加载过程。Qt4/Opengl bindTexture在分离线程中
我有一个工作(QThread)从磁盘加载图像,主线程检查新加载的图像,如果它发现任何然后使用bindTexture将它们加载到QGLContext中。当纹理被绑定时,主线程被阻塞,所以我有一个fps的下降。
这样做的正确方法是什么?
在主线程(单QGLWidget
溶液)的结合:
决定最大纹理大小。例如,您可以根据最大可能的小部件大小来决定它。假设您知道该窗口小部件最多可以(大约)800x600像素,并且最大的可见屏幕上下可以看到30像素的边距,并且纵横比为1:2 - > 600-2 * 30 = 540 - >封面的最大尺寸为270x540,例如存储在m_maxCoverSize
。
在加载程序线程中将传入图像缩放到该大小。绑定较大的纹理并没有意义,并且它越大,上传到显卡所需的时间就越长。使用QImage::scaled(m_maxCoverSize, Qt::KeepAspectRatio)
来缩放加载的图像并将其传递给主线程。
限制纹理的数量或更好地花费每帧绑定它们的时间。即记住你开始绑定纹理的时间(例如QTime bindStartTime
;),并绑定每个纹理之后:
if(bindStartTime.elapsed()> BIND_TIME_LIMIT) break;
BIND_TIME_LIMIT
将取决于你想保留的帧频。但是,当然,如果绑定每一个纹理需要比BIND_TIME_LIMIT
长得多的时间,你还没有解决任何问题。
尽管在较慢的机器/图形卡上加载图像,但您仍然可能会遇到帧率下降。其余的代码应该准备好与它一起生活(例如,使用实际的时间来驱动动画)。
替代溶液是在单独的线程绑定(使用第二隐形QGLWidget
,见):在一个线程
2.
纹理上传。在处理大量需要显示的图像的应用程序中执行纹理上传可能非常有用,例如照片库应用程序。 Qt通过现有的bindTexture()API支持这一点。一个简单的方法是创建两个共享的QGLWidgets。一个是在主GUI线程中创建的,另一个是在纹理上传线程中创建的。上传线程中的小部件从不显示,它仅用于与主线程共享纹理。对于通过bindTexture()绑定的每个纹理,请通知主线程,以便它可以开始使用纹理。
我发现bindTexture在Qt4的默认行为是extremelly慢:
bindTexture(image,target,format,LinearFilteringBindOption | InvertedYBindOption | MipmapBindOption)
仅使用绑定选项LinearFilteringBindOption加快了很多东西,这是我当前的呼叫:
bindTexture(image, GL_TEXTURE_2D,GL_RGBA,QGLContext::LinearFilteringBindOption);
的详细信息here:加载时间为3800x2850 bmp文件2秒降低到34毫秒
当然,如果你需要mipmapping,这不是解决方案。在这种情况下,我认为要走的路是像素缓冲区对象。
问题是纹理大小,我使用480x700图像(或多或少),但每个封面都有自己的大小(480x741,480x744,640x437),以保持封面的高宽比。我已经缩小了工作线程上的覆盖范围,但取决于显卡,封面尺寸必须缩放太多。 – louissmr
为什么会出现这种问题? – artm
对不起,我的评论不完整。 – louissmr