34

次の要件を満たすHaskellグラフィックライブラリまたは外部ライブラリへのバインディングが存在しますか?

  1. から使用できますghci。つまり、プログラムをリンクして再起動する必要はありません。
  2. MacOS Xで動作します(1と組み合わせてトリッキーです!)
  3. 単純なベクターグラフィック(線、多角形、単純な塗りつぶし、ストローク)を実行できます。
  4. 画面にビットマップ画像を配置できます。例:17x12の.bmp画像をブリットします。

特にポイント1と2を確認できるように、最小限のソースコード例またはその参照(画面上のウィンドウのみ、内部に緑色の線が引かれている可能性があります)を含めてください。また、これらの機能要求の1つがより複雑な場合(たとえば、OpenGL + 4)、適切なリファレンスを含めてください。


PS:1と2に関しては、私はそのトリックを知っており、enableGUIそれを喜んで使用します。ただし、ほとんどのライブラリには、関数を複数回実行できないため、main資格がないという問題があります。


編集:あなたの時間を無駄にしないために、ここに私が試したパッケージのリストがあります:

  • wx -ghciが窒息するlibstdc++
  • sdl-mainマクロとして再定義します。コンパイル時のみ。
  • GLFW(OpenGL) -2main回実行できません。これは、「マウスイベントハンドラーをインストールできないために失敗する」というものです。
4

5 に答える 5

15

編集:実際には、私はもうわかりません。いくつかのバージョンの後、GLFWはOSXのGHCiでは機能しなくなったようです。

GLFW+OpenGLは4つの要件すべてを満たしていることがわかりました。

  1. でghciを呼び出す必要がありますghci -framework Carbon
  2. ここでEnableGUI.hs入手できるファイルが必要です。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

ここにサンプルビットマップ(変換する必要があります.tga)。

サンプルビットマップ

于 2011-05-07T17:23:12.933 に答える
3

X11バージョンのgtk2フレームワークを使用する場合、Gtk2Hsライブラリはすべての要件を満たします。

要件について:

  1. X11を使用すると、多くの問題を回避できます。
  2. MacPortsgtk2経由でインストールし、+ x11オプション(デフォルト)を使用します。(そうは言っても、私は過去にgtk2のインストールで多くの問題を抱えていましたが、今回はうまくいったようです。)
  3. GTK+がそれができないとしたら驚きます。
  4. 同上。

ここに最小限の例があります

import Graphics.UI.Gtk

hello :: (ButtonClass o) => o -> IO ()
hello b = set b [buttonLabel := "Hello World"]

main :: IO ()
main = do
    initGUI
    window <- windowNew
    button <- buttonNew
    set window [windowDefaultWidth := 200, windowDefaultHeight := 200,
              containerChild := button, containerBorderWidth := 10]
    onClicked button (hello button)
    onDestroy window mainQuit
    widgetShowAll window
    mainGUI
于 2011-05-07T17:24:31.280 に答える
2

2014年の初めの時点で、Mac OSXで@heinrich-apfelmusの回答を使用できませんでした。ただし、このGLFW-bの例(リンク)は機能しました。

したがって、次のことを確認してください。

$ cabal install glfw-b

そして、もしあなたがアプフェルムスの答えを試したなら、あなたはする必要があるかもしれません

$ ghc-pkg list
$ ghc-pkg unregister GLFW-x.x.x.x

両方が提供するGraphics.UI.GLFWので、ghcから「あいまいなモジュール名'Graphics.UI.GLFW'」を取得します。次に、上記のサンプルプログラムを試してみたところ、動作しました(Mac OS X、10.9、Mavericks)

于 2014-04-07T05:37:36.120 に答える
1

参照されているGLFWを見たことがありますかhttp://plucky.cs.yale.edu/soe/software1.htm

于 2011-05-03T20:36:02.867 に答える
1

Haskell + GUI + OpenGLの詳細については、このディスカッションを参照してください:http: //www.haskell.org/pipermail/haskell-cafe/2011-May/091991.html

于 2011-05-18T18:31:22.090 に答える