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)。
是什么导致了这种行为?
将功能强大的 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 中的错误。经过一些操作并实际绘制纹理后,我已验证它确实包含正确的数据。
我正在尝试将图像加载到 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)。
是什么导致了这种行为?
将功能强大的 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 中的错误。经过一些操作并实际绘制纹理后,我已验证它确实包含正确的数据。