    --------------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.Rendering.OpenGL.GL.ReadCopyPixels
    -- Copyright   :  (c) Sven Panne 2002-2019
    -- License     :  BSD3
    --
    -- Maintainer  :  Sven Panne <svenpanne@gmail.com>
    -- Stability   :  stable
    -- Portability :  portable
    --
    -- This module corresponds to section 4.3 (Drawing, Reading, and Copying Pixels)
    -- of the OpenGL 2.1 specs.
    --
    --------------------------------------------------------------------------------

    module Graphics.Rendering.OpenGL.GL.ReadCopyPixels (
       -- * Reading Pixels
       readPixels, readBuffer,

       -- * Copying Pixels
       PixelCopyType(..), copyPixels,

       -- * Copying Pixels for framebuffers
       BlitBuffer(..), blitFramebuffer
    ) where

    import Data.StateVar
    import Graphics.Rendering.OpenGL.GL.BufferMode
    import Graphics.Rendering.OpenGL.GL.CoordTrans
    import Graphics.Rendering.OpenGL.GL.PixelData
    import Graphics.Rendering.OpenGL.GL.QueryUtils
    import Graphics.Rendering.OpenGL.GL.Texturing.Filter
    import Graphics.Rendering.OpenGL.GLU.ErrorsInternal
    import Graphics.GL

    --------------------------------------------------------------------------------

    readPixels :: Position -> Size -> PixelData a -> IO ()
    readPixels :: forall a. Position -> Size -> PixelData a -> IO ()
    readPixels (Position GLint
    x GLint
    y) (Size GLint
    w GLint
    h) PixelData a
    pd =
       PixelData a
    -> (GLbitfield -> GLbitfield -> Ptr a -> IO ()) -> IO ()
    forall a b.
    PixelData a -> (GLbitfield -> GLbitfield -> Ptr a -> b) -> b
    withPixelData PixelData a
    pd ((GLbitfield -> GLbitfield -> Ptr a -> IO ()) -> IO ())
    -> (GLbitfield -> GLbitfield -> Ptr a -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ GLint
    -> GLint
    -> GLint
    -> GLint
    -> GLbitfield
    -> GLbitfield
    -> Ptr a
    -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLint
    -> GLint
    -> GLint
    -> GLint
    -> GLbitfield
    -> GLbitfield
    -> Ptr a
    -> m ()
    glReadPixels GLint
    x GLint
    y GLint
    w GLint
    h

    --------------------------------------------------------------------------------

    readBuffer :: StateVar BufferMode
    readBuffer :: StateVar BufferMode
    readBuffer =
       IO BufferMode -> (BufferMode -> IO ()) -> StateVar BufferMode
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
          ((GLbitfield -> BufferMode) -> PName1I -> IO BufferMode
    forall p a. GetPName1I p => (GLbitfield -> a) -> p -> IO a
    forall a. (GLbitfield -> a) -> PName1I -> IO a
    getEnum1 GLbitfield -> BufferMode
    unmarshalBufferMode PName1I
    GetReadBuffer)
          (IO () -> (GLbitfield -> IO ()) -> Maybe GLbitfield -> IO ()
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe IO ()
    recordInvalidValue GLbitfield -> IO ()
    forall (m :: * -> *). MonadIO m => GLbitfield -> m ()
    glReadBuffer (Maybe GLbitfield -> IO ())
    -> (BufferMode -> Maybe GLbitfield) -> BufferMode -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BufferMode -> Maybe GLbitfield
    marshalBufferMode)

    --------------------------------------------------------------------------------

    data PixelCopyType =
         CopyColor
       | CopyDepth
       | CopyStencil
       deriving ( PixelCopyType -> PixelCopyType -> Bool
    (PixelCopyType -> PixelCopyType -> Bool)
    -> (PixelCopyType -> PixelCopyType -> Bool) -> Eq PixelCopyType
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PixelCopyType -> PixelCopyType -> Bool
    == :: PixelCopyType -> PixelCopyType -> Bool
    $c/= :: PixelCopyType -> PixelCopyType -> Bool
    /= :: PixelCopyType -> PixelCopyType -> Bool
    Eq, Eq PixelCopyType
    Eq PixelCopyType =>
    (PixelCopyType -> PixelCopyType -> Ordering)
    -> (PixelCopyType -> PixelCopyType -> Bool)
    -> (PixelCopyType -> PixelCopyType -> Bool)
    -> (PixelCopyType -> PixelCopyType -> Bool)
    -> (PixelCopyType -> PixelCopyType -> Bool)
    -> (PixelCopyType -> PixelCopyType -> PixelCopyType)
    -> (PixelCopyType -> PixelCopyType -> PixelCopyType)
    -> Ord PixelCopyType
    PixelCopyType -> PixelCopyType -> Bool
    PixelCopyType -> PixelCopyType -> Ordering
    PixelCopyType -> PixelCopyType -> PixelCopyType
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: PixelCopyType -> PixelCopyType -> Ordering
    compare :: PixelCopyType -> PixelCopyType -> Ordering
    $c< :: PixelCopyType -> PixelCopyType -> Bool
    < :: PixelCopyType -> PixelCopyType -> Bool
    $c<= :: PixelCopyType -> PixelCopyType -> Bool
    <= :: PixelCopyType -> PixelCopyType -> Bool
    $c> :: PixelCopyType -> PixelCopyType -> Bool
    > :: PixelCopyType -> PixelCopyType -> Bool
    $c>= :: PixelCopyType -> PixelCopyType -> Bool
    >= :: PixelCopyType -> PixelCopyType -> Bool
    $cmax :: PixelCopyType -> PixelCopyType -> PixelCopyType
    max :: PixelCopyType -> PixelCopyType -> PixelCopyType
    $cmin :: PixelCopyType -> PixelCopyType -> PixelCopyType
    min :: PixelCopyType -> PixelCopyType -> PixelCopyType
    Ord, Int -> PixelCopyType -> ShowS
    [PixelCopyType] -> ShowS
    PixelCopyType -> String
    (Int -> PixelCopyType -> ShowS)
    -> (PixelCopyType -> String)
    -> ([PixelCopyType] -> ShowS)
    -> Show PixelCopyType
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PixelCopyType -> ShowS
    showsPrec :: Int -> PixelCopyType -> ShowS
    $cshow :: PixelCopyType -> String
    show :: PixelCopyType -> String
    $cshowList :: [PixelCopyType] -> ShowS
    showList :: [PixelCopyType] -> ShowS
    Show )

    marshalPixelCopyType :: PixelCopyType -> GLenum
    marshalPixelCopyType :: PixelCopyType -> GLbitfield
    marshalPixelCopyType PixelCopyType
    x = case PixelCopyType
    x of
       PixelCopyType
    CopyColor -> GLbitfield
    GL_COLOR
       PixelCopyType
    CopyDepth -> GLbitfield
    GL_DEPTH
       PixelCopyType
    CopyStencil -> GLbitfield
    GL_STENCIL

    --------------------------------------------------------------------------------

    copyPixels :: Position -> Size -> PixelCopyType -> IO ()
    copyPixels :: Position -> Size -> PixelCopyType -> IO ()
    copyPixels (Position GLint
    x GLint
    y) (Size GLint
    w GLint
    h) PixelCopyType
    t =
       GLint -> GLint -> GLint -> GLint -> GLbitfield -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLint -> GLint -> GLint -> GLint -> GLbitfield -> m ()
    glCopyPixels GLint
    x GLint
    y GLint
    w GLint
    h (PixelCopyType -> GLbitfield
    marshalPixelCopyType PixelCopyType
    t)

    --------------------------------------------------------------------------------

    -- | The buffers which can be copied with 'blitFramebuffer'.

    data BlitBuffer =
         ColorBuffer'
       | StencilBuffer'
       | DepthBuffer'
       deriving ( BlitBuffer -> BlitBuffer -> Bool
    (BlitBuffer -> BlitBuffer -> Bool)
    -> (BlitBuffer -> BlitBuffer -> Bool) -> Eq BlitBuffer
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: BlitBuffer -> BlitBuffer -> Bool
    == :: BlitBuffer -> BlitBuffer -> Bool
    $c/= :: BlitBuffer -> BlitBuffer -> Bool
    /= :: BlitBuffer -> BlitBuffer -> Bool
    Eq, Eq BlitBuffer
    Eq BlitBuffer =>
    (BlitBuffer -> BlitBuffer -> Ordering)
    -> (BlitBuffer -> BlitBuffer -> Bool)
    -> (BlitBuffer -> BlitBuffer -> Bool)
    -> (BlitBuffer -> BlitBuffer -> Bool)
    -> (BlitBuffer -> BlitBuffer -> Bool)
    -> (BlitBuffer -> BlitBuffer -> BlitBuffer)
    -> (BlitBuffer -> BlitBuffer -> BlitBuffer)
    -> Ord BlitBuffer
    BlitBuffer -> BlitBuffer -> Bool
    BlitBuffer -> BlitBuffer -> Ordering
    BlitBuffer -> BlitBuffer -> BlitBuffer
    forall a.
    Eq a =>
    (a -> a -> Ordering)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> Bool)
    -> (a -> a -> a)
    -> (a -> a -> a)
    -> Ord a
    $ccompare :: BlitBuffer -> BlitBuffer -> Ordering
    compare :: BlitBuffer -> BlitBuffer -> Ordering
    $c< :: BlitBuffer -> BlitBuffer -> Bool
    < :: BlitBuffer -> BlitBuffer -> Bool
    $c<= :: BlitBuffer -> BlitBuffer -> Bool
    <= :: BlitBuffer -> BlitBuffer -> Bool
    $c> :: BlitBuffer -> BlitBuffer -> Bool
    > :: BlitBuffer -> BlitBuffer -> Bool
    $c>= :: BlitBuffer -> BlitBuffer -> Bool
    >= :: BlitBuffer -> BlitBuffer -> Bool
    $cmax :: BlitBuffer -> BlitBuffer -> BlitBuffer
    max :: BlitBuffer -> BlitBuffer -> BlitBuffer
    $cmin :: BlitBuffer -> BlitBuffer -> BlitBuffer
    min :: BlitBuffer -> BlitBuffer -> BlitBuffer
    Ord, Int -> BlitBuffer -> ShowS
    [BlitBuffer] -> ShowS
    BlitBuffer -> String
    (Int -> BlitBuffer -> ShowS)
    -> (BlitBuffer -> String)
    -> ([BlitBuffer] -> ShowS)
    -> Show BlitBuffer
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> BlitBuffer -> ShowS
    showsPrec :: Int -> BlitBuffer -> ShowS
    $cshow :: BlitBuffer -> String
    show :: BlitBuffer -> String
    $cshowList :: [BlitBuffer] -> ShowS
    showList :: [BlitBuffer] -> ShowS
    Show )

    marshalBlitBuffer :: BlitBuffer -> GLbitfield
    marshalBlitBuffer :: BlitBuffer -> GLbitfield
    marshalBlitBuffer BlitBuffer
    x = case BlitBuffer
    x of
       BlitBuffer
    ColorBuffer' -> GLbitfield
    GL_COLOR_BUFFER_BIT
       BlitBuffer
    StencilBuffer' -> GLbitfield
    GL_STENCIL_BUFFER_BIT
       BlitBuffer
    DepthBuffer' -> GLbitfield
    GL_DEPTH_BUFFER_BIT

    --------------------------------------------------------------------------------

    blitFramebuffer :: Position
                    -> Position
                    -> Position
                    -> Position
                    -> [BlitBuffer]
                    -> TextureFilter
                    -> IO ()
    blitFramebuffer :: Position
    -> Position
    -> Position
    -> Position
    -> [BlitBuffer]
    -> TextureFilter
    -> IO ()
    blitFramebuffer (Position GLint
    sx0 GLint
    sy0)
                    (Position GLint
    sx1 GLint
    sy1)
                    (Position GLint
    dx0 GLint
    dy0)
                    (Position GLint
    dx1 GLint
    dy1)
                    [BlitBuffer]
    buffers
                    TextureFilter
    filt =
       GLint
    -> GLint
    -> GLint
    -> GLint
    -> GLint
    -> GLint
    -> GLint
    -> GLint
    -> GLbitfield
    -> GLbitfield
    -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLint
    -> GLint
    -> GLint
    -> GLint
    -> GLint
    -> GLint
    -> GLint
    -> GLint
    -> GLbitfield
    -> GLbitfield
    -> m ()
    glBlitFramebuffer GLint
    sx0 GLint
    sy0 GLint
    sx1 GLint
    sy1 GLint
    dx0 GLint
    dy0 GLint
    dx1 GLint
    dy1
                         ([GLbitfield] -> GLbitfield
    forall a. Num a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum ((BlitBuffer -> GLbitfield) -> [BlitBuffer] -> [GLbitfield]
    forall a b. (a -> b) -> [a] -> [b]
    map BlitBuffer -> GLbitfield
    marshalBlitBuffer [BlitBuffer]
    buffers))
                         (GLint -> GLbitfield
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (TextureFilter -> GLint
    marshalMagnificationFilter TextureFilter
    filt))