Haskell библиотека рисования пикселей Linux - PullRequest
3 голосов
/ 07 декабря 2009

Я хочу нарисовать отдельные пиксели на экране в окне или что-то для отображения в реальном времени в haskell.

Я только начинаю работать с haskell (но не с функциональным программированием и не с графикой), поэтому я пытаюсь создать с его помощью элементарные графические элементы.

Я пытался использовать SDL, но следующий код дает мне пустой экран:

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

Ответы [ 2 ]

2 голосов
/ 07 декабря 2009

Мне кажется, что вы на самом деле не рисуете ничего там. Вы уверены, что setColors делает то, что, по вашему мнению, делает? Если мне не изменяет память, это для настройки цветовой палитры для 8-битной поверхности, тогда как вы явно устанавливаете 32-битный режим видео

Кроме того, если вы уже занимались графическим программированием, прежде чем я уверен, вы знаете разницу, но в интересах других, читающих это: 8-битные режимы видео хранят пиксельные цвета как 8 -битный индекс в таблицу из 256 цветов, выбранных из гораздо большего набора потенциальных цветов; при более высокой глубине цвета таблица палитры обходится, и каждый цвет пикселя сохраняется непосредственно как упакованная тройка RGB, обычно по 8 бит каждый (32-битные пиксели либо имеют 8-битный альфа-канал, либо всего 8 бит заполнение для лучшего выравнивания памяти, я не могу вспомнить).

В любом случае, если я правильно угадываю, что вы пытались сделать, попробуйте добавить это в вашу программу:

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

Предупреждение: Это почти наверняка ужасный и неэффективный код, и он был протестирован только в среде Win32. Я не квалифицированный программист на Haskell, и мои советы не должны восприниматься как указание на правильное использование языка. Только для наружного применения. Не издевайтесь над Happy Fun IO Monad.

В любом случае, я думаю, что ваша проблема заключается в использовании SDL, а не Haskell. Graphics.UI.SDL довольно сырой, немного больше, чем оборачивание C API в соответствующие типы Haskell. Если вы ранее не использовали SDL или использовали его только с немного более сложными привязками (например, PyGame), вы можете рассмотреть поиск примеров SDL в C в качестве справочного материала.

1 голос
/ 21 ноября 2010

Я знаю, что этому вопросу около года, но здесь есть вводящие в заблуждение ответы, вы можете делать пиксельные манипуляции с привязками Haskell SDL, посмотрите мой код, например, как это сделать, это порт учебника SDL от LazyFoo 31

...