macos - descargar - install haskell brew
Biblioteca de gráficos Haskell que funciona en GHCi en MacOS X (5)
¿Has visto el GLFW como se menciona http://plucky.cs.yale.edu/soe/software1.htm
¿Existe una biblioteca de gráficos Haskell o un enlace a una biblioteca externa que cumpla con los siguientes requisitos:
- Se puede usar desde
ghci
, es decir, no tengo que vincular y reiniciar el programa. - Funciona en MacOS X. (¡Tricky en conjunto con 1!)
- Puede hacer gráficos vectoriales simples (líneas, polígonos, rellenos simples y trazos).
- Puede poner imágenes de mapas de bits en la pantalla. Ejemplo: blit una imagen de 17x12 .bmp.
?
Incluya un ejemplo de código fuente mínimo o una referencia (solo una ventana en la pantalla, tal vez con una línea verde dibujada en su interior) para que pueda verificar los puntos 1. y 2. en particular. Además, si una de estas solicitudes de funciones es más elaborada (por ejemplo, OpenGL + 4), incluya una buena referencia.
PD: Con respecto a 1 y 2, sé sobre el truco enableGUI
y estoy dispuesto a usarlo. Sin embargo, la mayoría de las bibliotecas tienen el problema de que no puede ejecutar la función main
varias veces y, por lo tanto, no califican.
Editar: para evitar perder el tiempo, aquí una lista de paquetes que he probado:
A principios de 2014, no pude usar @ heinrich-apfelmus answer en Mac OS X. Sin embargo, este ejemplo GLFW-b ( link ) funcionó.
Por lo tanto, asegúrese de tener:
$ cabal install glfw-b
y, si probaste la respuesta de Apfelmus, es posible que necesites
$ ghc-pkg list
$ ghc-pkg unregister GLFW-x.x.x.x
ya que ambos proporcionan Graphics.UI.GLFW
, y obtendrá un "nombre de módulo ambiguo ''Graphics.UI.GLFW''" de ghc. Entonces probé el programa de ejemplo anterior y funcionó (Mac OS X, 10.9, Mavericks)
EDITAR: En realidad, ya no estoy seguro. Varias versiones más adelante, parece que GLFW ya no funciona en GHCi en OS X.
¡Resulta que GLFW + OpenGL cumple con los cuatro requisitos!
- Necesita invocar ghci con
ghci -framework Carbon
. - Necesita el archivo
EnableGUI.hs
, que puede obtener here . Tenga en cuenta que no puede cargarlo directamente en GHCi, primero tiene que ponerlo en práctica. - OpenGL tiene un modo de proyección 2D donde puede dibujar líneas y polígonos.
- Los mapas de bits pueden cargarse como texturas y colocarse en polígonos.
Aquí hay un pequeño ejemplo que pone un mapa de bits en la pantalla. Hay algunas restricciones en el mapa de bits: sus dimensiones deben ser una potencia de dos (aquí 256) y debe ser un archivo .tga
(aquí "Bitmap.tga"
). Pero dado que la transparencia es compatible, esto no es un gran problema.
Debería poder llamar al main
varias veces sin problema. El punto clave es que no debe llamar a 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
Aquí un mapa de bits de ejemplo (que debe convertir a .tga
).
La biblioteca Gtk2Hs cumple todos los requisitos si utiliza la versión X11 del marco gtk2.
En cuanto a los requisitos:
- El uso de X11 evita muchos problemas.
- Instale
gtk2
través de MacPorts y use la opción + x11 (valor predeterminado). (Dicho esto, he tenido numerosos problemas para instalar gtk2 en el pasado, pero esta vez parecía funcionar). - Me sorprendería si GTK + no puede hacer eso.
- Ídem.
Aquí un ejemplo mínimo
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
Más información sobre Haskell + GUI + OpenGL está disponible en esta discusión: http://www.haskell.org/pipermail/haskell-cafe/2011-May/091991.html