    {-# OPTIONS_HADDOCK hide #-}
    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.Rendering.OpenGL.GL.QueryUtils.VertexAttrib
    -- Copyright   :  (c) Sven Panne 2009-2019, Lars Corbijn 2009-2016
    -- License     :  BSD3
    --
    -- Maintainer  :  Sven Panne <svenpanne@gmail.com>, Jason Dagit <dagitj@gmail.com>
    -- Stability   :  stable
    -- Portability :  portable
    --
    -----------------------------------------------------------------------------

    module Graphics.Rendering.OpenGL.GL.QueryUtils.VertexAttrib (
        AttribLocation(..), GetVertexAttribPName(..),
        getVertexAttribInteger1, getVertexAttribEnum1, getVertexAttribBoolean1,
        getVertexAttribFloat4, getVertexAttribIInteger4, getVertexAttribIuInteger4,
        GetVertexAttribPointerPName(..), getVertexAttribPointer
    ) where

    import Foreign.Marshal.Alloc
    import Foreign.Marshal.Utils
    import Foreign.Ptr
    import Foreign.Storable
    import Graphics.Rendering.OpenGL.GL.PeekPoke
    import Graphics.GL

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

    newtype AttribLocation = AttribLocation GLuint
       deriving ( AttribLocation -> AttribLocation -> Bool
    (AttribLocation -> AttribLocation -> Bool)
    -> (AttribLocation -> AttribLocation -> Bool) -> Eq AttribLocation
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: AttribLocation -> AttribLocation -> Bool
    == :: AttribLocation -> AttribLocation -> Bool
    $c/= :: AttribLocation -> AttribLocation -> Bool
    /= :: AttribLocation -> AttribLocation -> Bool
    Eq, Eq AttribLocation
    Eq AttribLocation =>
    (AttribLocation -> AttribLocation -> Ordering)
    -> (AttribLocation -> AttribLocation -> Bool)
    -> (AttribLocation -> AttribLocation -> Bool)
    -> (AttribLocation -> AttribLocation -> Bool)
    -> (AttribLocation -> AttribLocation -> Bool)
    -> (AttribLocation -> AttribLocation -> AttribLocation)
    -> (AttribLocation -> AttribLocation -> AttribLocation)
    -> Ord AttribLocation
    AttribLocation -> AttribLocation -> Bool
    AttribLocation -> AttribLocation -> Ordering
    AttribLocation -> AttribLocation -> AttribLocation
    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 :: AttribLocation -> AttribLocation -> Ordering
    compare :: AttribLocation -> AttribLocation -> Ordering
    $c< :: AttribLocation -> AttribLocation -> Bool
    < :: AttribLocation -> AttribLocation -> Bool
    $c<= :: AttribLocation -> AttribLocation -> Bool
    <= :: AttribLocation -> AttribLocation -> Bool
    $c> :: AttribLocation -> AttribLocation -> Bool
    > :: AttribLocation -> AttribLocation -> Bool
    $c>= :: AttribLocation -> AttribLocation -> Bool
    >= :: AttribLocation -> AttribLocation -> Bool
    $cmax :: AttribLocation -> AttribLocation -> AttribLocation
    max :: AttribLocation -> AttribLocation -> AttribLocation
    $cmin :: AttribLocation -> AttribLocation -> AttribLocation
    min :: AttribLocation -> AttribLocation -> AttribLocation
    Ord, Int -> AttribLocation -> ShowS
    [AttribLocation] -> ShowS
    AttribLocation -> String
    (Int -> AttribLocation -> ShowS)
    -> (AttribLocation -> String)
    -> ([AttribLocation] -> ShowS)
    -> Show AttribLocation
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> AttribLocation -> ShowS
    showsPrec :: Int -> AttribLocation -> ShowS
    $cshow :: AttribLocation -> String
    show :: AttribLocation -> String
    $cshowList :: [AttribLocation] -> ShowS
    showList :: [AttribLocation] -> ShowS
    Show )

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

    data GetVertexAttribPName =
         GetVertexAttribArrayEnabled
       | GetVertexAttribArraySize
       | GetVertexAttribArrayStride
       | GetVertexAttribArrayType
       | GetVertexAttribArrayNormalized
       | GetCurrentVertexAttrib
       | GetVertexAttribArrayBufferBinding
       | GetVertexAttribArrayInteger

    marshalGetVertexAttribPName :: GetVertexAttribPName -> GLenum
    marshalGetVertexAttribPName :: GetVertexAttribPName -> GLuint
    marshalGetVertexAttribPName GetVertexAttribPName
    x = case GetVertexAttribPName
    x of
       GetVertexAttribPName
    GetVertexAttribArrayEnabled -> GLuint
    GL_VERTEX_ATTRIB_ARRAY_ENABLED
       GetVertexAttribPName
    GetVertexAttribArraySize -> GLuint
    GL_VERTEX_ATTRIB_ARRAY_SIZE
       GetVertexAttribPName
    GetVertexAttribArrayStride -> GLuint
    GL_VERTEX_ATTRIB_ARRAY_STRIDE
       GetVertexAttribPName
    GetVertexAttribArrayType -> GLuint
    GL_VERTEX_ATTRIB_ARRAY_TYPE
       GetVertexAttribPName
    GetVertexAttribArrayNormalized -> GLuint
    GL_VERTEX_ATTRIB_ARRAY_NORMALIZED
       GetVertexAttribPName
    GetCurrentVertexAttrib -> GLuint
    GL_CURRENT_VERTEX_ATTRIB
       GetVertexAttribPName
    GetVertexAttribArrayBufferBinding -> GLuint
    GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
       GetVertexAttribPName
    GetVertexAttribArrayInteger -> GLuint
    GL_VERTEX_ATTRIB_ARRAY_INTEGER

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

    getVertexAttribInteger1 :: (GLint -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribInteger1 :: forall b.
    (GLint -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribInteger1 GLint -> b
    f (AttribLocation GLuint
    location) GetVertexAttribPName
    n = GLint -> (Ptr GLint -> IO b) -> IO b
    forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
    with GLint
    0 ((Ptr GLint -> IO b) -> IO b) -> (Ptr GLint -> IO b) -> IO b
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLint
    buf -> do
       GLuint -> GLuint -> Ptr GLint -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLuint -> GLuint -> Ptr GLint -> m ()
    glGetVertexAttribiv GLuint
    location (GetVertexAttribPName -> GLuint
    marshalGetVertexAttribPName GetVertexAttribPName
    n) Ptr GLint
    buf
       (GLint -> b) -> Ptr GLint -> IO b
    forall a b. Storable a => (a -> b) -> Ptr a -> IO b
    peek1 GLint -> b
    f Ptr GLint
    buf

    getVertexAttribEnum1 :: (GLenum -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribEnum1 :: forall b.
    (GLuint -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribEnum1 GLuint -> b
    f = (GLint -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    forall b.
    (GLint -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribInteger1 (GLuint -> b
    f (GLuint -> b) -> (GLint -> GLuint) -> GLint -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GLint -> GLuint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral)

    getVertexAttribBoolean1 :: (GLboolean -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribBoolean1 :: forall b.
    (GLboolean -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribBoolean1 GLboolean -> b
    f = (GLint -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    forall b.
    (GLint -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribInteger1 (GLboolean -> b
    f (GLboolean -> b) -> (GLint -> GLboolean) -> GLint -> b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GLint -> GLboolean
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral)

    getVertexAttribFloat4 :: (GLfloat -> GLfloat -> GLfloat -> GLfloat -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribFloat4 :: forall b.
    (GLfloat -> GLfloat -> GLfloat -> GLfloat -> b)
    -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribFloat4 GLfloat -> GLfloat -> GLfloat -> GLfloat -> b
    f (AttribLocation GLuint
    location) GetVertexAttribPName
    n = (Ptr GLfloat -> IO b) -> IO b
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    alloca ((Ptr GLfloat -> IO b) -> IO b) -> (Ptr GLfloat -> IO b) -> IO b
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLfloat
    buf -> do
       GLuint -> GLuint -> Ptr GLfloat -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLuint -> GLuint -> Ptr GLfloat -> m ()
    glGetVertexAttribfv GLuint
    location (GetVertexAttribPName -> GLuint
    marshalGetVertexAttribPName GetVertexAttribPName
    n) Ptr GLfloat
    buf
       (GLfloat -> GLfloat -> GLfloat -> GLfloat -> b)
    -> Ptr GLfloat -> IO b
    forall a b. Storable a => (a -> a -> a -> a -> b) -> Ptr a -> IO b
    peek4 GLfloat -> GLfloat -> GLfloat -> GLfloat -> b
    f Ptr GLfloat
    buf

    getVertexAttribIInteger4 :: (GLint -> GLint -> GLint -> GLint -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribIInteger4 :: forall b.
    (GLint -> GLint -> GLint -> GLint -> b)
    -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribIInteger4 GLint -> GLint -> GLint -> GLint -> b
    f (AttribLocation GLuint
    location) GetVertexAttribPName
    n = (Ptr GLint -> IO b) -> IO b
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    alloca ((Ptr GLint -> IO b) -> IO b) -> (Ptr GLint -> IO b) -> IO b
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLint
    buf -> do
       GLuint -> GLuint -> Ptr GLint -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLuint -> GLuint -> Ptr GLint -> m ()
    glGetVertexAttribIiv GLuint
    location (GetVertexAttribPName -> GLuint
    marshalGetVertexAttribPName GetVertexAttribPName
    n) Ptr GLint
    buf
       (GLint -> GLint -> GLint -> GLint -> b) -> Ptr GLint -> IO b
    forall a b. Storable a => (a -> a -> a -> a -> b) -> Ptr a -> IO b
    peek4 GLint -> GLint -> GLint -> GLint -> b
    f Ptr GLint
    buf

    getVertexAttribIuInteger4 :: (GLuint -> GLuint -> GLuint -> GLuint -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribIuInteger4 :: forall b.
    (GLuint -> GLuint -> GLuint -> GLuint -> b)
    -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribIuInteger4 GLuint -> GLuint -> GLuint -> GLuint -> b
    f (AttribLocation GLuint
    location) GetVertexAttribPName
    n = (Ptr GLuint -> IO b) -> IO b
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    alloca ((Ptr GLuint -> IO b) -> IO b) -> (Ptr GLuint -> IO b) -> IO b
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLuint
    buf -> do
       GLuint -> GLuint -> Ptr GLuint -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLuint -> GLuint -> Ptr GLuint -> m ()
    glGetVertexAttribIuiv GLuint
    location (GetVertexAttribPName -> GLuint
    marshalGetVertexAttribPName GetVertexAttribPName
    n) Ptr GLuint
    buf
       (GLuint -> GLuint -> GLuint -> GLuint -> b) -> Ptr GLuint -> IO b
    forall a b. Storable a => (a -> a -> a -> a -> b) -> Ptr a -> IO b
    peek4 GLuint -> GLuint -> GLuint -> GLuint -> b
    f Ptr GLuint
    buf

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

    data GetVertexAttribPointerPName =
       VertexAttribArrayPointer

    marshalGetVertexAttribPointerPName :: GetVertexAttribPointerPName -> GLenum
    marshalGetVertexAttribPointerPName :: GetVertexAttribPointerPName -> GLuint
    marshalGetVertexAttribPointerPName GetVertexAttribPointerPName
    x = case GetVertexAttribPointerPName
    x of
       GetVertexAttribPointerPName
    VertexAttribArrayPointer -> GLuint
    GL_VERTEX_ATTRIB_ARRAY_POINTER

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

    getVertexAttribPointer :: AttribLocation -> GetVertexAttribPointerPName -> IO (Ptr a)
    getVertexAttribPointer :: forall a.
    AttribLocation -> GetVertexAttribPointerPName -> IO (Ptr a)
    getVertexAttribPointer (AttribLocation GLuint
    location) GetVertexAttribPointerPName
    n = Ptr a -> (Ptr (Ptr a) -> IO (Ptr a)) -> IO (Ptr a)
    forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
    with Ptr a
    forall a. Ptr a
    nullPtr ((Ptr (Ptr a) -> IO (Ptr a)) -> IO (Ptr a))
    -> (Ptr (Ptr a) -> IO (Ptr a)) -> IO (Ptr a)
    forall a b. (a -> b) -> a -> b
    $ \Ptr (Ptr a)
    buf -> do
       GLuint -> GLuint -> Ptr (Ptr a) -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> GLuint -> Ptr (Ptr a) -> m ()
    glGetVertexAttribPointerv GLuint
    location (GetVertexAttribPointerPName -> GLuint
    marshalGetVertexAttribPointerPName GetVertexAttribPointerPName
    n) Ptr (Ptr a)
    buf
       Ptr (Ptr a) -> IO (Ptr a)
    forall a. Storable a => Ptr a -> IO a
    peek Ptr (Ptr a)
    buf