Does there exist a Haskell graphics library or binding to an external library that fulfills the following requirements:
ghci
, i.e. I don't have to link and restart the program.?
Please include a minimal source code example or a reference to it (just a window on screen, maybe with a green line drawn inside it) so that I can check the points 1. and 2. in particular. Also, if one of these feature requests is more elaborate (for example OpenGL + 4), please include a good reference.
PS: Concerning 1 and 2, I know about the enableGUI
trick and I am willing to use it. However, most libraries have the problem that you can't run the main
function multiple times and hence don't qualify.
Edit: To avoid wasting your time, here a list of packages that I've tried:
libstdc++
main
to be a macro. Compile-time only.main
twice, something about "failing because it can't install mouse event handler".EDIT: Actually, I'm no longer sure. Several versions later, it seems that GLFW no longer works in GHCi on OS X.
It turns out that GLFW+OpenGL fulfills all four requirements!
ghci -framework Carbon
.EnableGUI.hs
file, which you can get here. Note that you can't load it right into GHCi, you have to comiple it, first.Here is a small example that puts a bitmap onto the screen. There are some restrictions on the bitmap: its dimensions must be a power of two (here 256) and it must be a .tga
file (here "Bitmap.tga"
). But since transparency is supported, this is not much of a problem.
You should be able to call main
multiple times without problem. The key point is that you should not call 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
Here an example bitmap (which you need to convert to .tga
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With