2010-07-20 15 views
6

A continuación se muestra un código para usar SDL con Haskell para dibujar una línea diagonal. Obtengo una línea CYAN cuando el RGB claramente debe ser blanco. Esto está en Ubuntu. ¿Estoy haciendo algo mal?¿Por qué esta línea Haskell SDL es cian cuando debería ser blanca?

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

¿Todavía suceda con una línea vertical, y con la pintura de toda la pantalla? Solo un control de cordura para asegurarse de que no se está produciendo un anti-aliasing loco o algo así. – luqui

+0

¿no es eso un problema con Big-little Endian? No configura el canal alfa, por lo que 255 255 255 0 se convierte en 0 255 255 255 (si invierte el orden de bytes)? – mb14

+0

mb14: NO. Usar mapRGB y usar 255 255 255 255 hace lo mismo. – qrest

Respuesta

1

me sale el mismo problema en mi sistema (para ambas líneas y otras primitivas), y utilizando el constructor Pixel directamente en lugar de mapRGB parece dar los colores correctos.

Por ejemplo, si importo Graphics.UI.SDL.Color como SDLC y luego let white' = SDLC.Pixel maxBound, obtengo una línea blanca, como era de esperar. Con SDLC.Pixel 4278190335 (o 255 * 2^24 + 255, un valor razonable para el rojo), obtengo una línea roja.

Esto claramente no es una solución o respuesta real, pero podría sugerir algunos puntos de partida.

Otra cosa extraña: si puedo imprimir tanto el blanco y el mío, así:

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

me sale esto:

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

para que luzcan el mismo a través de getRGBA, pero el real Pixel los valores son diferentes

2

Observo el mismo efecto en Lucid con ATI HD2400 y el controlador de radeon (si eso importa). Pero hay una solución.

Este ejemplo dibuja una línea blanca:

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 

acepto que este es un truco feo, pero parece que' formato de píxel de superficie por defecto no es RGB, y usando un formato de píxel de un (?) superficie conocida por ser RGB ayuda. No tengo experiencia con SDL, así que no puedo decir cuál es la forma correcta de usarlo.

3

Tal vez un corte menos sucia (aunque probablemente la plataforma/dependiente de la implementación):

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