--------------------------------------------------------------------------------
-- |
-- Module      :  Graphics.Rendering.OpenGL.GL.PixelRectangles.Minmax
-- Copyright   :  (c) Sven Panne 2002-2019
-- License     :  BSD3
--
-- Maintainer  :  Sven Panne <svenpanne@gmail.com>
-- Stability   :  stable
-- Portability :  portable
--
-- This module corresponds to a part of section 3.6.1 (Pixel Storage Modes) of
-- the OpenGL 2.1 specs.
--
--------------------------------------------------------------------------------

module Graphics.Rendering.OpenGL.GL.PixelRectangles.Minmax (
   minmax, getMinmax, resetMinmax
) where

import Data.StateVar
import Foreign.Marshal.Utils
import Graphics.Rendering.OpenGL.GL.Capability
import Graphics.Rendering.OpenGL.GL.PeekPoke
import Graphics.Rendering.OpenGL.GL.PixelData
import Graphics.Rendering.OpenGL.GL.PixelRectangles.Reset
import Graphics.Rendering.OpenGL.GL.PixelRectangles.Sink
import Graphics.Rendering.OpenGL.GL.Texturing.PixelInternalFormat
import Graphics.GL

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

data MinmaxTarget =
     Minmax

marshalMinmaxTarget :: MinmaxTarget -> GLenum
marshalMinmaxTarget :: MinmaxTarget -> GLenum
marshalMinmaxTarget MinmaxTarget
x = case MinmaxTarget
x of
   MinmaxTarget
Minmax -> GLenum
GL_MINMAX

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

minmax :: StateVar (Maybe (PixelInternalFormat, Sink))
minmax :: StateVar (Maybe (PixelInternalFormat, Sink))
minmax = IO EnableCap
-> IO (PixelInternalFormat, Sink)
-> ((PixelInternalFormat, Sink) -> IO ())
-> StateVar (Maybe (PixelInternalFormat, Sink))
forall a.
IO EnableCap -> IO a -> (a -> IO ()) -> StateVar (Maybe a)
makeStateVarMaybe (EnableCap -> IO EnableCap
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return EnableCap
CapMinmax) IO (PixelInternalFormat, Sink)
getMinmax' (PixelInternalFormat, Sink) -> IO ()
setMinmax

getMinmax' :: IO (PixelInternalFormat, Sink)
getMinmax' :: IO (PixelInternalFormat, Sink)
getMinmax' = do
   PixelInternalFormat
f <- (GLint -> PixelInternalFormat)
-> GetMinmaxParameterPName -> IO PixelInternalFormat
forall a. (GLint -> a) -> GetMinmaxParameterPName -> IO a
getMinmaxParameteri GLint -> PixelInternalFormat
unmarshalPixelInternalFormat GetMinmaxParameterPName
MinmaxFormat
   Sink
s <- (GLint -> Sink) -> GetMinmaxParameterPName -> IO Sink
forall a. (GLint -> a) -> GetMinmaxParameterPName -> IO a
getMinmaxParameteri GLint -> Sink
unmarshalSink GetMinmaxParameterPName
MinmaxSink
   (PixelInternalFormat, Sink) -> IO (PixelInternalFormat, Sink)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (PixelInternalFormat
f, Sink
s)

setMinmax :: (PixelInternalFormat, Sink) -> IO ()
setMinmax :: (PixelInternalFormat, Sink) -> IO ()
setMinmax (PixelInternalFormat
int, Sink
sink) =
   GLenum -> GLenum -> GLboolean -> IO ()
forall (m :: * -> *).
MonadIO m =>
GLenum -> GLenum -> GLboolean -> m ()
glMinmax
      (MinmaxTarget -> GLenum
marshalMinmaxTarget MinmaxTarget
Minmax)
      (PixelInternalFormat -> GLenum
marshalPixelInternalFormat' PixelInternalFormat
int)
      (Sink -> GLboolean
marshalSink Sink
sink)

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

getMinmax :: Reset -> PixelData a -> IO ()
getMinmax :: forall a. Reset -> PixelData a -> IO ()
getMinmax Reset
reset PixelData a
pd =
   PixelData a -> (GLenum -> GLenum -> Ptr a -> IO ()) -> IO ()
forall a b. PixelData a -> (GLenum -> GLenum -> Ptr a -> b) -> b
withPixelData PixelData a
pd ((GLenum -> GLenum -> Ptr a -> IO ()) -> IO ())
-> (GLenum -> GLenum -> Ptr a -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$
      GLenum -> GLboolean -> GLenum -> GLenum -> Ptr a -> IO ()
forall (m :: * -> *) a.
MonadIO m =>
GLenum -> GLboolean -> GLenum -> GLenum -> Ptr a -> m ()
glGetMinmax (MinmaxTarget -> GLenum
marshalMinmaxTarget MinmaxTarget
Minmax) (Reset -> GLboolean
marshalReset Reset
reset)

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

resetMinmax :: IO ()
resetMinmax :: IO ()
resetMinmax = GLenum -> IO ()
forall (m :: * -> *). MonadIO m => GLenum -> m ()
glResetMinmax (MinmaxTarget -> GLenum
marshalMinmaxTarget MinmaxTarget
Minmax)

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

data GetMinmaxParameterPName =
     MinmaxFormat
   | MinmaxSink

marshalGetMinmaxParameterPName :: GetMinmaxParameterPName -> GLenum
marshalGetMinmaxParameterPName :: GetMinmaxParameterPName -> GLenum
marshalGetMinmaxParameterPName GetMinmaxParameterPName
x = case GetMinmaxParameterPName
x of
   GetMinmaxParameterPName
MinmaxFormat -> GLenum
GL_MINMAX_FORMAT
   GetMinmaxParameterPName
MinmaxSink -> GLenum
GL_MINMAX_SINK

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

getMinmaxParameteri :: (GLint -> a) -> GetMinmaxParameterPName -> IO a
getMinmaxParameteri :: forall a. (GLint -> a) -> GetMinmaxParameterPName -> IO a
getMinmaxParameteri GLint -> a
f GetMinmaxParameterPName
p =
   GLint -> (Ptr GLint -> IO a) -> IO a
forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
with GLint
0 ((Ptr GLint -> IO a) -> IO a) -> (Ptr GLint -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \Ptr GLint
buf -> do
      GLenum -> GLenum -> Ptr GLint -> IO ()
forall (m :: * -> *).
MonadIO m =>
GLenum -> GLenum -> Ptr GLint -> m ()
glGetMinmaxParameteriv
         (MinmaxTarget -> GLenum
marshalMinmaxTarget MinmaxTarget
Minmax)
         (GetMinmaxParameterPName -> GLenum
marshalGetMinmaxParameterPName GetMinmaxParameterPName
p)
         Ptr GLint
buf
      (GLint -> a) -> Ptr GLint -> IO a
forall a b. Storable a => (a -> b) -> Ptr a -> IO b
peek1 GLint -> a
f Ptr GLint
buf