2

我正在将图像加载到 OpenGL 应用程序中。通常我使用线性过滤,但现在测试最近我发现生成的图像比原始图像要暗得多。顺便说一句,在我看来,线性过滤也会导致一些亮度松动。这里是例子:

线性过滤: 线性过滤

最近过滤: 最近过滤

原图: 原始图像

现在,我正在设置 mipmap 级别(到 4 )。我发现当不使用 mipmap 时,原始亮度是完整的。可能是什么问题?它与伽玛校正有关吗?

这是图像加载和mipmap生成的代码:

                    ILinfo imageInfo;

        iluGetImageInfo(&imageInfo);
        iluFlipImage();

        if (imageInfo.Format == IL_RGB)
        {
            ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE);
        }
        else if (imageInfo.Format == IL_RGBA)
        {
            ilConvertImage(IL_BGRA, IL_UNSIGNED_BYTE);

        }

        iluGetImageInfo(&imageInfo);

        glPixelStorei(GL_PACK_ALIGNMENT, 1);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

        glGenTextures(1, &textureName);
        glBindTexture(GL_TEXTURE_2D, textureName);

        glTexStorage2D(GL_TEXTURE_2D,numMipMapLevels,GL_RGBA8,imageInfo.Width,imageInfo.Height);
        glTexSubImage2D(GL_TEXTURE_2D,0,0,0,imageInfo.Width,imageInfo.Height,GL_BGRA,GL_UNSIGNED_BYTE,imageInfo.Data);

        /* ==================================== */
        // Trilinear filtering by default

        if(smooth){
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glGenerateMipmap(GL_TEXTURE_2D);
        }else{
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        }

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

我还在自定义 FBO 中运行 MSAA 通行证,但它看起来与问题无关,因为我也在关闭 MSAA 的情况下进行了测试,并且同样的问题仍然存在。

4

1 回答 1

4

从您的代码看来,您创建了一个 mipmap 纹理(如您所说,具有 4 个 mipmap 级别),但随后只为第一级设置图像。这意味着所有其他级别的图像都是未定义的。然后使用GL_NEAREST_MIPMAP_LINEAR时,它将访问最适合像素纹理比率(MIPMAP_LINEAR-part)的两个 mipmap 级别,然后从每个级别(-part)中选择一个最近的纹理像素NEAREST并对其进行插值。

从您的图像来看,未指定的 mipmap 级别看起来只是黑色,因此您可以在纹理颜色和黑色之间进行插值,因此纹理变暗(好吧,它们实际上可以包含任何东西,并且纹理甚至不应该工作,因为纹理是不完整,但可能不可变存储在这方面表现不同)。当不使用 mipmap 时(因此仅使用 创建单个级别glTexStorage),过滤中只会使用一个级别(即使使用 mipmaped 过滤器),这当然具有有效的图像。

如果您打算使用某种 mipmap,那么您应该为每个 mipmap 级别实际设置纹理图像(或设置顶级图像并在glGenerateMipmap之后进行调用)。如果您只想使用真正的最近邻过滤,那么只需使用GL_NEAREST(我实际上从未见过所有其他 mipmap 过滤器的实际用途,除了真正的三线性过滤器GL_LINEAR_MIPMAP_LINEAR)。

于 2013-06-13T08:19:07.533 回答