3

我希望在窗口中的屏幕上绘制单个像素或在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
4

2 回答 2

2

在我看来,您实际上并没有在那里任何东西。你确定 setColors 做你认为它做的事吗?如果我没记错的话,它是用于为 8 位表面设置调色板,而您正在明确设置 32 位视频模式。

顺便说一句,如果您在我确定知道区别之前完成了图形编程,但为了其他人阅读本文的好处:8 位视频模式将像素颜色作为 8 位索引存储到 256 色表中从更大的一组潜在颜色中选择;在更高的颜色深度中,调色板表被省去,每个像素颜色直接存储为一个打包的 RGB 三元组,通常每个 8 位(32 位像素也有一个 8 位 alpha 通道,或者只有 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),您可能需要考虑寻找 C 语言中的 SDL 示例作为参考资料。

于 2009-12-07T15:23:23.570 回答
1

我知道这个问题大约有一年的历史,但这里有误导性的答案,你可以使用 Haskell SDL 绑定进行像素操作,查看我的代码以了解如何做,这是LazyFoo 的 SDL 教程 31 的一个端口

于 2010-11-21T17:00:46.380 回答