为什么 Haskell SDL 线应该是白色的却是青色的?

发布于 2024-09-10 17:04:12 字数 673 浏览 4 评论 0原文

下面是一些使用 SDL 和 Haskell 来绘制对角线的代码。当 RGB 显然应该是白色时,我得到一条青色线。这是在 Ubuntu 上。我做错了什么吗?

import qualified Graphics.UI.SDL as SDL
import qualified Graphics.UI.SDL.Primitives as SDLP

main = do
    SDL.init [SDL.InitEverything]
    SDL.setVideoMode 640 480 32 []
    SDL.setCaption "My Window" "My Test"
    surf0 <- SDL.getVideoSurface
    white <- SDL.mapRGB (SDL.surfaceGetPixelFormat surf0) 255 255 255
    SDLP.line surf0 0 0 640 480 white 
    SDL.flip surf0
    eventLoop
    SDL.quit
    print "done"
    where
    eventLoop = SDL.waitEventBlocking >>= checkEvent
    checkEvent (SDL.KeyUp _) = return ()
    checkEvent _ = eventLoop

Below is some code to use SDL with Haskell to draw a diagonal line. I get a CYAN line when the RGB clearly should be white. This is on Ubuntu. Am I doing something wrong?

import qualified Graphics.UI.SDL as SDL
import qualified Graphics.UI.SDL.Primitives as SDLP

main = do
    SDL.init [SDL.InitEverything]
    SDL.setVideoMode 640 480 32 []
    SDL.setCaption "My Window" "My Test"
    surf0 <- SDL.getVideoSurface
    white <- SDL.mapRGB (SDL.surfaceGetPixelFormat surf0) 255 255 255
    SDLP.line surf0 0 0 640 480 white 
    SDL.flip surf0
    eventLoop
    SDL.quit
    print "done"
    where
    eventLoop = SDL.waitEventBlocking >>= checkEvent
    checkEvent (SDL.KeyUp _) = return ()
    checkEvent _ = eventLoop

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

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

发布评论

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

评论(3

多情出卖 2024-09-17 17:04:12

也许是一个不太肮脏的黑客(尽管可能取决于平台/实现):

import GHC.Word
import Data.Bits

fi a = fromIntegral a

rgbColor::Word8→ Word8→ Word8→ Pixel
rgbColor r g b = Pixel (shiftL (fi r) 24 .|. shiftL (fi g) 16 .|. shiftL (fi b) 8 .|. (fi 255))

Maybe a less dirty hack (though probably platform/implementation dependant) :

import GHC.Word
import Data.Bits

fi a = fromIntegral a

rgbColor::Word8→ Word8→ Word8→ Pixel
rgbColor r g b = Pixel (shiftL (fi r) 24 .|. shiftL (fi g) 16 .|. shiftL (fi b) 8 .|. (fi 255))
甜点 2024-09-17 17:04:12

我在使用 ATI HD2400 和 radeon 驱动程序的 Lucid 上观察到相同的效果(如果这很重要的话)。但有一个解决方法。

这个例子画了一条白线:

import qualified Graphics.UI.SDL as SDL
import qualified Graphics.UI.SDL.Primitives as SDLP

import Control.Applicative ((<
gt;))

main = do
    SDL.init [SDL.InitEverything]
    sbase <- SDL.setVideoMode 640 480 24 []  -- draw here
    -- an ugly hack to get pixel format from an RGB surface:
    rgbPF <- SDL.surfaceGetPixelFormat <
gt; SDL.createRGBSurfaceEndian [] 1 1 24
    white <- SDL.mapRGB rgbPF (-1) (-1) (-1)
    SDLP.line sbase 0 0 (640-1) (480-1) white
    SDL.flip sbase
    eventLoop
    SDL.quit
  where
    eventLoop = SDL.waitEventBlocking >>= checkEvent
    checkEvent (SDL.KeyDown _) = return ()
    checkEvent _ = eventLoop

我承认这是一个丑陋的黑客,但似乎默认表面的像素格式不是RGB(?),并且使用已知为RGB的表面的像素格式会有所帮助。我没有使用 SDL 的经验,所以我无法判断正确的使用方法是什么。

I observe the same effect on Lucid with ATI HD2400 and radeon driver (if that matters). But there is a workaround.

This example draws a white line:

import qualified Graphics.UI.SDL as SDL
import qualified Graphics.UI.SDL.Primitives as SDLP

import Control.Applicative ((<
gt;))

main = do
    SDL.init [SDL.InitEverything]
    sbase <- SDL.setVideoMode 640 480 24 []  -- draw here
    -- an ugly hack to get pixel format from an RGB surface:
    rgbPF <- SDL.surfaceGetPixelFormat <
gt; SDL.createRGBSurfaceEndian [] 1 1 24
    white <- SDL.mapRGB rgbPF (-1) (-1) (-1)
    SDLP.line sbase 0 0 (640-1) (480-1) white
    SDL.flip sbase
    eventLoop
    SDL.quit
  where
    eventLoop = SDL.waitEventBlocking >>= checkEvent
    checkEvent (SDL.KeyDown _) = return ()
    checkEvent _ = eventLoop

I accept that this is an ugly hack, but it seems that default surface' pixel format is not RGB (?), and using a pixel format of a surface known to be RGB helps. I don't have experience with SDL, so I cannot tell what the right way to use it is.

沩ん囻菔务 2024-09-17 17:04:12

我在我的系统上遇到了同样的问题(对于线条和其他基元),并且直接使用 Pixel 构造函数而不是 mapRGB 似乎给出了正确的颜色。

例如,如果我将 Graphics.UI.SDL.Color 导入为 SDLC,然后 letwhite' = SDLC.Pixel maxBound,我会得到白线,正如预期的那样。使用 SDLC.Pixel 4278190335 (或 255 * 2^24 + 255,一个合理的红色值),我得到一条红线。

这显然不是真正的解决方案或答案,但它可能会建议一些起点。

另一件奇怪的事情是:如果我像这样打印你的白色和我的白色:

print =<< SDL.getRGBA white (SDL.surfaceGetPixelFormat surf0)
print =<< SDL.getRGBA white' (SDL.surfaceGetPixelFormat surf0)
print white
print white'

我得到这个:

(255,255,255,255)
(255,255,255,255)
Pixel 16777215
Pixel 4294967295

所以它们通过 getRGBA 看起来相同,但实际的 Pixel 值不同。

I get the same issue on my system (for both lines and other primitives), and using the Pixel constructor directly instead of mapRGB seems to give the correct colors.

For example, if I import Graphics.UI.SDL.Color as SDLC and then let white' = SDLC.Pixel maxBound, I get a white line, as expected. With SDLC.Pixel 4278190335 (or 255 * 2^24 + 255, a sensible value for red), I get a red line.

This clearly isn't a real solution or answer, but it might suggest some starting points.

One other odd thing: if I print both your white and mine like so:

print =<< SDL.getRGBA white (SDL.surfaceGetPixelFormat surf0)
print =<< SDL.getRGBA white' (SDL.surfaceGetPixelFormat surf0)
print white
print white'

I get this:

(255,255,255,255)
(255,255,255,255)
Pixel 16777215
Pixel 4294967295

So they look the same via getRGBA, but the actual Pixel values are different.

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