-- | This example program demonstrates how \"boxes\" work.
--
-- It is also useful for debugging.
--
-- Note: this program does not do any font rendering; for that, see the
-- other example program (example-STIX.hs)!
--
module Main where
--------------------------------------------------------------------------------
import Data.Char hiding ( Space )
import Control.Monad
import Data.IORef
import System.IO.Unsafe as Unsafe
import qualified Data.Map as Map ; import Data.Map (Map)
import Graphics.Rendering.OpenGL as GL
import Graphics.UI.GLFW ( Window )
import Graphics.Rendering.MiniTypeset
import GL
--------------------------------------------------------------------------------
box1, box2 :: Box
box1 = Box 50 75 5 10 15 20 10 5
box2 = Box 63 105 10 25 5 5 12 8
--------------------------------------------------------------------------------
scaleCol :: Double -> Col -> Col
scaleCol s (Col r g b) = Col (s*r) (s*g) (s*b)
setCol :: Col -> IO ()
setCol (Col r g b) = color (Color3 r g b)
setColAlpha :: Col -> Double -> IO ()
setColAlpha (Col r g b) a = color (Color4 r g b a)
withPos :: Pos -> IO a -> IO a
withPos (Pos x y) action = do
GL.translate (Vector3 x y 0)
r <- action
GL.translate (Vector3 (-x) (-y) 0) -- quick hack :)
return r
--------------------------------------------------------------------------------
renderBoxOutline :: Col -> Box -> IO ()
renderBoxOutline col (Box w h l r t b hgap vgap) = do
setCol (scaleCol 0.5 col) ; renderQuadOutline (-l,-t) (w+r+hgap,h+b+vgap)
setCol (scaleCol 0.75 col) ; renderQuadOutline (-l,-t) (w+r,h+b)
setCol col ; renderQuadOutline ( 0, 0) (w,h)
renderBoxFilled:: Col -> Double -> Box -> IO ()
renderBoxFilled col alpha (Box w h l r t b hgap vgap) = do
blend $= Enabled
blendFunc $= (SrcAlpha, OneMinusSrcAlpha)
setColAlpha (scaleCol 0.5 col) alpha ; renderQuadFilled (-l,-t) (w+r+hgap,h+b+vgap)
setColAlpha (scaleCol 0.75 col) alpha ; renderQuadFilled (-l,-t) (w+r,h+b)
setColAlpha col alpha ; renderQuadFilled ( 0, 0) (w,h)
blend $= Disabled
withAbsBox :: AbsBox -> (Box -> IO a) -> IO a
withAbsBox (AbsBox pos box) action = withPos pos (action box)
--------------------------------------------------------------------------------
renderQuadOutline :: (Double,Double) -> (Double,Double) -> IO ()
renderQuadOutline (x1,y1) (x2,y2) = do
renderPrimitive LineLoop $ do
vertex (Vertex2 x1 y1)
vertex (Vertex2 x2 y1)
vertex (Vertex2 x2 y2)
vertex (Vertex2 x1 y2)
renderQuadFilled :: (Double,Double) -> (Double,Double) -> IO ()
renderQuadFilled (x1,y1) (x2,y2) = do
renderPrimitive Quads $ do
vertex (Vertex2 x1 y1)
vertex (Vertex2 x2 y1)
vertex (Vertex2 x2 y2)
vertex (Vertex2 x1 y2)
--------------------------------------------------------------------------------
renderTriple :: (Box,(AbsBox,AbsBox)) -> IO ()
renderTriple (box,(abox1,abox2)) = do
withAbsBox abox1 $ renderBoxFilled (Col 0 1 0) 0.75
withAbsBox abox2 $ renderBoxFilled (Col 0 0 1) 0.75
let abox = AbsBox (Pos 0 0) box
blend $= Enabled
setColAlpha (Col 1 0 0) 0.20
renderOuterBoxQuad abox
renderInnerBoxQuad abox
setColAlpha (Col 1 1 1) 0.25
renderBoxGap abox
blend $= Disabled
renderBoxOutline (Col 1 0 0) box
display :: Window -> Double -> IO ()
display window time = do
clearColor $=! (Color4 0 0 0 0)
clear [ColorBuffer,DepthBuffer]
-- setWindowCoordSystem
-- GL.scale 2 2 (0.5::Double)
matrixMode $= Projection
loadIdentity
ortho 0 800 500 0 (-1) (1::Double) -- to avoid issues with "retina" displays (window size /= framebuffer res)
withPos (Pos 15 25) $ renderTriple $ hcatBox2 AlignTop box1 box2
withPos (Pos 215 25) $ renderTriple $ hcatBox2 AlignBottom box1 box2
withPos (Pos 15 225) $ renderTriple $ vcatBox2 AlignLeft box1 box2
withPos (Pos 215 225) $ renderTriple $ vcatBox2 AlignRight box1 box2
withPos (Pos 415 25) $ renderTriple $ hcatBox2 AlignTop box2 box1
withPos (Pos 615 25) $ renderTriple $ hcatBox2 AlignBottom box2 box1
withPos (Pos 415 225) $ renderTriple $ vcatBox2 AlignLeft box2 box1
withPos (Pos 615 225) $ renderTriple $ vcatBox2 AlignRight box2 box1
return ()
--------------------------------------------------------------------------------
main = do
initGL (return ()) (\() -> display)
--------------------------------------------------------------------------------