为什么这个Haskell SDL线应该是白色的?

时间:2010-07-20 03:44:15

标签: haskell sdl

下面是一些使用SDL和Haskell绘制对角线的代码。当RGB显然应该是白色时,我得到一条CYAN线。这是在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

3 个答案:

答案 0 :(得分:3)

可能是一个不那么脏的黑客(尽管可能依赖于平台/实现):

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))

答案 1 :(得分:2)

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

此示例绘制一条白线:

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

import Control.Applicative ((<$>))

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 <$> 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的经验,所以我不知道使用它的正确方法是什么。

答案 2 :(得分:1)

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

例如,如果我将Graphics.UI.SDL.Color导入SDLC然后导入let white' = 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值不同。