Haskell图形库,适用于MacOS X上的GHCi

Hei*_*mus 34 macos graphics haskell ghci

是否存在Haskell图形库或绑定到满足以下要求的外部库:

  1. 可以使用ghci,即我没有链接和重新启动程序.
  2. 适用于MacOS X.(Tricky与1一起使用!)
  3. 可以做简单的矢量图形(线条,多边形,简单填充和笔画).
  4. 可以将位图图像放在屏幕上.示例:blit a 17x12 .bmp图像.

请包含一个最小的源代码示例或对它的引用(只是屏幕上的一个窗口,可能在其中绘制绿线),以便我可以检查点1和2.特别是.此外,如果其中一个功能请求更复杂(例如OpenGL + 4),请包含一个很好的参考.


PS:关于1和2,我知道这个enableGUI技巧,我愿意使用它.但是,大多数库存在的问题是您无法main多次运行该函数,因此不符合条件.


编辑:为了避免浪费你的时间,这里列出了我尝试过的软件包:

  • wx - ghci呛到了libstdc++
  • sdl - 重新定义main为宏.仅编译时间.
  • GLFW(OpenGL) - 无法运行main两次,因为"无法安装鼠标事件处理程序而失败".

Hei*_*mus 15

编辑:实际上,我不再确定.几个版本之后,似乎GLFW不再适用于OS X上的GHCi.

事实证明,GLFW + OpenGL满足了所有四个要求!

  1. 你需要调用ghci ghci -framework Carbon.
  2. 你需要这个EnableGUI.hs文件,你可以在这里找到.请注意,您无法将其直接加载到GHCi中,您必须首先将其加载到GHCi中.
  3. OpenGL具有2D投影模式,您可以在其中绘制线条和多边形.
  4. 位图可以作为纹理加载并放在多边形上.

这是一个将位图放在屏幕上的小例子.位图有一些限制:它的尺寸必须是2的幂(这里是256),它必须是一个.tga文件(这里"Bitmap.tga").但由于支持透明度,这不是一个问题.

您应该可以main多次调用而不会出现问题.关键是你不应该打电话GLFW.terminate.

import Graphics.Rendering.OpenGL as GL
import qualified Graphics.UI.GLFW as GLFW
import Graphics.Rendering.OpenGL (($=))

import Control.Monad
import EnableGUI

main = do
    enableGUI
    GLFW.initialize
    -- open window
    GLFW.openWindow (GL.Size 400 400) [GLFW.DisplayAlphaBits 8] GLFW.Window
    GLFW.windowTitle $= "Bitmap Test"

    -- enable alpha channel
    GL.blend         $= GL.Enabled
    GL.blendFunc     $= (GL.SrcAlpha, GL.OneMinusSrcAlpha)
    -- set the color to clear background
    GL.clearColor    $= GL.Color4 0.8 0.8 0.8 0

    -- set 2D orthogonal view inside windowSizeCallback because
    -- any change to the Window size should result in different
    -- OpenGL Viewport.
    GLFW.windowSizeCallback $= \ size@(GL.Size w h) ->
      do
        GL.viewport   $= (GL.Position 0 0, size)
        GL.matrixMode $= GL.Projection
        GL.loadIdentity
        GL.ortho2D 0 (realToFrac w) (realToFrac h) 0

    render <- initialize
    loop render

    GLFW.closeWindow

loop render = do
    -- draw the entire screen
    render
    -- swap buffer
    GLFW.swapBuffers
    -- check whether ESC is pressed for termination
    p <- GLFW.getKey GLFW.ESC
    unless (p == GLFW.Press) $ do
        -- sleep for 1ms to yield CPU to other applications
        GLFW.sleep 0.001
        -- only continue when the window is not closed
        windowOpenStatus <- GLFW.getParam GLFW.Opened
        unless (windowOpenStatus == False) $
            loop render

-- rendering
initialize = do
    -- load texture from file
    GL.texture GL.Texture2D $= Enabled
    [textureName] <- GL.genObjectNames 1
    GL.textureBinding GL.Texture2D $= Just textureName
    GL.textureFilter  GL.Texture2D $= ((GL.Nearest, Nothing), GL.Nearest)
    GLFW.loadTexture2D "Bitmap.tga" []

    return $ do
        GL.clear [GL.ColorBuffer]
        GL.renderPrimitive GL.Quads $ do
            GL.texCoord $ texCoord2 0 0
            GL.vertex   $ vertex3 (0) 256 0
            GL.texCoord $ texCoord2 0 1
            GL.vertex   $ vertex3 (0) (0) 0
            GL.texCoord $ texCoord2 1 1
            GL.vertex   $ vertex3 256 (0) 0
            GL.texCoord $ texCoord2 1 0
            GL.vertex   $ vertex3 256 256 0

-- type signatures to avoid ambiguity
vertex3 :: GLfloat -> GLfloat -> GLfloat -> GL.Vertex3 GLfloat
vertex3 = GL.Vertex3

texCoord2 :: GLfloat -> GLfloat -> GL.TexCoord2 GLfloat
texCoord2 = GL.TexCoord2

color3 :: GLfloat -> GLfloat -> GLfloat -> GL.Color3 GLfloat
color3 = GL.Color3
Run Code Online (Sandbox Code Playgroud)

这是一个示例位图(您需要转换为.tga).

示例位图