简体   繁体   English

将图像加载到OpenGL纹理QT C ++

[英]Loading image to opengl texture qt c++

I'm using opengl calls on Qt with c++, in order to display images to the screen. 我正在Qt和c ++上使用opengl调用,以便将图像显示到屏幕上。 In order to get the image to the texture, I first read it as a QImage, and then use the following code to load to texture: 为了使图像具有纹理,我首先将其读取为QImage,然后使用以下代码加载到纹理:

void imageDisplay::loadImage(const QImage &img){
    glEnable(GL_TEXTURE_2D); // Enable texturing
    glBindTexture(GL_TEXTURE_2D, texture); // Set as the current texture
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, img.width(),
                  img.height(),
                  0, GL_BGRA,      GL_UNSIGNED_BYTE, img.bits() );
    glFinish();
    glDisable(GL_TEXTURE_2D);
}

However, when profiling performance, I suspect this is not the most efficient way of doing this. 但是,在分析性能时,我怀疑这不是实现此目的的最有效方法。 Performance is critical for the application that I am developing, and I would really appreciate any suggestions on how to improve this part. 对于我正在开发的应用程序,性能至关重要。对于如何改进此部分,我将不胜感激。 (BTW - reading the image is done on a separate module than the one that is displaying it - is it possible to read and load to a texture, and then move the texture the displaying object?) (顺便说一句-读取图像是在与显示图像的模块不同的模块上进行的-是否可以读取并加载到纹理,然后将纹理移动到显示对象上?)

Thank you 谢谢

消除问题,当您根本不需要它时,它会严重降低性能。

It's hard to say without looking at your profiling results, but a few things to try: 如果不查看分析结果,很难说,但是要尝试一些方法:

  1. You are sending your data via glTexImage2D() in GL_BGRA format and having the driver reformat. 您正在通过glTexImage2D()以GL_BGRA格式发送数据,并重新设置了驱动程序格式。 Does it work any faster when you pre-format the bits?: (would be surprising, but you never know what drivers do under the hood.) 在对位进行预格式化时,它的工作速度更快吗?:(令人惊讶,但您永远不知道驱动程序在做什么。)

    QImage imageUpload = imageOriginal.convertToFormat( QImage::Format_ARGB32 ).rgbSwapped(); QImage imageUpload = imageOriginal.convertToFormat(QImage :: Format_ARGB32).rgbSwapped(); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.bits() ); glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,image.width(),image.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,image.bits());

  2. Are you populating that QImage from a file on disk? 您是从磁盘上的文件填充该QImage吗? How big is it? 它有多大? If the sheer volume of image data is the problem, and it's a static texture, you can try compressing the image to a DXT/St3 format offline and saving that for later. 如果大量的图像数据是问题所在,并且是静态纹理,则可以尝试将图像离线压缩为DXT / St3格式,并保存以备后用。 Then read and upload those bits at runtime instead. 然后改为在运行时读取并上传这些位。 This will reduce the number of bytes being transferred to the GPU (and stored on GPU memory) to 1/6 or 1/4 the original. 这会将传输到GPU(并存储在GPU内存中)的字节数减少到原始字节的1/6或1/4。 If you need to generate the QImage at runtime and can't precompress, then this will probably slow things down, so keep that in mind. 如果您需要在运行时生成QImage并且无法进行预压缩,则可能会减慢速度,因此请记住这一点。

  3. Is the alpha combine important? alpha合并重要吗? ie if you remove glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 即如果您删除glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE); does it help? 有帮助吗? I wonder if that's causing some unwanted churn. 我不知道这是否会引起不必要的流失。 Ie it to be downloaded to host, modified, then sent back or something... 即它可以下载到主机,进行修改,然后发送回去……

  4. I agree that you should remove the glFinish(); 我同意您应该删除glFinish(); unless you have a VERY specific reason for it. 除非您有非常特定的原因。

  5. How often are you needing to do this? 您需要多久执行一次此操作? every frame? 每帧?

What about STB image loader: its raw pixel data in a buffer, it returns a char pointer to a byte buffer which you can use and release after its loaded in OpenGL. 关于STB图像加载器呢:它的原始像素数据在缓冲区中,它返回一个char指针指向 字节缓冲区 ,您可以在将其加载到OpenGL后使用并释放它。

int width, height comp;
unsigned char *data = stbi_load(filename, &width, &height, &comp, 4); // ask it to load 4 components since its rgba  // demo only

    glGenBuffers(1, &m_vbo);
    glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
    glBufferData(GL_ARRAY_BUFFER, vertexByteSize), this->Vertices, GL_STATIC_DRAW);
    glGenTexture(...)
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D( ... );

    // you can generate mipmaps here

    // Important
    stbi_image_free(data);

You can find STB here: get the image load header: https://github.com/nothings/stb 您可以在此处找到STB:获取图像加载标头: https//github.com/nothings/stb

Drawing with mipmaps using openGL improves performance. 使用openGL使用mipmap进行绘制可以提高性能。 generate mipmaps after you have used glTexImage2D 使用glTexImage2D后生成Mipmap

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glGenerateMipmap(GL_TEXTURE_2D);

Good luck 祝好运

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM