【问题标题】:OpenGL texture contains bad data - what's going on?OpenGL 纹理包含错误数据 - 这是怎么回事?
【发布时间】:2015-02-06 15:41:25
【问题描述】:

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

我创建了一个窗口和 GL 4.4 Core Forward-Compatible 上下文:

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

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.

【问题讨论】:

  • 致以“没有明确的问题陈述/缺少代码”的方式关闭它的人 - 代码链接为 Gist,因为 Q 已经太长了,并且 gist 中的部分与手头的问题;它们只是为了方便而呈现。至于声明,我认为很明显我没有加载只有青色的PNG,呵呵。
  • 从什么时候开始,N/A 在常规 2D 纹理上是 GL_TEXTURE_MIN_FILTER 的合理值?你确定这不仅仅是 gDEBugger 愚蠢吗?或者它把N/A放在那里是因为你的缩小过滤器包括mipmapping,但是你的纹理LOD数量是错误的?
  • 你试过查看 glGetError 的输出吗?
  • @Mokosha 我总是将 gDebugger 设置为中断错误。

标签: opengl haskell juicy-pixels


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    将功能强大的 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);
    

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

    【讨论】:

    • 好吧。默认过滤器定义明确。它是用于缩小的 mipmapping,使纹理不是 mipmapping-complete。但是,纹理对象本身是有效的,可以读回,或使用texelFetch 访问。该 gdebugger 输出完全具有误导性,因为没有办法在那里获得一些 N/A 状态。我并不是说设置这些过滤器是一个坏主意,但这并不能解决这里的问题。
    • @derhass 嗯,你是对的。见编辑;我已经阐明了我的意图。
    • 正如预期的那样,添加正确的过滤器设置并没有改变 gDebugger 的输出。
    猜你喜欢
    • 2014-06-13
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 2014-04-06
    相关资源
    最近更新 更多