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
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))
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 ((<$>))
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
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.
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.
精彩评论