使用 SDL 图像加载 OpenGL 图像

发布于 2024-10-26 12:26:36 字数 743 浏览 5 评论 0原文

如上所述:如何使用 SDL-image 的图像加载工具绑定到 Haskell 以加载 OpenGL 纹理,就像您在 C 中经常做的那样。SDL-image 支持多种图像格式,但仅提供 Surface 数据类型。对于 glTexImage2D,看来,我需要提供一些不同的东西,一个PixelData 数据类型。

有什么方法可以不借助C 来获取图像数据吗?我什至会使用其他库,只要它支持 PNG、JPG 和 TGA。

As it says above: How can I employ the image loading facilities of the SDL-image binding to Haskell to load a OpenGL texture, as you so often do in C. SDL-image supports a nice variety of image formats, but only delivers a Surface data type. For glTexImage2D, it seems, I need to provide something different, a PixelData data type.

Any way to get the image data without resorting to C? I would even employ some other library, as long as it gives me PNG, JPG and TGA support.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

请远离我 2024-11-02 12:26:36

为了使这项工作与 SDL 表面和Haskell 绑定使用 surfaceGetPixels 它返回 Pixels,它是 Ptr PixelData 的类型别名,而 PixelData 是一个空数据声明。之所以会这样,是因为SDL表面像素格式&每个像素的位数几乎可以是任何值。所以基本上,如果你有 32bpp 格式,你可以使用 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 来上传纹理。

To make this work with SDL surfaces & Haskell bindings use surfaceGetPixels it returns Pixels which is a type alias for Ptr PixelData and PixelData is an empty data declaration. The reason why this is, is because SDL surface pixel format & number of bits per pixel could be almost anything. So basically if you have 32bpp format you would cast the pointer to say Ptr Word32 using castPtr.

Here is an example of getting/putting a pixel:

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

So similarly you can cast the pointer to a particular pointer type and give that to glTexImage2D to upload the texture.

ヤ经典坏疍 2024-11-02 12:26:36

也许编解码器。 Image.DevIL 提供了您正在寻找的内容?我相信无论如何应该

Perhaps Codec.Image.DevIL provides what you're looking for? I believe it should anyway.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文