{-# OPTIONS_HADDOCK hide #-} {-# LANGUAGE ScopedTypeVariables, Rank2Types #-} -- | Handling the current viewport during rendering. module Graphics.Gloss.Internals.Render.ViewPort ( withViewPort ) where import Graphics.Gloss.Internals.Interface.Backend import Graphics.Gloss.Internals.Interface.ViewPort import Graphics.Rendering.OpenGL (GLfloat, ($=)) import qualified Graphics.Rendering.OpenGL.GL as GL import Data.IORef (IORef) -- | Perform a rendering action whilst using the given viewport withViewPort :: forall a . Backend a => IORef a -> ViewPort -- ^ The viewport to use. -> IO () -- ^ The rendering action to perform. -> IO () withViewPort backendRef port action = do GL.matrixMode $= GL.Projection GL.preservingMatrix $ do -- setup the co-ordinate system GL.loadIdentity (sizeX, sizeY) <- getWindowDimensions backendRef 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 GL.preservingMatrix $ do GL.loadIdentity let rotate :: GLfloat = realToFrac $ viewPortRotate port let transX :: GLfloat = realToFrac $ fst $ viewPortTranslate port let transY :: GLfloat = realToFrac $ snd $ viewPortTranslate port let scale :: GLfloat = realToFrac $ viewPortScale port -- apply the global view transforms GL.scale scale scale 1 GL.rotate rotate (GL.Vector3 0 0 1) GL.translate (GL.Vector3 transX transY 0) -- call the client render action action GL.matrixMode $= GL.Projection GL.matrixMode $= GL.Modelview 0