OpenGL 纹理包含错误数据 - 发生了什么事?

OpenGL texture contains bad data - what's going on?

我正在尝试将图像加载到 OpenGL 纹理中。

我创建了一个 window 和 GL 4.4 核心向前兼容的上下文:

这是我用来加载图像和创建纹理的代码:

load :: IO ()
load = do
    image <- JP.readImage "image.png"
    case image of
        (Left err) -> do print err
                         exitWith (ExitFailure 1)
        (Right imgData) -> do 
            a <- malloc
            glGenTextures 1 a
            texId <- peek a
            free a
            loadImgIntoTexture texId imgData

loadImgIntoTexture texId (JP.ImageRGBA8 (JP.Image width height dat)) = do
    glBindTexture GL_TEXTURE_2D texId
    unsafeWith dat $ glTexImage2D GL_TEXTURE_2D 0 GL_RGBA (fromIntegral width) (fromIntegral height) 0 GL_RGBA GL_UNSIGNED_BYTE . castPtr
    --p <- mallocBytes $ (fromIntegral width) * (fromIntegral height) * 4
    --glTexImage2D GL_TEXTURE_2D 0 GL_RGBA (fromIntegral width) (fromIntegral height) 0 GL_RGBA GL_UNSIGNED_BYTE (castPtr p)
    print "everything ok"

注释掉的行是另一种尝试将任何有意义的东西放入该纹理中。

这是 gDebugger 报告的纹理信息:

下面是它显示的纹理内容:

当我打印出 JuicyPixels 返回的结构时,它打印出不同的字节序列,这些字节序列肯定不会生成平面图像。

在这个例子中,我没有渲染纹理,而是使用由 gl 包生成的原始绑定。使用 OpenGL 包时,我有完全相同的行为(具有相同的蓝绿色)。毫不奇怪,它在屏幕上呈现为平面矩形。

我尝试了不同的图像,大小为 128x128 和 NPOT(屏幕截图中为 100x100)。

是什么导致了这种行为?

Full source.

将功能强大的 Haskell 与混乱状态的典型代表 OpenGL 相结合,充其量是令人沮丧的,因此我承认我对这个确切的场景有点不知所措。

然而,众所周知,如果没有与数据匹配的缩小过滤器和放大过滤器,OpenGL 纹理是不完整的(参见 here)。我在代码中没有看到这样的,所以你的纹理不完整。在 C 中,您可以添加如下内容:

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

正如评论中所指出的,这可能不应该导致 gDEBugger 提供虚假输出;浏览文档,我没有看到任何需要完整纹理才能读取的内容(并且 gDEBugger 无论如何都是通过拦截 GL 调用来工作的)。尽管如此,从采样过滤器不匹配的纹理中读取对我来说还是不对的;如果这是一个边缘案例,我不会感到惊讶。

这很可能是 gDEBugger 中的错误。经过一些操作并实际绘制纹理后,我已验证它确实包含正确的数据。