packages feed

brillo-rendering-2.0.0: Brillo/Internals/Rendering/Common.hs

{-# OPTIONS_HADDOCK hide #-}

module Brillo.Internals.Rendering.Common (
  gf,
  gsizei,
  withModelview,
  withClearBuffer,
)
where

import Brillo.Internals.Data.Color (Color)
import Brillo.Internals.Rendering.Color (glColor4OfColor)
import Graphics.Rendering.OpenGL (($=))
import Graphics.Rendering.OpenGL.GL qualified as GL
import Unsafe.Coerce (unsafeCoerce)


{-| The OpenGL library doesn't seem to provide a nice way convert
     a Float to a GLfloat, even though they're the same thing
     under the covers.

 Using realToFrac is too slow, as it doesn't get fused in at
     least GHC 6.12.1
-}
gf :: Float -> GL.GLfloat
gf = unsafeCoerce
{-# INLINE gf #-}


-- | Used for similar reasons to above
gsizei :: Int -> GL.GLsizei
gsizei = unsafeCoerce
{-# INLINE gsizei #-}


{-| Set up the OpenGL rendering context for orthographic projection and run an
  action to draw the model.
-}
withModelview ::
  -- | Width and height of window.
  (Int, Int) ->
  -- | Action to perform.
  IO () ->
  IO ()
withModelview (sizeX, sizeY) action =
  do
    GL.matrixMode $= GL.Projection
    GL.preservingMatrix $
      do
        -- setup the co-ordinate system
        GL.loadIdentity
        let (sx, sy) = (fromIntegral sizeX / 2, fromIntegral sizeY / 2)
        GL.ortho (-sx) sx (-sy) sy 0 (-100)

        -- draw the world
        GL.matrixMode $= GL.Modelview 0
        action

        GL.matrixMode $= GL.Projection

    GL.matrixMode $= GL.Modelview 0


{-| Clear the OpenGL buffer with the given background color and run
  an action to draw the model.
-}
withClearBuffer ::
  -- | Background color
  Color ->
  -- | Action to perform
  IO () ->
  IO ()
withClearBuffer clearColor action =
  do
    -- initialization (done every time in this case)
    -- we don't need the depth buffer for 2d.
    GL.depthFunc GL.$= Just GL.Always

    -- always clear the buffer to white
    GL.clearColor GL.$= glColor4OfColor clearColor

    -- on every loop
    GL.clear [GL.ColorBuffer, GL.DepthBuffer]
    GL.color $ GL.Color4 0 0 0 (1 :: GL.GLfloat)

    action