    --------------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.Rendering.OpenGL.GL.PerFragment
    -- Copyright   :  (c) Sven Panne 2002-2019
    -- License     :  BSD3
    --
    -- Maintainer  :  Sven Panne <svenpanne@gmail.com>
    -- Stability   :  stable
    -- Portability :  portable
    --
    -- This module corresponds to section 4.1 (Per-Fragment Operations) of the
    -- OpenGL 2.1 specs.
    --
    --------------------------------------------------------------------------------

    module Graphics.Rendering.OpenGL.GL.PerFragment (
       -- * Discarding Primitives Before Rasterization
       rasterizerDiscard, discardingRasterizer,

       -- * Scissor Test
       scissor,

       -- * Multisample Fragment Operations
       sampleAlphaToCoverage,  sampleAlphaToOne, sampleCoverage,

       -- * Depth Bounds Test
       depthBounds,

       -- * Alpha Test
       ComparisonFunction(..), alphaFunc,

       -- * Stencil Test
       stencilTest, stencilFunc, stencilFuncSeparate, StencilOp(..), stencilOp,
       stencilOpSeparate, activeStencilFace,

       -- * Depth Buffer Test
       depthFunc,

       -- * Blending
       blend, blendBuffer, BlendEquation(..), blendEquation, blendEquationSeparate,
       BlendingFactor(..), blendFuncSeparate, blendFunc, blendColor,

       -- * Dithering
       dither,

       -- * Logical Operation
       LogicOp(..), logicOp
    ) where

    import Control.Monad
    import Data.StateVar
    import Graphics.Rendering.OpenGL.GL.BlendingFactor
    import Graphics.Rendering.OpenGL.GL.Capability
    import Graphics.Rendering.OpenGL.GL.ComparisonFunction
    import Graphics.Rendering.OpenGL.GL.CoordTrans
    import Graphics.Rendering.OpenGL.GL.Exception
    import Graphics.Rendering.OpenGL.GL.Face
    import Graphics.Rendering.OpenGL.GL.Framebuffer
    import Graphics.Rendering.OpenGL.GL.GLboolean
    import Graphics.Rendering.OpenGL.GL.QueryUtils
    import Graphics.Rendering.OpenGL.GL.VertexSpec
    import Graphics.Rendering.OpenGL.GLU.ErrorsInternal
    import Graphics.GL

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

    rasterizerDiscard :: StateVar Capability
    rasterizerDiscard :: StateVar Capability
    rasterizerDiscard = EnableCap -> StateVar Capability
    makeCapability EnableCap
    CapRasterizerDiscard

    discardingRasterizer :: IO a -> IO a
    discardingRasterizer :: forall a. IO a -> IO a
    discardingRasterizer IO a
    act = do
       r <- StateVar Capability -> IO Capability
    forall t a (m :: * -> *). (HasGetter t a, MonadIO m) => t -> m a
    forall (m :: * -> *).
    MonadIO m =>
    StateVar Capability -> m Capability
    get StateVar Capability
    rasterizerDiscard
       bracket_ (rasterizerDiscard $= Enabled) (rasterizerDiscard $= r) act

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

    scissor :: StateVar (Maybe (Position, Size))
    scissor :: StateVar (Maybe (Position, Size))
    scissor =
       IO EnableCap
    -> IO (Position, Size)
    -> ((Position, Size) -> IO ())
    -> StateVar (Maybe (Position, Size))
    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
    CapScissorTest)
          ((GLint -> GLint -> GLint -> GLint -> (Position, Size))
    -> PName4I -> IO (Position, Size)
    forall p a.
    GetPName4I p =>
    (GLint -> GLint -> GLint -> GLint -> a) -> p -> IO a
    forall a.
    (GLint -> GLint -> GLint -> GLint -> a) -> PName4I -> IO a
    getInteger4 GLint -> GLint -> GLint -> GLint -> (Position, Size)
    forall {a} {a}.
    (Integral a, Integral a) =>
    GLint -> GLint -> a -> a -> (Position, Size)
    makeSB PName4I
    GetScissorBox)
          (\(Position GLint
    x GLint
    y, Size GLint
    w GLint
    h) -> GLint -> GLint -> GLint -> GLint -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLint -> GLint -> GLint -> GLint -> m ()
    glScissor GLint
    x GLint
    y GLint
    w GLint
    h)
       where makeSB :: GLint -> GLint -> a -> a -> (Position, Size)
    makeSB GLint
    x GLint
    y a
    w a
    h = (GLint -> GLint -> Position
    Position GLint
    x GLint
    y, GLint -> GLint -> Size
    Size (a -> GLint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    w) (a -> GLint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    h))

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

    sampleAlphaToCoverage :: StateVar Capability
    sampleAlphaToCoverage :: StateVar Capability
    sampleAlphaToCoverage = EnableCap -> StateVar Capability
    makeCapability EnableCap
    CapSampleAlphaToCoverage

    sampleAlphaToOne :: StateVar Capability
    sampleAlphaToOne :: StateVar Capability
    sampleAlphaToOne = EnableCap -> StateVar Capability
    makeCapability EnableCap
    CapSampleAlphaToOne

    sampleCoverage :: StateVar (Maybe (GLclampf, Bool))
    sampleCoverage :: StateVar (Maybe (GLclampf, Bool))
    sampleCoverage =
       IO EnableCap
    -> IO (GLclampf, Bool)
    -> ((GLclampf, Bool) -> IO ())
    -> StateVar (Maybe (GLclampf, Bool))
    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
    CapSampleCoverage)
          ((GLclampf -> Bool -> (GLclampf, Bool))
    -> IO GLclampf -> GettableStateVar Bool -> IO (GLclampf, Bool)
    forall (m :: * -> *) a1 a2 r.
    Monad m =>
    (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
    liftM2 (,) ((GLclampf -> GLclampf) -> PName1F -> IO GLclampf
    forall p a. GetPName1F p => (GLclampf -> a) -> p -> IO a
    forall a. (GLclampf -> a) -> PName1F -> IO a
    getClampf1 GLclampf -> GLclampf
    forall a. a -> a
    id PName1F
    GetSampleCoverageValue)
                      ((GLboolean -> Bool) -> PName1I -> GettableStateVar Bool
    forall p a. GetPName1I p => (GLboolean -> a) -> p -> IO a
    forall a. (GLboolean -> a) -> PName1I -> IO a
    getBoolean1 GLboolean -> Bool
    forall a. (Eq a, Num a) => a -> Bool
    unmarshalGLboolean PName1I
    GetSampleCoverageInvert))
          (\(GLclampf
    value, Bool
    invert) -> GLclampf -> GLboolean -> IO ()
    forall (m :: * -> *). MonadIO m => GLclampf -> GLboolean -> m ()
    glSampleCoverage GLclampf
    value (Bool -> GLboolean
    forall a. Num a => Bool -> a
    marshalGLboolean Bool
    invert))

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

    depthBounds :: StateVar (Maybe (GLclampd, GLclampd))
    depthBounds :: StateVar (Maybe (GLclampd, GLclampd))
    depthBounds =
       IO EnableCap
    -> IO (GLclampd, GLclampd)
    -> ((GLclampd, GLclampd) -> IO ())
    -> StateVar (Maybe (GLclampd, GLclampd))
    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
    CapDepthBoundsTest)
          ((GLclampd -> GLclampd -> (GLclampd, GLclampd))
    -> PName2F -> IO (GLclampd, GLclampd)
    forall p a.
    GetPName2F p =>
    (GLclampd -> GLclampd -> a) -> p -> IO a
    forall a. (GLclampd -> GLclampd -> a) -> PName2F -> IO a
    getClampd2 (,) PName2F
    GetDepthBounds)
          ((GLclampd -> GLclampd -> IO ()) -> (GLclampd, GLclampd) -> IO ()
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry GLclampd -> GLclampd -> IO ()
    forall (m :: * -> *). MonadIO m => GLclampd -> GLclampd -> m ()
    glDepthBoundsEXT)

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

    alphaFunc :: StateVar (Maybe (ComparisonFunction, GLclampf))
    alphaFunc :: StateVar (Maybe (ComparisonFunction, GLclampf))
    alphaFunc =
       IO EnableCap
    -> IO (ComparisonFunction, GLclampf)
    -> ((ComparisonFunction, GLclampf) -> IO ())
    -> StateVar (Maybe (ComparisonFunction, GLclampf))
    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
    CapAlphaTest)
          ((ComparisonFunction -> GLclampf -> (ComparisonFunction, GLclampf))
    -> IO ComparisonFunction
    -> IO GLclampf
    -> IO (ComparisonFunction, GLclampf)
    forall (m :: * -> *) a1 a2 r.
    Monad m =>
    (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
    liftM2 (,) ((GLenum -> ComparisonFunction) -> PName1I -> IO ComparisonFunction
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> PName1I -> IO a
    getEnum1 GLenum -> ComparisonFunction
    unmarshalComparisonFunction PName1I
    GetAlphaTestFunc)
                      ((GLclampf -> GLclampf) -> PName1F -> IO GLclampf
    forall p a. GetPName1F p => (GLclampf -> a) -> p -> IO a
    forall a. (GLclampf -> a) -> PName1F -> IO a
    getClampf1 GLclampf -> GLclampf
    forall a. a -> a
    id PName1F
    GetAlphaTestRef))
          ((ComparisonFunction -> GLclampf -> IO ())
    -> (ComparisonFunction, GLclampf) -> IO ()
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry (GLenum -> GLclampf -> IO ()
    forall (m :: * -> *). MonadIO m => GLenum -> GLclampf -> m ()
    glAlphaFunc (GLenum -> GLclampf -> IO ())
    -> (ComparisonFunction -> GLenum)
    -> ComparisonFunction
    -> GLclampf
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ComparisonFunction -> GLenum
    marshalComparisonFunction))

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

    stencilTest :: StateVar Capability
    stencilTest :: StateVar Capability
    stencilTest = EnableCap -> StateVar Capability
    makeCapability EnableCap
    CapStencilTest

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

    stencilFunc :: StateVar (ComparisonFunction, GLint, GLuint)
    stencilFunc :: StateVar (ComparisonFunction, GLint, GLenum)
    stencilFunc =
       IO (ComparisonFunction, GLint, GLenum)
    -> ((ComparisonFunction, GLint, GLenum) -> IO ())
    -> StateVar (ComparisonFunction, GLint, GLenum)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
          (StateVar (ComparisonFunction, GLint, GLenum)
    -> IO (ComparisonFunction, GLint, GLenum)
    forall t a (m :: * -> *). (HasGetter t a, MonadIO m) => t -> m a
    forall (m :: * -> *).
    MonadIO m =>
    StateVar (ComparisonFunction, GLint, GLenum)
    -> m (ComparisonFunction, GLint, GLenum)
    get (Face -> StateVar (ComparisonFunction, GLint, GLenum)
    stencilFuncSeparate Face
    Front))
          (\(ComparisonFunction
    func, GLint
    ref, GLenum
    mask) ->
             GLenum -> GLint -> GLenum -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLenum -> GLint -> GLenum -> m ()
    glStencilFunc (ComparisonFunction -> GLenum
    marshalComparisonFunction ComparisonFunction
    func) GLint
    ref GLenum
    mask)

    stencilFuncSeparate :: Face -> StateVar (ComparisonFunction, GLint, GLuint)
    stencilFuncSeparate :: Face -> StateVar (ComparisonFunction, GLint, GLenum)
    stencilFuncSeparate Face
    face =
       IO (ComparisonFunction, GLint, GLenum)
    -> ((ComparisonFunction, GLint, GLenum) -> IO ())
    -> StateVar (ComparisonFunction, GLint, GLenum)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
          (case Face
    face of
              Face
    Front -> PName1I
    -> PName1I -> PName1I -> IO (ComparisonFunction, GLint, GLenum)
    forall {p} {p} {p} {a3}.
    (GetPName1I p, GetPName1I p, GetPName1I p, Num a3) =>
    p -> p -> p -> IO (ComparisonFunction, GLint, a3)
    getStencilFunc PName1I
    GetStencilFunc
                                      PName1I
    GetStencilRef
                                      PName1I
    GetStencilValueMask
              Face
    Back -> PName1I
    -> PName1I -> PName1I -> IO (ComparisonFunction, GLint, GLenum)
    forall {p} {p} {p} {a3}.
    (GetPName1I p, GetPName1I p, GetPName1I p, Num a3) =>
    p -> p -> p -> IO (ComparisonFunction, GLint, a3)
    getStencilFunc PName1I
    GetStencilBackFunc
                                     PName1I
    GetStencilBackRef
                                     PName1I
    GetStencilBackValueMask
              Face
    FrontAndBack -> do IO ()
    recordInvalidEnum; (ComparisonFunction, GLint, GLenum)
    -> IO (ComparisonFunction, GLint, GLenum)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (ComparisonFunction
    Never, GLint
    0, GLenum
    0))
          (\(ComparisonFunction
    func, GLint
    ref, GLenum
    mask) ->
             GLenum -> GLenum -> GLint -> GLenum -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLenum -> GLenum -> GLint -> GLenum -> m ()
    glStencilFuncSeparate (Face -> GLenum
    marshalFace Face
    face)
                                   (ComparisonFunction -> GLenum
    marshalComparisonFunction ComparisonFunction
    func) GLint
    ref GLenum
    mask)
       where getStencilFunc :: p -> p -> p -> IO (ComparisonFunction, GLint, a3)
    getStencilFunc p
    func p
    ref p
    mask =
                (ComparisonFunction
     -> GLint -> a3 -> (ComparisonFunction, GLint, a3))
    -> IO ComparisonFunction
    -> IO GLint
    -> IO a3
    -> IO (ComparisonFunction, GLint, a3)
    forall (m :: * -> *) a1 a2 a3 r.
    Monad m =>
    (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
    liftM3 (,,) ((GLenum -> ComparisonFunction) -> p -> IO ComparisonFunction
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> p -> IO a
    getEnum1 GLenum -> ComparisonFunction
    unmarshalComparisonFunction p
    func)
                            ((GLint -> GLint) -> p -> IO GLint
    forall p a. GetPName1I p => (GLint -> a) -> p -> IO a
    forall a. (GLint -> a) -> p -> IO a
    getInteger1 GLint -> GLint
    forall a. a -> a
    id p
    ref)
                            ((GLint -> a3) -> p -> IO a3
    forall p a. GetPName1I p => (GLint -> a) -> p -> IO a
    forall a. (GLint -> a) -> p -> IO a
    getInteger1 GLint -> a3
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral p
    mask)

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

    data StencilOp =
         OpZero
       | OpKeep
       | OpReplace
       | OpIncr
       | OpIncrWrap
       | OpDecr
       | OpDecrWrap
       | OpInvert
       deriving ( StencilOp -> StencilOp -> Bool
    (StencilOp -> StencilOp -> Bool)
    -> (StencilOp -> StencilOp -> Bool) -> Eq StencilOp
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: StencilOp -> StencilOp -> Bool
    == :: StencilOp -> StencilOp -> Bool
    $c/= :: StencilOp -> StencilOp -> Bool
    /= :: StencilOp -> StencilOp -> Bool
    Eq, Eq StencilOp
    Eq StencilOp =>
    (StencilOp -> StencilOp -> Ordering)
    -> (StencilOp -> StencilOp -> Bool)
    -> (StencilOp -> StencilOp -> Bool)
    -> (StencilOp -> StencilOp -> Bool)
    -> (StencilOp -> StencilOp -> Bool)
    -> (StencilOp -> StencilOp -> StencilOp)
    -> (StencilOp -> StencilOp -> StencilOp)
    -> Ord StencilOp
    StencilOp -> StencilOp -> Bool
    StencilOp -> StencilOp -> Ordering
    StencilOp -> StencilOp -> StencilOp
    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 :: StencilOp -> StencilOp -> Ordering
    compare :: StencilOp -> StencilOp -> Ordering
    $c< :: StencilOp -> StencilOp -> Bool
    < :: StencilOp -> StencilOp -> Bool
    $c<= :: StencilOp -> StencilOp -> Bool
    <= :: StencilOp -> StencilOp -> Bool
    $c> :: StencilOp -> StencilOp -> Bool
    > :: StencilOp -> StencilOp -> Bool
    $c>= :: StencilOp -> StencilOp -> Bool
    >= :: StencilOp -> StencilOp -> Bool
    $cmax :: StencilOp -> StencilOp -> StencilOp
    max :: StencilOp -> StencilOp -> StencilOp
    $cmin :: StencilOp -> StencilOp -> StencilOp
    min :: StencilOp -> StencilOp -> StencilOp
    Ord, Int -> StencilOp -> ShowS
    [StencilOp] -> ShowS
    StencilOp -> String
    (Int -> StencilOp -> ShowS)
    -> (StencilOp -> String)
    -> ([StencilOp] -> ShowS)
    -> Show StencilOp
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> StencilOp -> ShowS
    showsPrec :: Int -> StencilOp -> ShowS
    $cshow :: StencilOp -> String
    show :: StencilOp -> String
    $cshowList :: [StencilOp] -> ShowS
    showList :: [StencilOp] -> ShowS
    Show )

    marshalStencilOp :: StencilOp -> GLenum
    marshalStencilOp :: StencilOp -> GLenum
    marshalStencilOp StencilOp
    x = case StencilOp
    x of
       StencilOp
    OpZero -> GLenum
    GL_ZERO
       StencilOp
    OpKeep -> GLenum
    GL_KEEP
       StencilOp
    OpReplace -> GLenum
    GL_REPLACE
       StencilOp
    OpIncr -> GLenum
    GL_INCR
       StencilOp
    OpIncrWrap -> GLenum
    GL_INCR_WRAP
       StencilOp
    OpDecr -> GLenum
    GL_DECR
       StencilOp
    OpDecrWrap -> GLenum
    GL_DECR_WRAP
       StencilOp
    OpInvert -> GLenum
    GL_INVERT

    unmarshalStencilOp :: GLenum -> StencilOp
    unmarshalStencilOp :: GLenum -> StencilOp
    unmarshalStencilOp GLenum
    x
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_ZERO = StencilOp
    OpZero
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_KEEP = StencilOp
    OpKeep
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_REPLACE = StencilOp
    OpReplace
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_INCR = StencilOp
    OpIncr
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_INCR_WRAP = StencilOp
    OpIncrWrap
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_DECR = StencilOp
    OpDecr
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_DECR_WRAP = StencilOp
    OpDecrWrap
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_INVERT = StencilOp
    OpInvert
       | Bool
    otherwise = String -> StencilOp
    forall a. HasCallStack => String -> a
    error (String
    "unmarshalStencilOp: illegal value " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ GLenum -> String
    forall a. Show a => a -> String
    show GLenum
    x)

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

    stencilOp :: StateVar (StencilOp, StencilOp, StencilOp)
    stencilOp :: StateVar (StencilOp, StencilOp, StencilOp)
    stencilOp =
       IO (StencilOp, StencilOp, StencilOp)
    -> ((StencilOp, StencilOp, StencilOp) -> IO ())
    -> StateVar (StencilOp, StencilOp, StencilOp)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
          (StateVar (StencilOp, StencilOp, StencilOp)
    -> IO (StencilOp, StencilOp, StencilOp)
    forall t a (m :: * -> *). (HasGetter t a, MonadIO m) => t -> m a
    forall (m :: * -> *).
    MonadIO m =>
    StateVar (StencilOp, StencilOp, StencilOp)
    -> m (StencilOp, StencilOp, StencilOp)
    get (Face -> StateVar (StencilOp, StencilOp, StencilOp)
    stencilOpSeparate Face
    Front))
          (\(StencilOp
    sf, StencilOp
    spdf, StencilOp
    spdp) -> GLenum -> GLenum -> GLenum -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLenum -> GLenum -> GLenum -> m ()
    glStencilOp (StencilOp -> GLenum
    marshalStencilOp StencilOp
    sf)
                                            (StencilOp -> GLenum
    marshalStencilOp StencilOp
    spdf)
                                            (StencilOp -> GLenum
    marshalStencilOp StencilOp
    spdp))

    stencilOpSeparate :: Face -> StateVar (StencilOp, StencilOp, StencilOp)
    stencilOpSeparate :: Face -> StateVar (StencilOp, StencilOp, StencilOp)
    stencilOpSeparate Face
    face =
       IO (StencilOp, StencilOp, StencilOp)
    -> ((StencilOp, StencilOp, StencilOp) -> IO ())
    -> StateVar (StencilOp, StencilOp, StencilOp)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
          (case Face
    face of
              Face
    Front -> PName1I
    -> PName1I -> PName1I -> IO (StencilOp, StencilOp, StencilOp)
    forall {p} {p} {p}.
    (GetPName1I p, GetPName1I p, GetPName1I p) =>
    p -> p -> p -> IO (StencilOp, StencilOp, StencilOp)
    getStencilOp PName1I
    GetStencilFail
                                    PName1I
    GetStencilPassDepthFail
                                    PName1I
    GetStencilPassDepthPass
              Face
    Back ->  PName1I
    -> PName1I -> PName1I -> IO (StencilOp, StencilOp, StencilOp)
    forall {p} {p} {p}.
    (GetPName1I p, GetPName1I p, GetPName1I p) =>
    p -> p -> p -> IO (StencilOp, StencilOp, StencilOp)
    getStencilOp PName1I
    GetStencilBackFail
                                    PName1I
    GetStencilBackPassDepthFail
                                    PName1I
    GetStencilBackPassDepthPass
              Face
    FrontAndBack -> do IO ()
    recordInvalidEnum
                                 (StencilOp, StencilOp, StencilOp)
    -> IO (StencilOp, StencilOp, StencilOp)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (StencilOp
    OpZero, StencilOp
    OpZero, StencilOp
    OpZero))
          (\(StencilOp
    sf, StencilOp
    spdf, StencilOp
    spdp) -> GLenum -> GLenum -> GLenum -> GLenum -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLenum -> GLenum -> GLenum -> GLenum -> m ()
    glStencilOpSeparate (Face -> GLenum
    marshalFace Face
    face)
                                                    (StencilOp -> GLenum
    marshalStencilOp StencilOp
    sf)
                                                    (StencilOp -> GLenum
    marshalStencilOp StencilOp
    spdf)
                                                    (StencilOp -> GLenum
    marshalStencilOp StencilOp
    spdp))
       where getStencilOp :: p -> p -> p -> IO (StencilOp, StencilOp, StencilOp)
    getStencilOp p
    sf p
    spdf p
    spdp =
                ((StencilOp
     -> StencilOp -> StencilOp -> (StencilOp, StencilOp, StencilOp))
    -> IO StencilOp
    -> IO StencilOp
    -> IO StencilOp
    -> IO (StencilOp, StencilOp, StencilOp)
    forall (m :: * -> *) a1 a2 a3 r.
    Monad m =>
    (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r
    liftM3 (,,) ((GLenum -> StencilOp) -> p -> IO StencilOp
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> p -> IO a
    getEnum1 GLenum -> StencilOp
    unmarshalStencilOp p
    sf)
                             ((GLenum -> StencilOp) -> p -> IO StencilOp
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> p -> IO a
    getEnum1 GLenum -> StencilOp
    unmarshalStencilOp p
    spdf)
                             ((GLenum -> StencilOp) -> p -> IO StencilOp
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> p -> IO a
    getEnum1 GLenum -> StencilOp
    unmarshalStencilOp p
    spdp))

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

    activeStencilFace :: StateVar (Maybe Face)
    activeStencilFace :: StateVar (Maybe Face)
    activeStencilFace =
       IO EnableCap -> IO Face -> (Face -> IO ()) -> StateVar (Maybe Face)
    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
    CapStencilTestTwoSide)
          ((GLenum -> Face) -> PName1I -> IO Face
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> PName1I -> IO a
    getEnum1 GLenum -> Face
    unmarshalFace PName1I
    GetActiveStencilFace)
          (GLenum -> IO ()
    forall (m :: * -> *). MonadIO m => GLenum -> m ()
    glActiveStencilFaceEXT (GLenum -> IO ()) -> (Face -> GLenum) -> Face -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Face -> GLenum
    marshalFace)

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

    depthFunc :: StateVar (Maybe ComparisonFunction)
    depthFunc :: StateVar (Maybe ComparisonFunction)
    depthFunc =
       IO EnableCap
    -> IO ComparisonFunction
    -> (ComparisonFunction -> IO ())
    -> StateVar (Maybe ComparisonFunction)
    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
    CapDepthTest)
          ((GLenum -> ComparisonFunction) -> PName1I -> IO ComparisonFunction
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> PName1I -> IO a
    getEnum1 GLenum -> ComparisonFunction
    unmarshalComparisonFunction PName1I
    GetDepthFunc)
          (GLenum -> IO ()
    forall (m :: * -> *). MonadIO m => GLenum -> m ()
    glDepthFunc (GLenum -> IO ())
    -> (ComparisonFunction -> GLenum) -> ComparisonFunction -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ComparisonFunction -> GLenum
    marshalComparisonFunction)

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

    blend :: StateVar Capability
    blend :: StateVar Capability
    blend = EnableCap -> StateVar Capability
    makeCapability EnableCap
    CapBlend

    -- | enable or disable blending based on the buffer bound to the /i/'th drawBuffer
    -- that is the buffer fmap (!! i) (get drawBuffers)
    blendBuffer :: DrawBufferIndex -> StateVar Capability
    blendBuffer :: GLenum -> StateVar Capability
    blendBuffer = (GLenum -> GLenum)
    -> IndexedEnableCap -> GLenum -> StateVar Capability
    forall a.
    (a -> GLenum) -> IndexedEnableCap -> a -> StateVar Capability
    makeIndexedCapability ((GLenum -> GLenum
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GLenum
    GL_DRAW_BUFFER0) GLenum -> GLenum -> GLenum
    forall a. Num a => a -> a -> a
    +) IndexedEnableCap
    BlendI

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

    data BlendEquation =
         FuncAdd
       | FuncSubtract
       | FuncReverseSubtract
       | Min
       | Max
       | LogicOp
       deriving ( BlendEquation -> BlendEquation -> Bool
    (BlendEquation -> BlendEquation -> Bool)
    -> (BlendEquation -> BlendEquation -> Bool) -> Eq BlendEquation
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: BlendEquation -> BlendEquation -> Bool
    == :: BlendEquation -> BlendEquation -> Bool
    $c/= :: BlendEquation -> BlendEquation -> Bool
    /= :: BlendEquation -> BlendEquation -> Bool
    Eq, Eq BlendEquation
    Eq BlendEquation =>
    (BlendEquation -> BlendEquation -> Ordering)
    -> (BlendEquation -> BlendEquation -> Bool)
    -> (BlendEquation -> BlendEquation -> Bool)
    -> (BlendEquation -> BlendEquation -> Bool)
    -> (BlendEquation -> BlendEquation -> Bool)
    -> (BlendEquation -> BlendEquation -> BlendEquation)
    -> (BlendEquation -> BlendEquation -> BlendEquation)
    -> Ord BlendEquation
    BlendEquation -> BlendEquation -> Bool
    BlendEquation -> BlendEquation -> Ordering
    BlendEquation -> BlendEquation -> BlendEquation
    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 :: BlendEquation -> BlendEquation -> Ordering
    compare :: BlendEquation -> BlendEquation -> Ordering
    $c< :: BlendEquation -> BlendEquation -> Bool
    < :: BlendEquation -> BlendEquation -> Bool
    $c<= :: BlendEquation -> BlendEquation -> Bool
    <= :: BlendEquation -> BlendEquation -> Bool
    $c> :: BlendEquation -> BlendEquation -> Bool
    > :: BlendEquation -> BlendEquation -> Bool
    $c>= :: BlendEquation -> BlendEquation -> Bool
    >= :: BlendEquation -> BlendEquation -> Bool
    $cmax :: BlendEquation -> BlendEquation -> BlendEquation
    max :: BlendEquation -> BlendEquation -> BlendEquation
    $cmin :: BlendEquation -> BlendEquation -> BlendEquation
    min :: BlendEquation -> BlendEquation -> BlendEquation
    Ord, Int -> BlendEquation -> ShowS
    [BlendEquation] -> ShowS
    BlendEquation -> String
    (Int -> BlendEquation -> ShowS)
    -> (BlendEquation -> String)
    -> ([BlendEquation] -> ShowS)
    -> Show BlendEquation
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> BlendEquation -> ShowS
    showsPrec :: Int -> BlendEquation -> ShowS
    $cshow :: BlendEquation -> String
    show :: BlendEquation -> String
    $cshowList :: [BlendEquation] -> ShowS
    showList :: [BlendEquation] -> ShowS
    Show )

    marshalBlendEquation :: BlendEquation -> GLenum
    marshalBlendEquation :: BlendEquation -> GLenum
    marshalBlendEquation BlendEquation
    x = case BlendEquation
    x of
       BlendEquation
    FuncAdd -> GLenum
    GL_FUNC_ADD
       BlendEquation
    FuncSubtract -> GLenum
    GL_FUNC_SUBTRACT
       BlendEquation
    FuncReverseSubtract -> GLenum
    GL_FUNC_REVERSE_SUBTRACT
       BlendEquation
    Min -> GLenum
    GL_MIN
       BlendEquation
    Max -> GLenum
    GL_MAX
       BlendEquation
    LogicOp -> GLenum
    GL_INDEX_LOGIC_OP

    unmarshalBlendEquation :: GLenum -> BlendEquation
    unmarshalBlendEquation :: GLenum -> BlendEquation
    unmarshalBlendEquation GLenum
    x
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_FUNC_ADD = BlendEquation
    FuncAdd
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_FUNC_SUBTRACT = BlendEquation
    FuncSubtract
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_FUNC_REVERSE_SUBTRACT = BlendEquation
    FuncReverseSubtract
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_MIN = BlendEquation
    Min
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_MAX = BlendEquation
    Max
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_INDEX_LOGIC_OP = BlendEquation
    LogicOp
       | Bool
    otherwise = String -> BlendEquation
    forall a. HasCallStack => String -> a
    error (String
    "unmarshalBlendEquation: illegal value " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ GLenum -> String
    forall a. Show a => a -> String
    show GLenum
    x)

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

    blendEquation :: StateVar BlendEquation
    blendEquation :: StateVar BlendEquation
    blendEquation =
       IO BlendEquation
    -> (BlendEquation -> IO ()) -> StateVar BlendEquation
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
          ((GLenum -> BlendEquation) -> PName1I -> IO BlendEquation
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> PName1I -> IO a
    getEnum1 GLenum -> BlendEquation
    unmarshalBlendEquation PName1I
    GetBlendEquation)
          (GLenum -> IO ()
    forall (m :: * -> *). MonadIO m => GLenum -> m ()
    glBlendEquation (GLenum -> IO ())
    -> (BlendEquation -> GLenum) -> BlendEquation -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . BlendEquation -> GLenum
    marshalBlendEquation)

    blendEquationSeparate :: StateVar (BlendEquation,BlendEquation)
    blendEquationSeparate :: StateVar (BlendEquation, BlendEquation)
    blendEquationSeparate =
       IO (BlendEquation, BlendEquation)
    -> ((BlendEquation, BlendEquation) -> IO ())
    -> StateVar (BlendEquation, BlendEquation)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
          ((BlendEquation -> BlendEquation -> (BlendEquation, BlendEquation))
    -> IO BlendEquation
    -> IO BlendEquation
    -> IO (BlendEquation, BlendEquation)
    forall (m :: * -> *) a1 a2 r.
    Monad m =>
    (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
    liftM2 (,) ((GLenum -> BlendEquation) -> PName1I -> IO BlendEquation
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> PName1I -> IO a
    getEnum1 GLenum -> BlendEquation
    unmarshalBlendEquation PName1I
    GetBlendEquation)
                      ((GLenum -> BlendEquation) -> PName1I -> IO BlendEquation
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> PName1I -> IO a
    getEnum1 GLenum -> BlendEquation
    unmarshalBlendEquation PName1I
    GetBlendEquationAlpha))
          (\(BlendEquation
    funcRGB, BlendEquation
    funcAlpha) ->
              GLenum -> GLenum -> IO ()
    forall (m :: * -> *). MonadIO m => GLenum -> GLenum -> m ()
    glBlendEquationSeparate (BlendEquation -> GLenum
    marshalBlendEquation BlendEquation
    funcRGB)
                                      (BlendEquation -> GLenum
    marshalBlendEquation BlendEquation
    funcAlpha))

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

    blendFuncSeparate ::
       StateVar ((BlendingFactor, BlendingFactor), (BlendingFactor, BlendingFactor))
    blendFuncSeparate :: StateVar
      ((BlendingFactor, BlendingFactor),
       (BlendingFactor, BlendingFactor))
    blendFuncSeparate =
       IO
      ((BlendingFactor, BlendingFactor),
       (BlendingFactor, BlendingFactor))
    -> (((BlendingFactor, BlendingFactor),
         (BlendingFactor, BlendingFactor))
        -> IO ())
    -> StateVar
         ((BlendingFactor, BlendingFactor),
          (BlendingFactor, BlendingFactor))
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
          (do srcRGB   <- (GLenum -> BlendingFactor) -> PName1I -> IO BlendingFactor
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> PName1I -> IO a
    getEnum1 GLenum -> BlendingFactor
    unmarshalBlendingFactor PName1I
    GetBlendSrcRGB
              srcAlpha <- getEnum1 unmarshalBlendingFactor GetBlendSrcAlpha
              dstRGB   <- getEnum1 unmarshalBlendingFactor GetBlendDstRGB
              dstAlpha <- getEnum1 unmarshalBlendingFactor GetBlendDstAlpha
              return ((srcRGB, srcAlpha), (dstRGB, dstAlpha)))
          (\((BlendingFactor
    srcRGB, BlendingFactor
    srcAlpha), (BlendingFactor
    dstRGB, BlendingFactor
    dstAlpha)) ->
             GLenum -> GLenum -> GLenum -> GLenum -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLenum -> GLenum -> GLenum -> GLenum -> m ()
    glBlendFuncSeparate (BlendingFactor -> GLenum
    marshalBlendingFactor BlendingFactor
    srcRGB)
                                 (BlendingFactor -> GLenum
    marshalBlendingFactor BlendingFactor
    srcAlpha)
                                 (BlendingFactor -> GLenum
    marshalBlendingFactor BlendingFactor
    dstRGB)
                                 (BlendingFactor -> GLenum
    marshalBlendingFactor BlendingFactor
    dstAlpha))

    blendFunc :: StateVar (BlendingFactor, BlendingFactor)
    blendFunc :: StateVar (BlendingFactor, BlendingFactor)
    blendFunc =
       IO (BlendingFactor, BlendingFactor)
    -> ((BlendingFactor, BlendingFactor) -> IO ())
    -> StateVar (BlendingFactor, BlendingFactor)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
          ((BlendingFactor
     -> BlendingFactor -> (BlendingFactor, BlendingFactor))
    -> IO BlendingFactor
    -> IO BlendingFactor
    -> IO (BlendingFactor, BlendingFactor)
    forall (m :: * -> *) a1 a2 r.
    Monad m =>
    (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
    liftM2 (,) ((GLenum -> BlendingFactor) -> PName1I -> IO BlendingFactor
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> PName1I -> IO a
    getEnum1 GLenum -> BlendingFactor
    unmarshalBlendingFactor PName1I
    GetBlendSrc)
                      ((GLenum -> BlendingFactor) -> PName1I -> IO BlendingFactor
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> PName1I -> IO a
    getEnum1 GLenum -> BlendingFactor
    unmarshalBlendingFactor PName1I
    GetBlendDst))
          (\(BlendingFactor
    s, BlendingFactor
    d) ->
             GLenum -> GLenum -> IO ()
    forall (m :: * -> *). MonadIO m => GLenum -> GLenum -> m ()
    glBlendFunc (BlendingFactor -> GLenum
    marshalBlendingFactor BlendingFactor
    s) (BlendingFactor -> GLenum
    marshalBlendingFactor BlendingFactor
    d))

    blendColor :: StateVar (Color4 GLclampf)
    blendColor :: StateVar (Color4 GLclampf)
    blendColor =
       IO (Color4 GLclampf)
    -> (Color4 GLclampf -> IO ()) -> StateVar (Color4 GLclampf)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
          ((GLclampf -> GLclampf -> GLclampf -> GLclampf -> Color4 GLclampf)
    -> PName4F -> IO (Color4 GLclampf)
    forall p a.
    GetPName4F p =>
    (GLclampf -> GLclampf -> GLclampf -> GLclampf -> a) -> p -> IO a
    forall a.
    (GLclampf -> GLclampf -> GLclampf -> GLclampf -> a)
    -> PName4F -> IO a
    getClampf4 GLclampf -> GLclampf -> GLclampf -> GLclampf -> Color4 GLclampf
    forall a. a -> a -> a -> a -> Color4 a
    Color4 PName4F
    GetBlendColor)
          (\(Color4 GLclampf
    r GLclampf
    g GLclampf
    b GLclampf
    a) -> GLclampf -> GLclampf -> GLclampf -> GLclampf -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLclampf -> GLclampf -> GLclampf -> GLclampf -> m ()
    glBlendColor GLclampf
    r GLclampf
    g GLclampf
    b GLclampf
    a)

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

    dither :: StateVar Capability
    dither :: StateVar Capability
    dither = EnableCap -> StateVar Capability
    makeCapability EnableCap
    CapDither

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

    data LogicOp =
         Clear
       | And
       | AndReverse
       | Copy
       | AndInverted
       | Noop
       | Xor
       | Or
       | Nor
       | Equiv
       | Invert
       | OrReverse
       | CopyInverted
       | OrInverted
       | Nand
       | Set
       deriving ( LogicOp -> LogicOp -> Bool
    (LogicOp -> LogicOp -> Bool)
    -> (LogicOp -> LogicOp -> Bool) -> Eq LogicOp
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: LogicOp -> LogicOp -> Bool
    == :: LogicOp -> LogicOp -> Bool
    $c/= :: LogicOp -> LogicOp -> Bool
    /= :: LogicOp -> LogicOp -> Bool
    Eq, Eq LogicOp
    Eq LogicOp =>
    (LogicOp -> LogicOp -> Ordering)
    -> (LogicOp -> LogicOp -> Bool)
    -> (LogicOp -> LogicOp -> Bool)
    -> (LogicOp -> LogicOp -> Bool)
    -> (LogicOp -> LogicOp -> Bool)
    -> (LogicOp -> LogicOp -> LogicOp)
    -> (LogicOp -> LogicOp -> LogicOp)
    -> Ord LogicOp
    LogicOp -> LogicOp -> Bool
    LogicOp -> LogicOp -> Ordering
    LogicOp -> LogicOp -> LogicOp
    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 :: LogicOp -> LogicOp -> Ordering
    compare :: LogicOp -> LogicOp -> Ordering
    $c< :: LogicOp -> LogicOp -> Bool
    < :: LogicOp -> LogicOp -> Bool
    $c<= :: LogicOp -> LogicOp -> Bool
    <= :: LogicOp -> LogicOp -> Bool
    $c> :: LogicOp -> LogicOp -> Bool
    > :: LogicOp -> LogicOp -> Bool
    $c>= :: LogicOp -> LogicOp -> Bool
    >= :: LogicOp -> LogicOp -> Bool
    $cmax :: LogicOp -> LogicOp -> LogicOp
    max :: LogicOp -> LogicOp -> LogicOp
    $cmin :: LogicOp -> LogicOp -> LogicOp
    min :: LogicOp -> LogicOp -> LogicOp
    Ord, Int -> LogicOp -> ShowS
    [LogicOp] -> ShowS
    LogicOp -> String
    (Int -> LogicOp -> ShowS)
    -> (LogicOp -> String) -> ([LogicOp] -> ShowS) -> Show LogicOp
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> LogicOp -> ShowS
    showsPrec :: Int -> LogicOp -> ShowS
    $cshow :: LogicOp -> String
    show :: LogicOp -> String
    $cshowList :: [LogicOp] -> ShowS
    showList :: [LogicOp] -> ShowS
    Show )

    marshalLogicOp :: LogicOp -> GLenum
    marshalLogicOp :: LogicOp -> GLenum
    marshalLogicOp LogicOp
    x = case LogicOp
    x of
       LogicOp
    Clear -> GLenum
    GL_CLEAR
       LogicOp
    And -> GLenum
    GL_AND
       LogicOp
    AndReverse -> GLenum
    GL_AND_REVERSE
       LogicOp
    Copy -> GLenum
    GL_COPY
       LogicOp
    AndInverted -> GLenum
    GL_AND_INVERTED
       LogicOp
    Noop -> GLenum
    GL_NOOP
       LogicOp
    Xor -> GLenum
    GL_XOR
       LogicOp
    Or -> GLenum
    GL_OR
       LogicOp
    Nor -> GLenum
    GL_NOR
       LogicOp
    Equiv -> GLenum
    GL_EQUIV
       LogicOp
    Invert -> GLenum
    GL_INVERT
       LogicOp
    OrReverse -> GLenum
    GL_OR_REVERSE
       LogicOp
    CopyInverted -> GLenum
    GL_COPY_INVERTED
       LogicOp
    OrInverted -> GLenum
    GL_OR_INVERTED
       LogicOp
    Nand -> GLenum
    GL_NAND
       LogicOp
    Set -> GLenum
    GL_SET

    unmarshalLogicOp :: GLenum -> LogicOp
    unmarshalLogicOp :: GLenum -> LogicOp
    unmarshalLogicOp GLenum
    x
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_CLEAR = LogicOp
    Clear
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_AND = LogicOp
    And
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_AND_REVERSE = LogicOp
    AndReverse
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_COPY = LogicOp
    Copy
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_AND_INVERTED = LogicOp
    AndInverted
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_NOOP = LogicOp
    Noop
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_XOR = LogicOp
    Xor
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_OR = LogicOp
    Or
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_NOR = LogicOp
    Nor
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_EQUIV = LogicOp
    Equiv
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_INVERT = LogicOp
    Invert
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_OR_REVERSE = LogicOp
    OrReverse
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_COPY_INVERTED = LogicOp
    CopyInverted
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_OR_INVERTED = LogicOp
    OrInverted
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_NAND = LogicOp
    Nand
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_SET = LogicOp
    Set
       | Bool
    otherwise = String -> LogicOp
    forall a. HasCallStack => String -> a
    error (String
    "unmarshalLogicOp: illegal value " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ GLenum -> String
    forall a. Show a => a -> String
    show GLenum
    x)

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

    logicOp :: StateVar (Maybe LogicOp)
    logicOp :: StateVar (Maybe LogicOp)
    logicOp =
       IO EnableCap
    -> IO LogicOp -> (LogicOp -> IO ()) -> StateVar (Maybe LogicOp)
    forall a.
    IO EnableCap -> IO a -> (a -> IO ()) -> StateVar (Maybe a)
    makeStateVarMaybe
          (do rgba <- GettableStateVar Bool -> GettableStateVar Bool
    forall t a (m :: * -> *). (HasGetter t a, MonadIO m) => t -> m a
    forall (m :: * -> *). MonadIO m => GettableStateVar Bool -> m Bool
    get GettableStateVar Bool
    rgbaMode
              return $ if rgba then CapColorLogicOp else CapIndexLogicOp)
          ((GLenum -> LogicOp) -> PName1I -> IO LogicOp
    forall p a. GetPName1I p => (GLenum -> a) -> p -> IO a
    forall a. (GLenum -> a) -> PName1I -> IO a
    getEnum1 GLenum -> LogicOp
    unmarshalLogicOp PName1I
    GetLogicOpMode)
          (GLenum -> IO ()
    forall (m :: * -> *). MonadIO m => GLenum -> m ()
    glLogicOp (GLenum -> IO ()) -> (LogicOp -> GLenum) -> LogicOp -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LogicOp -> GLenum
    marshalLogicOp)