2010-07-20 7 views
6

Poniżej znajduje się kod do używania SDL z Haskellem do narysowania ukośnej linii. Dostaję linię CYAN, kiedy RGB wyraźnie powinno być białe. To jest na Ubuntu. czy robię coś źle?Dlaczego ta linia Haskell SDL jest niebieskozielona, ​​gdy powinna być biała?

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

Czy to jeszcze zdarzyć z pionową linią, a wraz z malowaniem cały ekran? Tylko sprawdzanie poczytalności, aby upewnić się, że szalone anty-aliasing nie dzieje się, czy coś. – luqui

+0

czy to nie problem z dużymi małymi endianami? Nie ustawiasz kanału alfa, aby 255 255 255 0 stało się 0 255 255 255 (jeśli odwrócisz kolejność bajtów)? – mb14

+0

mb14: NIE. Używanie mapRGB i użycie 255 255 255 255 robi to samo. – qrest

Odpowiedz

1

mam ten sam problem w moim systemie (na obu liniach i innych prymitywów), a przy użyciu konstruktora Pixel bezpośrednio zamiast mapRGB wydaje się dawać odpowiednie kolory.

Na przykład, jeśli zaimportuję Graphics.UI.SDL.Color jako SDLC, a następnie let white' = SDLC.Pixel maxBound, otrzymam białą linię zgodnie z oczekiwaniami. Z SDLC.Pixel 4278190335 (lub 255 * 2^24 + 255, rozsądna wartość dla czerwonego), otrzymuję czerwoną linię.

To zdecydowanie nie jest prawdziwe rozwiązanie lub odpowiedź, ale może sugerować kilka punktów początkowych.

Inną dziwną rzeczą: jeśli drukować zarówno swoją białe i kopalni tak:

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

uzyskać to:

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

Tak wyglądają tak samo poprzez getRGBA, ale rzeczywista Pixel wartości są różne.

2

Obserwuję ten sam efekt na Lucid za pomocą ATI HD2400 i sterownika radeon (jeśli to ma znaczenie). Ale istnieje obejście.

Ten przykład rysuje białą linię:

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 

Zgadzam się, że jest to brzydki hack, ale wydaje się, że domyślne powierzchnia”format pikseli nie jest RGB, a przy użyciu formatu piksela (?) powierzchnia, o której wiadomo, że RGB pomaga. Nie mam doświadczenia z SDL, więc nie mogę powiedzieć, jaki jest właściwy sposób korzystania z niego.

3

Może mniej brudny Hack (choć prawdopodobnie platforma/zależna od implementacji):

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)) 
Powiązane problemy