Ответ 1
EDIT: Вообще-то, я не уверен. Несколько версий позже, похоже, GLFW больше не работает в GHCi на OS X.
Оказывается, GLFW + OpenGL выполняет все четыре требования!
- Вам нужно вызвать ghci с помощью
ghci -framework Carbon
. - Вам нужен файл
EnableGUI.hs
, который вы можете получить здесь. Обратите внимание, что вы не можете загрузить его прямо в GHCi, сначала вам нужно соединить его. - OpenGL имеет режим 2D-проекции, где вы можете рисовать линии и полигоны.
- Растровые изображения могут быть загружены как текстуры и наложены на многоугольники.
Вот небольшой пример, который помещает растровое изображение на экран. Существуют некоторые ограничения на растровое изображение: его размеры должны быть равны двум (здесь 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 $= \ [email protected](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
).