HaskellでGLFWを使うための備忘録 - ウィンドウ表示編

HaskellでGLFWを使うための備忘録のウィンドウ表示編です。

OpenGLなどのGUI関連のチュートリアルでほとんど最初に行うことはウィンドウ表示です。

ウィンドウを表示するコードは以下の通りです。

GLFWの関数

今回のコードで使ったGLFW-bの関数の適当な説明をここに記していきます。

getVersionString :: IO (Maybe String)

Maybe String型のバージョン情報を取得するための関数です。

C/C++版GLFWのglfwGetVersionStringに相当。

getVersionStringは型を見るとMaybe Stringの値を返すIOアクションであることが分かるので<-関数を使ってversionという変数に束縛します。

Just version = GLFW.getVersionString
putStrLn version

MaybeモナドNothing以外はすべてJust aの型になるのでパターンマッチを使ってMaybe StringStringの値のみを抽出します。

init :: IO Bool

GLFWを初期化するための関数。

初期化していない場合、使える関数はgetVersiongetVersionStringsetErrorCallbackinitterminateのみとなります。

C/C++版GLFWのglfwInitに相当。

initBoolを返すIOアクションなのでgetVersionStringと同様に(<-)関数で束縛します。

glfwInitialized <- GLFW.init
putStrLn $ "status:" ++ (show glfwInitialized)

defaultWindowHints :: IO ()

Window Hintsをデフォルト値にする関数。

(Window Hintsについてご存知の御方はコメントにて教えていただけると助かります。)

defaultWindowHints()なので何も出力も返しません。

createWindow :: Int -> Int -> String -> Maybe Monitor -> Maybe Window -> IO (Maybe Window)

新しくウィンドウを作る関数。

GHCIで実行する際は:set -fno-ghci-sandboxを忘れずにとのことですが試してないです。

GLFWのglfwCreateWindowに相当。

引数はそれぞれcreateWindow Width Height Title Monitor Windowとなっており。

Monitorにはフルスクリーンで表示するときにどのモニターを使うか指定するときに使います。

Windowは別のウィンドウの情報を共有する際に用いるらしいです。

今回MonitorWindowは指定しないので両方共Nothingとします。

Just win <- GLFW.createWindow width height title monitor window

--------------------

where
    width = 400
    height = 400
    title = "Hello World"
    monitor = Nothing
    window = Nothing 

これもMaybe Windowを返すIOアクションなのでパターンマッチを使ってWindowwinに束縛しています。

makeContextCurrent :: Maybe Window -> IO ()

現在のウィンドウのコンテキストを作成します。

コンテキストとはOpenGLの状態を保持しているデータです。

コンテキストを変更することで表示が変わるなどします。

GLFW.makeContextCurrent (Just win)

setKeyCallback :: Window -> Maybe KeyCallback -> IO ()

対象のウィンドウに任意のキーが押された際のコールバックを設定する関数です。

GLFW.setKeyCallback win (Just keyCallback)

--------------------

keyCallback :: GLFW.KeyCallback
keyCallback win GLFW.Key'Q _ GLFW.KeyState'Pressed _ = shutdown win
keyCallback _ _ _ _ _ = return ()

KeyCallback :: Window -> Key -> Int -> KeyState -> ModifierKeys -> IO ()

GLFW.KeyCallbackWindow -> Key -> Int -> KeyState -> ModifierKeys -> IO ()の型シノニムです。

C/C++版GLFWのsetKeyCallbackによるとGLFWkeyfunという構造体に相当します。

それぞれの引数はWindow -> Key -> Scancode -> KeyState -> ModifierKeysとなります。

Keyはキーボードからの入力。

Scancodeは任意のキーのスキャンコード。

KeyStateKeyState'PressedKeyState'ReleasedKeyState'Repeating押された離された繰り返し押されたの3状態のうちいずれか。

ModifierKeysはデータ型ModifierKeysを指定します。

ModifierKeysModifierKeys :: Bool -> Bool -> Bool -> Bool -> ModifierKeysという型シグネチャのデータ型です。 4つのBool値はそれぞれShiftControlAltSuperに対応しています。

Shiftを押しながらQを押したときにウィンドウを閉じるときは以下のようにします。

keyCallback win GLFW.Key'Q _ GLFW.KeyState'Pressed (GLFW.ModifierKeys True False False False) = shutdown win

setWindowCloseCallback :: Window -> Maybe WindowCloseCallback -> IO ()

ウィンドウを閉じる際のコールバックを設定する関数です。

WindowCloseCallbackWindow -> IO ()の型シノニムです。

GLFW.setWindowCloseCallback win (Just shutdown)

雑な説明になりましたので何か間違ってる箇所とか自分が勘違いしているところも多々あると思いますので、コメントにてご指摘してくださると助かります。

参考文献

OpenGL (GLFW-b) - IT練習ノート

Graphics.UI.GLFW