2010-07-20 22 views
6

Dưới đây là một số mã để sử dụng SDL với Haskell để vẽ một đường chéo. Tôi nhận được một dòng CYAN khi RGB rõ ràng nên có màu trắng. Đây là trên Ubuntu. Tôi có làm điều gì sai?Tại sao dòng Haskell SDL màu lục lam này lại có màu trắng?

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

Liệu nó vẫn xảy ra với một đường thẳng đứng, và với sơn toàn bộ màn hình? Chỉ cần kiểm tra sanity để chắc chắn rằng một số anti-aliasing điên không xảy ra hay gì đó. – luqui

+0

là không phải là một vấn đề với endian lớn nhỏ? Bạn không đặt kênh alpha để 255 255 255 0 trở thành 0 255 255 255 (nếu bạn đảo ngược thứ tự byte)? – mb14

+0

mb14: KHÔNG. Sử dụng mapRGB và sử dụng 255 255 255 255 cũng làm như vậy. – qrest

Trả lời

1

tôi nhận được cùng một vấn đề trên hệ thống của tôi (cho cả hai dòng và nguyên thủy khác), và sử dụng các nhà xây dựng Pixel trực tiếp thay vì mapRGB dường như để cung cấp cho màu sắc chính xác.

Ví dụ: nếu tôi nhập Graphics.UI.SDL.Color làm SDLC và sau đó let white' = SDLC.Pixel maxBound, tôi nhận được đường trắng, như mong đợi. Với SDLC.Pixel 4278190335 (hoặc 255 * 2^24 + 255, một giá trị hợp lý cho màu đỏ), tôi nhận được một đường màu đỏ.

Đây rõ ràng không phải là giải pháp hoặc câu trả lời thực sự, nhưng có thể gợi ý một số điểm bắt đầu.

Một điều kỳ lạ khác: nếu tôi in cả hai màu trắng của bạn và của tôi như vậy:

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

tôi có được điều này:

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

Vì vậy, họ đều giống nhau qua getRGBA, nhưng thực tế Pixel các giá trị khác nhau.

2

Tôi quan sát hiệu ứng tương tự trên Lucid với trình điều khiển ATI HD2400 và radeon (nếu có vấn đề). Nhưng có một cách giải quyết khác.

Ví dụ này thu hút một dòng trắng:

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 

Tôi chấp nhận rằng đây là một hack xấu xí, nhưng có vẻ như đó là định dạng bề mặt mặc định điểm ảnh không phải là RGB, và sử dụng một định dạng pixel của một (?) bề mặt được biết đến là RGB giúp. Tôi không có kinh nghiệm với SDL, vì vậy tôi không thể nói những gì đúng cách để sử dụng nó là.

3

Có lẽ một hack ít bẩn (mặc dù có lẽ là nền tảng/thực hiện phụ thuộc):

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)) 
Các vấn đề liên quan