Pergunta

Desejo desenhar pixels individuais em uma tela em uma janela ou algo para exibição em tempo real em Haskell.

Estou apenas começando com a Haskell (mas não a programação funcional, e não os gráficos), por isso estou tentando criar algumas coisas gráficas rudimentares com ele.

Eu tentei usar o SDL, mas o código a seguir me dá uma tela em branco:

import Prelude
import Graphics.UI.SDL as SDL

createColor screen r g b = SDL.mapRGB (SDL.surfaceGetPixelFormat screen) r g b

drawGrad screen = SDL.setColors screen [SDL.Color x y 255 | x <- [0..255], y <- [0..255]] 800

main = do
  SDL.init [InitEverything]
  setVideoMode 256 256 32 []
  screen <- getVideoSurface
  drawGrad screen
  SDL.flip screen
  quitHandler

quitHandler :: IO ()
quitHandler = do
  e <- waitEvent
  case e of
    Quit -> return ()
    otherwise -> quitHandler
Foi útil?

Solução

Parece -me que você não está realmente desenho qualquer coisa aí. Tem certeza de que o SetColors faz o que você acha que sim? Se a memória me serve, é para definir a paleta de cores para uma superfície de 8 bits, enquanto você está definindo explicitamente um modo de vídeo de 32 bits.

Como um aparte, se você fez programação de gráficos antes de ter certeza vocês Saiba a diferença, mas para o benefício de outras pessoas lendo isso: modos de vídeo de 8 bits armazenam cores de pixel como um índice de 8 bits em uma tabela de 256 cores escolhidas de um conjunto muito maior de cores potenciais; Em profundidades de cores mais altas, a mesa da paleta é dispensada e cada cor de pixel é armazenada diretamente como um Triplo RGB embalado, normalmente de 8 bits cada (pixels de 32 bits também possuem um canal alfa de 8 bits, ou apenas 8 bits de preenchimento para melhor alinhamento de memória, não me lembro).

De qualquer maneira, se estou adivinhando corretamente o que você estava tentando fazer, tente adicionar isso ao seu programa:

import Ix

-- Given coordinates, create a 1x1 rectangle containing that pixel
getPix x y = SDL.Rect (fromIntegral x) (fromIntegral y) 1 1

-- Draw a pixel on a surface with color determined by position
drawPixel surf (x, y) = do
    let pixRect = Just (getPix x y)
    pixColor <- createColor surf x y 255
    SDL.fillRect surf pixRect pixColor

-- Apply drawPixel to each coordinate on the screen
drawGrad screen = mapM_ (drawPixel screen) $ range ((0,0),(255,255))

Aviso: Isso é quase certamente um código horrível e ineficiente, e foi testado apenas em um ambiente Win32. Não sou um programador haskell qualificado e meus conselhos não devem ser seguidos como indicativos do uso correto do idioma. Somente para uso externo. Não provoce a Feliz Diversão Io Mônada.

De qualquer forma, acho que seu problema está no uso do SDL, não Haskell. Graphics.ui.sdl é bastante cru, pouco mais do que envolver a API C nos tipos haskell apropriados. Se você não usou SDL antes ou o usou apenas com ligações um pouco mais elaboradas (por exemplo, pygame), considere procurar exemplos de SDL em C como material de referência.

Outras dicas

Eu sei que essa pergunta tem cerca de um ano de idade, mas há respostas enganosas aqui, você pode fazer manipulação de pixels com ligações Haskell SDL, verifique meu código, por exemplo, como fazer, é um Tutorial SDL do porto de Lazyfoo 31

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top