Qt 5 带有 QOpenGLTexture 和 16 位整数图像

Qt 5 with QOpenGLTexture and 16 bits integers images

本文关键字:整数 图像 带有 QOpenGLTexture Qt      更新时间:2023-10-16

一段时间以来,我一直在使用 QOpenGLTexture 在纹理中使用 32 位浮点精度的 RGB 图像。我没有遇到任何问题。最初这些图像具有无符号的短数据类型,我想保留此数据类型以将数据发送到 openGL(顺便说一句,它实际上可以节省一些内存来做到这一点吗? 经过多次尝试,我无法让QOpenGLTexture显示图像。我最终得到的只是一个黑色的图像。以下是我如何设置QOpenGLTexture。使用浮点数且到目前为止有效的部分被注释掉。假设图像为 16 位无符号整数的部分位于后者的正下方,未注释。我正在使用OpenGL 3.3,GLSL 330,核心配置文件,在带有Iris图形的Macbook pro视网膜上。

QOpenGLTexture *oglt = new QOpenGLTexture(QOpenGLTexture::Target2D);
    oglt->setMinificationFilter(QOpenGLTexture::NearestMipMapNearest);
    oglt->setMagnificationFilter(QOpenGLTexture::NearestMipMapNearest);
    //oglt->setFormat(QOpenGLTexture::RGB32F); // works
    oglt->setFormat(QOpenGLTexture::RGB16U);  
    oglt->setSize(naxis1, naxis2);
    oglt->setMipLevels(10);
    //oglt->allocateStorage(QOpenGLTexture::RGB, QOpenGLTexture::Float32); // works
    //oglt->setData(QOpenGLTexture::RGB, QOpenGLTexture::Float32, tempImageRGB.data); // works
    oglt->allocateStorage(QOpenGLTexture::RGB_Integer, QOpenGLTexture::UInt16);
    oglt->setData(QOpenGLTexture::RGB_Integer, QOpenGLTexture::UInt16, tempImageRGB.data);

那么,在上面的这些行中,有什么问题吗?当我使用 UInt16 时,我在tempImageRGB.data中的数据介于 [0-65535] 之间。当我使用 QOpenGLTexture::Float32 时,tempImageRGB.data 中的值已经规范化,因此它们将在 [0-1] 内。

然后,这是我的片段着色器:

#version 330 core
in mediump vec2 TexCoord;
out vec4 color;
uniform mediump sampler2D ourTexture; 

    void main()
    {
        mediump vec3 textureColor = texture(ourTexture, TexCoord).rgb; 
        color = vec4(textureColor, 1.0);
    }

我错过了什么?

似乎我通过简单地不使用放大滤镜NearestMipMapNearest来解决问题。如果我只将其用于缩小,事情就会起作用。虽然总的来说这是有道理的,但我不明白为什么在浮点情况下使用 NearestMipMapNearest 进行放大和缩小时没有问题。

因此,代码的工作原理是简单地将着色器中的"sampler2D"更改为"usampler2D",通过将"setMagnificationFilter(QOpenGLTexture::NearestMipMapNearest)"更改为"setMagnificationFilter(QOpenGLTexture::Nearest)"。缩小过滤器不需要更改。此外,尽管它可以与和不使用一起使用,但我不需要显式设置 MipMapLevels,因此我可以删除oglt->setMipLevels(10)

需要明确的是,这是更正后的代码:

QOpenGLTexture *oglt = new QOpenGLTexture(QOpenGLTexture::Target2D);
oglt->setMinificationFilter(QOpenGLTexture::NearestMipMapNearest);
oglt->setMagnificationFilter(QOpenGLTexture::Nearest);
//oglt->setFormat(QOpenGLTexture::RGB32F); // works
oglt->setFormat(QOpenGLTexture::RGB16U); // now works with integer images (unsigned)
oglt->setSize(naxis1, naxis2);
//oglt->allocateStorage(QOpenGLTexture::RGB, QOpenGLTexture::Float32); // works
//oglt->setData(QOpenGLTexture::RGB, QOpenGLTexture::Float32, tempImageRGB.data); // works
oglt->allocateStorage(QOpenGLTexture::RGB_Integer, QOpenGLTexture::UInt16); // now works with integer images (unsigned)
oglt->setData(QOpenGLTexture::RGB_Integer, QOpenGLTexture::UInt16, tempImageRGB.data); // now works with integer images (unsigned)

片段着色器变得简单:

#version 330 core
in mediump vec2 TexCoord;
out vec4 color;
uniform mediump usampler2D ourTexture; 
    void main()
    {
        mediump vec3 textureColor = texture(ourTexture, TexCoord).rgb; 
        color = vec4(textureColor, 1.0);
    }