Biblioteca de gráficos Haskell que funciona en GHCi en macOS X
¿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. (Difícil en conjunción con 1!)
- Puede hacer gráficos vectoriales simples (líneas, polígonos, rellenos simples y trazos).
- Puede poner imágenes de mapa de bits en la pantalla. Ejemplo: blit a 17x12 .imagen bmp.
?
Por favor incluya un ejemplo de código fuente mínimo o una referencia a él (solo una ventana en la pantalla, tal vez con una línea verde dibujada dentro de ella) para que pueda verificar los puntos 1. y 2. especialmente. Además, si una de estas solicitudes de características es más elaborada (por ejemplo, OpenGL + 4), incluya una buena referencia.
PS: Con respecto a 1 y 2, sé acerca del 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 calificar.
Edit: Para evitar perder el tiempo, aquí una lista de paquetes que he probado:
5 answers
EDITAR: En realidad, ya no estoy seguro. Varias versiones más tarde, 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 aquí. Tenga en cuenta que no se puede cargar directamente en GHCi, tienes que comiple, primero. - OpenGL tiene un modo de proyección 2D donde se pueden dibujar líneas y polígonos.
- Mapas de bits se puede cargar como texturas y poner 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 se apoya la transparencia, esto no es un gran problema.
Debería poder llamar a main
varias veces sin problema. El punto clave es que no debes 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 ejemplo de mapa de bits (que necesita convertir a .tga
).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-20 12:27:00
La biblioteca Gtk2Hs cumple todos los requisitos si utiliza la versión X11 del framework gtk2.
En cuanto a los requisitos:
- El uso de X11 evita muchos problemas.
- Instale
gtk2
a través de MacPorts y use la opción +x11 (predeterminada). (Dicho esto, he tenido numerosos problemas instalando gtk2 en el pasado, pero esta vez parecía funcionar.) - Me sorprendería si GTK+ no puede hacer eso.
- Ídem.
Aquí un mínimo ejemplo
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-07 17:24:31
A principios de 2014, no pude usar la respuesta @heinrich-apfelmus en Mac OS X. Sin embargo, este ejemplo de 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
Como ambos proporcionan Graphics.UI.GLFW
, y obtendrá un "nombre de módulo Ambiguo" Gráficos.UI.GLFW '" de ghc. Luego solo probé el programa de ejemplo anterior y funcionó (Mac OS X, 10.9, Mavericks)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-09 11:11:04
¿Has visto el GLFW como se hace referencia http://plucky.cs.yale.edu/soe/software1.htm
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-03 20:36:02
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-18 18:31:22