2010-07-20 1 views
6

Unten finden Sie einen Code, um SDL mit Haskell zu verwenden, um eine diagonale Linie zu zeichnen. Ich bekomme eine CYAN-Zeile, wenn das RGB eindeutig weiß sein sollte. Dies ist auf Ubuntu. Mache ich etwas falsch?Warum ist diese Haskell SDL Linie Cyan, wenn sie weiß sein sollte?

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 
+1

Ist es immer noch mit einer vertikalen Linie passieren, und mit dem ganzen Bildschirm zu malen? Nur ein Plausibilitätscheck, um sicherzustellen, dass kein verrücktes Anti-Aliasing stattfindet oder so. – luqui

+0

ist das kein Problem mit Big-Little-Endian? Sie legen den Alphakanal nicht so fest 255 255 255 0 wird 0 255 255 255 (wenn Sie die Byte-Reihenfolge umkehren)? – mb14

+0

mb14: NEIN. Die Verwendung von mapRGB und die Verwendung von 255 255 255 255 macht dasselbe. – qrest

Antwort

1

ich das gleiche Problem auf meinem System bekommen (für beide Linien und andere Primitiven) und mit dem Pixel Konstruktor direkt statt mapRGB scheint die richtigen Farben zu geben. Wenn ich zB Graphics.UI.SDL.Color als SDLC und dann let white' = SDLC.Pixel maxBound importiere, bekomme ich wie erwartet eine weiße Linie. Mit SDLC.Pixel 4278190335 (oder 255 * 2^24 + 255, ein sinnvoller Wert für rot), bekomme ich eine rote Linie.

Dies ist eindeutig keine echte Lösung oder Antwort, aber es könnte einige Ansatzpunkte vorschlagen.

Eine andere seltsame Sache: wenn ich drucken sowohl Ihre weißen und Mine in etwa so:

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

ich dieses:

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

So sehen sie die gleiche über getRGBA, aber die tatsächliche Pixel Werte sind unterschiedlich.

2

Ich beobachte den gleichen Effekt auf Lucid mit ATI HD2400 und Radeon-Treiber (wenn das wichtig ist). Aber es gibt einen Workaround.

Dieses Beispiel zieht eine weiße Linie:

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 

Ich akzeptiere, dass dies eine hässliche Hack ist, aber es scheint, dass Standard-Oberfläche‘Pixelformat ist nicht RGB und ein Pixelformat eines mit (?) Oberfläche, die als RGB bekannt ist, hilft. Ich habe keine Erfahrung mit SDL, daher kann ich nicht sagen, wie der richtige Weg dafür ist.

3

Vielleicht ein kleiner schmutziger Hack (wenn auch wahrscheinlich Plattform/Umsetzung abhängig):

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