2012-04-29 177 views
1

我有大约六个文件,每个250 KB到500 KB。每个文件都有多个QImages;每个文件大约有400张128x64的图像。加载到内存大约60MB/s(因为OpenGL需要将PNG解压缩到它自己的格式)。缓慢的纹理加载

可以加快这个过程吗?由于我有一场演出要填补,所以速度很慢。

QFile file("file.ucv"); 

if (file.open(QIODevice::ReadOnly)) { 
    qDebug() << "Read from hdd"; 

    QDataStream r(&file); 
    r.setVersion(QDataStream::Qt_4_3); 

    QImage t; 

    int i = maxPics * place; 
    glGenTextures(maxPics, &texture[i]); 
    for (int y = 0; y < yNrPics; y++) 
     for (int x = 0; x < xNrPics; x++, i++) { 

      // Write to precomputed object 
      r >> t; 

      glBindTexture(GL_TEXTURE_2D, texture[i]); 
      glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits()); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
     } 

探查发现这条线是最consumptious:

  glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA, t.width(), t.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, t.bits()); 

改变压缩到未压缩,可以节省一些时间,但仍然不多。

加载的QImage在GLformat中。

+1

一个好的开始是分析代码,看看哪一个是瓶颈。 –

+0

上传到GPU时,最有可能是CPU忙于等待。 – RobotRock

+0

不是,图像很小,上传和设置开销可能是瓶颈。 –

回答

2

请确保您确定您的数据:

  • I.e.确保探查器显示挂钟,而不仅仅是CPU消耗(因为磁盘I/O不消耗CPU,但需要时间)。

另外,避免做的工作是最好的优化:

  • 如果你想使用压缩纹理,压缩他们只有一次(第一次上传),然后下载的压缩数据,并将其缓存到磁盘。随后的上传应该直接从磁盘发送压缩数据到OpenGL,而不需要从png-via-raw-to-gl重新压缩。

流水线的工作,尤与I/O是加快速度的好办法,而且通常很容易(生产者 - 消费者parallellism):

  • 管道上传通过使用单独的线程加载图像并创建纹理。 Qt通过QtConcurrent库在这里提供了很好的支持,这意味着你不必自己搞砸线程。 (您将需要使用QGLWidget来绘图:: makeCurrent虽然)

使用CPU上的所有可用的内核,当你可以:

  • 考虑使用多个线程数据上传到OpenGL的。使用像素缓冲区对象,您可以获取指向纹理数据缓冲区的指针,然后使用memcpy上传它。 (memcpy线程不需要激活上下文。)。
  • 纹理压缩是在GL驱动程序中的软件中完成的,因此跨核心并行上传也会有所帮助,但您可能必须创建多个GL上下文(即共享数据)才能使GL驱动程序压缩parallell。在尝试此操作之前,应该不难看出它是否平行。

而且,通过缓冲API避免流数据:■当你不需要:

  • 通过记忆非常有效地映射数据上传可以做的文件(无缓冲,直接从磁盘到GL),只是从映射缓冲区到纹理指针的一个memcpy。
1

如果您确定瓶颈是在这段代码中,有几件事情可以做:

  • 不使用GL_COMPRESSED_RGBA,而只是GL_RGBA
  • 发现司机的最佳类型,并使用该(您需要配置文件OpenGL程序)的PNG文件(压缩避免)
  • 分割文件成更小的文件
  • 使用原始数据
+0

加载的图像是在GLformat,我认为它不能比任何更好。 – RobotRock

+0

将在多个上下文中分割纹理的加载有帮助吗? – RobotRock

+0

@RobotRock GL_UNSIGNED_BYTE'可能不是您的图形芯片的最佳类型。你可以玩其他类型的游戏。你在不同的环境下意味着什么?您只能在创建它的上下文中使用纹理 –