--------------------------------------------------------------------------------
-- |
-- 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 =
   forall a b.
PixelData a -> (GLbitfield -> GLbitfield -> Ptr a -> b) -> b
withPixelData PixelData a
pd forall a b. (a -> b) -> a -> b
$ 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 =
   forall a. IO a -> (a -> IO ()) -> StateVar a
makeStateVar
      (forall p a. GetPName1I p => (GLbitfield -> a) -> p -> IO a
getEnum1 GLbitfield -> BufferMode
unmarshalBufferMode PName1I
GetReadBuffer)
      (forall b a. b -> (a -> b) -> Maybe a -> b
maybe IO ()
recordInvalidValue forall (m :: * -> *). MonadIO m => GLbitfield -> m ()
glReadBuffer forall b c a. (b -> c) -> (a -> b) -> a -> c
. BufferMode -> Maybe GLbitfield
marshalBufferMode)

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

data PixelCopyType =
     CopyColor
   | CopyDepth
   | CopyStencil
   deriving ( PixelCopyType -> PixelCopyType -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PixelCopyType -> PixelCopyType -> Bool
$c/= :: PixelCopyType -> PixelCopyType -> Bool
== :: PixelCopyType -> PixelCopyType -> Bool
$c== :: PixelCopyType -> PixelCopyType -> Bool
Eq, Eq 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
min :: PixelCopyType -> PixelCopyType -> PixelCopyType
$cmin :: PixelCopyType -> PixelCopyType -> PixelCopyType
max :: PixelCopyType -> PixelCopyType -> PixelCopyType
$cmax :: PixelCopyType -> PixelCopyType -> PixelCopyType
>= :: PixelCopyType -> PixelCopyType -> Bool
$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
compare :: PixelCopyType -> PixelCopyType -> Ordering
$ccompare :: PixelCopyType -> PixelCopyType -> Ordering
Ord, Int -> PixelCopyType -> ShowS
[PixelCopyType] -> ShowS
PixelCopyType -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PixelCopyType] -> ShowS
$cshowList :: [PixelCopyType] -> ShowS
show :: PixelCopyType -> String
$cshow :: PixelCopyType -> String
showsPrec :: Int -> PixelCopyType -> ShowS
$cshowsPrec :: Int -> 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 =
   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
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BlitBuffer -> BlitBuffer -> Bool
$c/= :: BlitBuffer -> BlitBuffer -> Bool
== :: BlitBuffer -> BlitBuffer -> Bool
$c== :: BlitBuffer -> BlitBuffer -> Bool
Eq, Eq 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
min :: BlitBuffer -> BlitBuffer -> BlitBuffer
$cmin :: BlitBuffer -> BlitBuffer -> BlitBuffer
max :: BlitBuffer -> BlitBuffer -> BlitBuffer
$cmax :: BlitBuffer -> BlitBuffer -> BlitBuffer
>= :: BlitBuffer -> BlitBuffer -> Bool
$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
compare :: BlitBuffer -> BlitBuffer -> Ordering
$ccompare :: BlitBuffer -> BlitBuffer -> Ordering
Ord, Int -> BlitBuffer -> ShowS
[BlitBuffer] -> ShowS
BlitBuffer -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BlitBuffer] -> ShowS
$cshowList :: [BlitBuffer] -> ShowS
show :: BlitBuffer -> String
$cshow :: BlitBuffer -> String
showsPrec :: Int -> BlitBuffer -> ShowS
$cshowsPrec :: Int -> 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 =
   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
                     (forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (forall a b. (a -> b) -> [a] -> [b]
map BlitBuffer -> GLbitfield
marshalBlitBuffer [BlitBuffer]
buffers))
                     (forall a b. (Integral a, Num b) => a -> b
fromIntegral (TextureFilter -> GLint
marshalMagnificationFilter TextureFilter
filt))