РЕДАКТИРОВАТЬ: На самом деле я больше не уверен. Несколько версий спустя, кажется, что 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 $= \ 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
Вот пример растрового изображения (которое необходимо преобразовать в .tga
).