正如上面所说:我如何使用绑定到 Haskell的SDL-image的图像加载工具来加载OpenGL纹理,就像您在 C 中经常做的那样。SDL-image 支持多种图像格式,但只提供一个Surface
数据类型。对于glTexImage2D
,看来,我需要提供一些不同的东西,一种PixelData
数据类型。
有什么方法可以在不求助于 C 的情况下获取图像数据?我什至会使用其他一些库,只要它能给我 PNG、JPG 和 TGA 支持。
正如上面所说:我如何使用绑定到 Haskell的SDL-image的图像加载工具来加载OpenGL纹理,就像您在 C 中经常做的那样。SDL-image 支持多种图像格式,但只提供一个Surface
数据类型。对于glTexImage2D
,看来,我需要提供一些不同的东西,一种PixelData
数据类型。
有什么方法可以在不求助于 C 的情况下获取图像数据?我什至会使用其他一些库,只要它能给我 PNG、JPG 和 TGA 支持。
要使其与 SDL 表面和 Haskell 绑定一起使用,请使用surfaceGetPixels
它返回Pixels
,它是类型别名,Ptr PixelData
并且PixelData
是一个空数据声明。之所以会这样,是因为 SDL 表面像素格式和每个像素的位数几乎可以是任何东西。所以基本上,如果你有 32bpp 格式,你会将指针转换为Ptr Word32
using castPtr
.
这是获取/放置像素的示例:
getPixel32 :: MonadIO m => Surface -> Int -> Int -> m Pixel
getPixel32 s x y = liftIO $ do
ps <- surfaceGetPixels s
assert (x >= 0 && x < surfaceGetWidth s && y >= 0 && y < surfaceGetHeight s) $
Pixel `liftM` peekElemOff (castPtr ps :: Ptr Word32) offset
where offset = y * (fromIntegral $ surfaceGetPitch s `div` 4) + x
setPixel32 :: MonadIO m => Surface -> Int -> Int -> Pixel -> m ()
setPixel32 s x y (Pixel pixel) = liftIO $ do
ps <- surfaceGetPixels s
assert (x >= 0 && x < surfaceGetWidth s && y >= 0 && y < surfaceGetHeight s) $
pokeElemOff (castPtr ps :: Ptr Word32) offset pixel
where offset = y * (fromIntegral $ surfaceGetPitch s `div` 4) + x
因此,类似地,您可以将指针转换为特定的指针类型并将其提供给 glTexImage2D 以上传纹理。
也许Codec.Image.DevIL提供了您正在寻找的东西?我相信无论如何都应该。