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

    module Graphics.Rendering.OpenGL.GL.VertexArrays (
       -- * Describing Data for the Arrays
       NumComponents, DataType(..), Stride, VertexArrayDescriptor(..),

       -- * Specifying Data for the Arrays
       Capability(..),
       ClientArrayType(..), arrayPointer,
       InterleavedArrays(..), interleavedArrays,

       -- * Enabling Arrays
       clientState, clientActiveTexture,

       -- * Dereferencing and Rendering
       ArrayIndex, NumArrayIndices, NumIndexBlocks, NumInstances,
       BaseInstance, BaseVertex,
       arrayElement,

       drawArrays, drawArraysInstancedBaseInstance, drawArraysInstanced,
       multiDrawArrays,

       drawElements, drawElementsInstancedBaseInstance, drawElementsInstanced,
       multiDrawElements, drawRangeElements,

       drawElementsBaseVertex, drawRangeElementsBaseVertex,
       drawElementsInstancedBaseVertex, drawElementsInstancedBaseVertexBaseInstance,
       multiDrawElementsBaseVertex,

       maxElementsVertices, maxElementsIndices, lockArrays,
       primitiveRestartIndex, primitiveRestartIndexNV,

       -- * Generic Vertex Attribute Arrays
       vertexAttribPointer, vertexAttribArray,
    ) where

    import Data.StateVar
    import Foreign.Ptr ( Ptr, nullPtr )
    import Graphics.Rendering.OpenGL.GL.Capability
    import Graphics.Rendering.OpenGL.GL.DataType
    import Graphics.Rendering.OpenGL.GL.GLboolean
    import Graphics.Rendering.OpenGL.GL.PrimitiveMode
    import Graphics.Rendering.OpenGL.GL.PrimitiveModeInternal
    import Graphics.Rendering.OpenGL.GL.QueryUtils
    import Graphics.Rendering.OpenGL.GL.Texturing.TextureUnit
    import Graphics.Rendering.OpenGL.GL.VertexSpec
    import Graphics.Rendering.OpenGL.GLU.ErrorsInternal
    import Graphics.GL

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

    type NumComponents = GLint

    type Stride = GLsizei

    data VertexArrayDescriptor a =
       VertexArrayDescriptor !NumComponents !DataType !Stride !(Ptr a)
       deriving ( VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    (VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool)
    -> (VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool)
    -> Eq (VertexArrayDescriptor a)
    forall a.
    VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall a.
    VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    == :: VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    $c/= :: forall a.
    VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    /= :: VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    Eq, Eq (VertexArrayDescriptor a)
    Eq (VertexArrayDescriptor a) =>
    (VertexArrayDescriptor a -> VertexArrayDescriptor a -> Ordering)
    -> (VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool)
    -> (VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool)
    -> (VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool)
    -> (VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool)
    -> (VertexArrayDescriptor a
        -> VertexArrayDescriptor a -> VertexArrayDescriptor a)
    -> (VertexArrayDescriptor a
        -> VertexArrayDescriptor a -> VertexArrayDescriptor a)
    -> Ord (VertexArrayDescriptor a)
    VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    VertexArrayDescriptor a -> VertexArrayDescriptor a -> Ordering
    VertexArrayDescriptor a
    -> VertexArrayDescriptor a -> VertexArrayDescriptor a
    forall a. Eq (VertexArrayDescriptor a)
    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
    forall a.
    VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    forall a.
    VertexArrayDescriptor a -> VertexArrayDescriptor a -> Ordering
    forall a.
    VertexArrayDescriptor a
    -> VertexArrayDescriptor a -> VertexArrayDescriptor a
    $ccompare :: forall a.
    VertexArrayDescriptor a -> VertexArrayDescriptor a -> Ordering
    compare :: VertexArrayDescriptor a -> VertexArrayDescriptor a -> Ordering
    $c< :: forall a.
    VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    < :: VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    $c<= :: forall a.
    VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    <= :: VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    $c> :: forall a.
    VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    > :: VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    $c>= :: forall a.
    VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    >= :: VertexArrayDescriptor a -> VertexArrayDescriptor a -> Bool
    $cmax :: forall a.
    VertexArrayDescriptor a
    -> VertexArrayDescriptor a -> VertexArrayDescriptor a
    max :: VertexArrayDescriptor a
    -> VertexArrayDescriptor a -> VertexArrayDescriptor a
    $cmin :: forall a.
    VertexArrayDescriptor a
    -> VertexArrayDescriptor a -> VertexArrayDescriptor a
    min :: VertexArrayDescriptor a
    -> VertexArrayDescriptor a -> VertexArrayDescriptor a
    Ord, Int -> VertexArrayDescriptor a -> ShowS
    [VertexArrayDescriptor a] -> ShowS
    VertexArrayDescriptor a -> String
    (Int -> VertexArrayDescriptor a -> ShowS)
    -> (VertexArrayDescriptor a -> String)
    -> ([VertexArrayDescriptor a] -> ShowS)
    -> Show (VertexArrayDescriptor a)
    forall a. Int -> VertexArrayDescriptor a -> ShowS
    forall a. [VertexArrayDescriptor a] -> ShowS
    forall a. VertexArrayDescriptor a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Int -> VertexArrayDescriptor a -> ShowS
    showsPrec :: Int -> VertexArrayDescriptor a -> ShowS
    $cshow :: forall a. VertexArrayDescriptor a -> String
    show :: VertexArrayDescriptor a -> String
    $cshowList :: forall a. [VertexArrayDescriptor a] -> ShowS
    showList :: [VertexArrayDescriptor a] -> ShowS
    Show )

    noVertexArrayDescriptor :: VertexArrayDescriptor a
    noVertexArrayDescriptor :: forall a. VertexArrayDescriptor a
    noVertexArrayDescriptor = ArrayIndex
    -> DataType -> ArrayIndex -> Ptr a -> VertexArrayDescriptor a
    forall a.
    ArrayIndex
    -> DataType -> ArrayIndex -> Ptr a -> VertexArrayDescriptor a
    VertexArrayDescriptor ArrayIndex
    0 DataType
    Byte ArrayIndex
    0 Ptr a
    forall a. Ptr a
    nullPtr

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

    data ClientArrayType =
         VertexArray
       | NormalArray
       | ColorArray
       | IndexArray
       | TextureCoordArray
       | EdgeFlagArray
       | FogCoordArray
       | SecondaryColorArray
       | MatrixIndexArray
       deriving ( ClientArrayType -> ClientArrayType -> Bool
    (ClientArrayType -> ClientArrayType -> Bool)
    -> (ClientArrayType -> ClientArrayType -> Bool)
    -> Eq ClientArrayType
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ClientArrayType -> ClientArrayType -> Bool
    == :: ClientArrayType -> ClientArrayType -> Bool
    $c/= :: ClientArrayType -> ClientArrayType -> Bool
    /= :: ClientArrayType -> ClientArrayType -> Bool
    Eq, Eq ClientArrayType
    Eq ClientArrayType =>
    (ClientArrayType -> ClientArrayType -> Ordering)
    -> (ClientArrayType -> ClientArrayType -> Bool)
    -> (ClientArrayType -> ClientArrayType -> Bool)
    -> (ClientArrayType -> ClientArrayType -> Bool)
    -> (ClientArrayType -> ClientArrayType -> Bool)
    -> (ClientArrayType -> ClientArrayType -> ClientArrayType)
    -> (ClientArrayType -> ClientArrayType -> ClientArrayType)
    -> Ord ClientArrayType
    ClientArrayType -> ClientArrayType -> Bool
    ClientArrayType -> ClientArrayType -> Ordering
    ClientArrayType -> ClientArrayType -> ClientArrayType
    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 :: ClientArrayType -> ClientArrayType -> Ordering
    compare :: ClientArrayType -> ClientArrayType -> Ordering
    $c< :: ClientArrayType -> ClientArrayType -> Bool
    < :: ClientArrayType -> ClientArrayType -> Bool
    $c<= :: ClientArrayType -> ClientArrayType -> Bool
    <= :: ClientArrayType -> ClientArrayType -> Bool
    $c> :: ClientArrayType -> ClientArrayType -> Bool
    > :: ClientArrayType -> ClientArrayType -> Bool
    $c>= :: ClientArrayType -> ClientArrayType -> Bool
    >= :: ClientArrayType -> ClientArrayType -> Bool
    $cmax :: ClientArrayType -> ClientArrayType -> ClientArrayType
    max :: ClientArrayType -> ClientArrayType -> ClientArrayType
    $cmin :: ClientArrayType -> ClientArrayType -> ClientArrayType
    min :: ClientArrayType -> ClientArrayType -> ClientArrayType
    Ord, Int -> ClientArrayType -> ShowS
    [ClientArrayType] -> ShowS
    ClientArrayType -> String
    (Int -> ClientArrayType -> ShowS)
    -> (ClientArrayType -> String)
    -> ([ClientArrayType] -> ShowS)
    -> Show ClientArrayType
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ClientArrayType -> ShowS
    showsPrec :: Int -> ClientArrayType -> ShowS
    $cshow :: ClientArrayType -> String
    show :: ClientArrayType -> String
    $cshowList :: [ClientArrayType] -> ShowS
    showList :: [ClientArrayType] -> ShowS
    Show )

    marshalClientArrayType :: ClientArrayType -> GLenum
    marshalClientArrayType :: ClientArrayType -> GLuint
    marshalClientArrayType ClientArrayType
    x = case ClientArrayType
    x of
       ClientArrayType
    VertexArray -> GLuint
    GL_VERTEX_ARRAY
       ClientArrayType
    NormalArray -> GLuint
    GL_NORMAL_ARRAY
       ClientArrayType
    ColorArray -> GLuint
    GL_COLOR_ARRAY
       ClientArrayType
    IndexArray -> GLuint
    GL_INDEX_ARRAY
       ClientArrayType
    TextureCoordArray -> GLuint
    GL_TEXTURE_COORD_ARRAY
       ClientArrayType
    EdgeFlagArray -> GLuint
    GL_EDGE_FLAG_ARRAY
       ClientArrayType
    FogCoordArray -> GLuint
    GL_FOG_COORD_ARRAY
       ClientArrayType
    SecondaryColorArray -> GLuint
    GL_SECONDARY_COLOR_ARRAY
       ClientArrayType
    MatrixIndexArray -> GLuint
    GL_MATRIX_INDEX_ARRAY_ARB

    -- Hmmm...
    clientArrayTypeToEnableCap :: ClientArrayType -> EnableCap
    clientArrayTypeToEnableCap :: ClientArrayType -> EnableCap
    clientArrayTypeToEnableCap ClientArrayType
    x = case ClientArrayType
    x of
       ClientArrayType
    VertexArray -> EnableCap
    CapVertexArray
       ClientArrayType
    NormalArray -> EnableCap
    CapNormalArray
       ClientArrayType
    ColorArray -> EnableCap
    CapColorArray
       ClientArrayType
    IndexArray -> EnableCap
    CapIndexArray
       ClientArrayType
    TextureCoordArray -> EnableCap
    CapTextureCoordArray
       ClientArrayType
    EdgeFlagArray -> EnableCap
    CapEdgeFlagArray
       ClientArrayType
    FogCoordArray -> EnableCap
    CapFogCoordArray
       ClientArrayType
    SecondaryColorArray -> EnableCap
    CapSecondaryColorArray
       ClientArrayType
    MatrixIndexArray -> EnableCap
    CapMatrixIndexArray

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

    arrayPointer :: ClientArrayType -> StateVar (VertexArrayDescriptor a)
    arrayPointer :: forall a. ClientArrayType -> StateVar (VertexArrayDescriptor a)
    arrayPointer ClientArrayType
    t = case ClientArrayType
    t of
       ClientArrayType
    VertexArray -> StateVar (VertexArrayDescriptor a)
    forall a. StateVar (VertexArrayDescriptor a)
    vertexPointer
       ClientArrayType
    NormalArray -> StateVar (VertexArrayDescriptor a)
    forall a. StateVar (VertexArrayDescriptor a)
    normalPointer
       ClientArrayType
    ColorArray -> StateVar (VertexArrayDescriptor a)
    forall a. StateVar (VertexArrayDescriptor a)
    colorPointer
       ClientArrayType
    IndexArray -> StateVar (VertexArrayDescriptor a)
    forall a. StateVar (VertexArrayDescriptor a)
    indexPointer
       ClientArrayType
    TextureCoordArray -> StateVar (VertexArrayDescriptor a)
    forall a. StateVar (VertexArrayDescriptor a)
    texCoordPointer
       ClientArrayType
    EdgeFlagArray -> StateVar (VertexArrayDescriptor a)
    forall a. StateVar (VertexArrayDescriptor a)
    edgeFlagPointer
       ClientArrayType
    FogCoordArray -> StateVar (VertexArrayDescriptor a)
    forall a. StateVar (VertexArrayDescriptor a)
    fogCoordPointer
       ClientArrayType
    SecondaryColorArray -> StateVar (VertexArrayDescriptor a)
    forall a. StateVar (VertexArrayDescriptor a)
    secondaryColorPointer
       ClientArrayType
    MatrixIndexArray ->
          IO (VertexArrayDescriptor a)
    -> (VertexArrayDescriptor a -> IO ())
    -> StateVar (VertexArrayDescriptor a)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
            (do IO ()
    recordInvalidEnum ; VertexArrayDescriptor a -> IO (VertexArrayDescriptor a)
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return VertexArrayDescriptor a
    forall a. VertexArrayDescriptor a
    noVertexArrayDescriptor)
            (IO () -> VertexArrayDescriptor a -> IO ()
    forall a b. a -> b -> a
    const IO ()
    recordInvalidEnum)

    check :: Bool -> IO () -> IO ()
    check :: Bool -> IO () -> IO ()
    check Bool
    flag IO ()
    val = if Bool
    flag then IO ()
    val else IO ()
    recordInvalidValue

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

    vertexPointer :: StateVar (VertexArrayDescriptor a)
    vertexPointer :: forall a. StateVar (VertexArrayDescriptor a)
    vertexPointer = IO (VertexArrayDescriptor a)
    -> (VertexArrayDescriptor a -> IO ())
    -> StateVar (VertexArrayDescriptor a)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar IO (VertexArrayDescriptor a)
    forall a. IO (VertexArrayDescriptor a)
    getVertexPointer VertexArrayDescriptor a -> IO ()
    forall a. VertexArrayDescriptor a -> IO ()
    setVertexPointer

    getVertexPointer :: IO (VertexArrayDescriptor a)
    getVertexPointer :: forall a. IO (VertexArrayDescriptor a)
    getVertexPointer = do
       n <- (ArrayIndex -> ArrayIndex) -> PName1I -> IO ArrayIndex
    forall p a. GetPName1I p => (ArrayIndex -> a) -> p -> IO a
    forall a. (ArrayIndex -> a) -> PName1I -> IO a
    getInteger1 ArrayIndex -> ArrayIndex
    forall a. a -> a
    id PName1I
    GetVertexArraySize
       d <- getEnum1 unmarshalDataType GetVertexArrayType
       s <- getInteger1 fromIntegral GetVertexArrayStride
       p <- getPointer VertexArrayPointer
       return $ VertexArrayDescriptor n d s p

    setVertexPointer :: VertexArrayDescriptor a -> IO ()
    setVertexPointer :: forall a. VertexArrayDescriptor a -> IO ()
    setVertexPointer (VertexArrayDescriptor ArrayIndex
    n DataType
    d ArrayIndex
    s Ptr a
    p) =
       ArrayIndex -> GLuint -> ArrayIndex -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    ArrayIndex -> GLuint -> ArrayIndex -> Ptr a -> m ()
    glVertexPointer ArrayIndex
    n (DataType -> GLuint
    marshalDataType DataType
    d) ArrayIndex
    s Ptr a
    p

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

    normalPointer :: StateVar (VertexArrayDescriptor a)
    normalPointer :: forall a. StateVar (VertexArrayDescriptor a)
    normalPointer = IO (VertexArrayDescriptor a)
    -> (VertexArrayDescriptor a -> IO ())
    -> StateVar (VertexArrayDescriptor a)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar IO (VertexArrayDescriptor a)
    forall a. IO (VertexArrayDescriptor a)
    getNormalPointer VertexArrayDescriptor a -> IO ()
    forall a. VertexArrayDescriptor a -> IO ()
    setNormalPointer

    getNormalPointer :: IO (VertexArrayDescriptor a)
    getNormalPointer :: forall a. IO (VertexArrayDescriptor a)
    getNormalPointer = do
       d <- (GLuint -> DataType) -> PName1I -> IO DataType
    forall p a. GetPName1I p => (GLuint -> a) -> p -> IO a
    forall a. (GLuint -> a) -> PName1I -> IO a
    getEnum1 GLuint -> DataType
    unmarshalDataType PName1I
    GetNormalArrayType
       s <- getInteger1 fromIntegral GetNormalArrayStride
       p <- getPointer NormalArrayPointer
       return $ VertexArrayDescriptor 3 d s p

    setNormalPointer :: VertexArrayDescriptor a -> IO ()
    setNormalPointer :: forall a. VertexArrayDescriptor a -> IO ()
    setNormalPointer (VertexArrayDescriptor ArrayIndex
    n DataType
    d ArrayIndex
    s Ptr a
    p) =
       Bool -> IO () -> IO ()
    check (ArrayIndex
    n ArrayIndex -> ArrayIndex -> Bool
    forall a. Eq a => a -> a -> Bool
    == ArrayIndex
    3) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ GLuint -> ArrayIndex -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> ArrayIndex -> Ptr a -> m ()
    glNormalPointer (DataType -> GLuint
    marshalDataType DataType
    d) ArrayIndex
    s Ptr a
    p

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

    colorPointer :: StateVar (VertexArrayDescriptor a)
    colorPointer :: forall a. StateVar (VertexArrayDescriptor a)
    colorPointer = IO (VertexArrayDescriptor a)
    -> (VertexArrayDescriptor a -> IO ())
    -> StateVar (VertexArrayDescriptor a)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar IO (VertexArrayDescriptor a)
    forall a. IO (VertexArrayDescriptor a)
    getColorPointer VertexArrayDescriptor a -> IO ()
    forall a. VertexArrayDescriptor a -> IO ()
    setColorPointer

    getColorPointer :: IO (VertexArrayDescriptor a)
    getColorPointer :: forall a. IO (VertexArrayDescriptor a)
    getColorPointer = do
       n <- (ArrayIndex -> ArrayIndex) -> PName1I -> IO ArrayIndex
    forall p a. GetPName1I p => (ArrayIndex -> a) -> p -> IO a
    forall a. (ArrayIndex -> a) -> PName1I -> IO a
    getInteger1 ArrayIndex -> ArrayIndex
    forall a. a -> a
    id PName1I
    GetColorArraySize
       d <- getEnum1 unmarshalDataType GetColorArrayType
       s <- getInteger1 fromIntegral GetColorArrayStride
       p <- getPointer ColorArrayPointer
       return $ VertexArrayDescriptor n d s p

    setColorPointer :: VertexArrayDescriptor a -> IO ()
    setColorPointer :: forall a. VertexArrayDescriptor a -> IO ()
    setColorPointer (VertexArrayDescriptor ArrayIndex
    n DataType
    d ArrayIndex
    s Ptr a
    p) =
       Bool -> IO () -> IO ()
    check (ArrayIndex
    n ArrayIndex -> ArrayIndex -> Bool
    forall a. Eq a => a -> a -> Bool
    == ArrayIndex
    3 Bool -> Bool -> Bool
    || ArrayIndex
    n ArrayIndex -> ArrayIndex -> Bool
    forall a. Eq a => a -> a -> Bool
    == ArrayIndex
    4) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ ArrayIndex -> GLuint -> ArrayIndex -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    ArrayIndex -> GLuint -> ArrayIndex -> Ptr a -> m ()
    glColorPointer ArrayIndex
    n (DataType -> GLuint
    marshalDataType DataType
    d) ArrayIndex
    s Ptr a
    p

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

    indexPointer :: StateVar (VertexArrayDescriptor a)
    indexPointer :: forall a. StateVar (VertexArrayDescriptor a)
    indexPointer = IO (VertexArrayDescriptor a)
    -> (VertexArrayDescriptor a -> IO ())
    -> StateVar (VertexArrayDescriptor a)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar IO (VertexArrayDescriptor a)
    forall a. IO (VertexArrayDescriptor a)
    getIndexPointer VertexArrayDescriptor a -> IO ()
    forall a. VertexArrayDescriptor a -> IO ()
    setIndexPointer

    getIndexPointer :: IO (VertexArrayDescriptor a)
    getIndexPointer :: forall a. IO (VertexArrayDescriptor a)
    getIndexPointer = do
       d <- (GLuint -> DataType) -> PName1I -> IO DataType
    forall p a. GetPName1I p => (GLuint -> a) -> p -> IO a
    forall a. (GLuint -> a) -> PName1I -> IO a
    getEnum1 GLuint -> DataType
    unmarshalDataType PName1I
    GetIndexArrayType
       s <- getInteger1 fromIntegral GetIndexArrayStride
       p <- getPointer IndexArrayPointer
       return $ VertexArrayDescriptor 1 d s p

    setIndexPointer :: VertexArrayDescriptor a -> IO ()
    setIndexPointer :: forall a. VertexArrayDescriptor a -> IO ()
    setIndexPointer (VertexArrayDescriptor ArrayIndex
    n DataType
    d ArrayIndex
    s Ptr a
    p) =
       Bool -> IO () -> IO ()
    check (ArrayIndex
    n ArrayIndex -> ArrayIndex -> Bool
    forall a. Eq a => a -> a -> Bool
    == ArrayIndex
    1) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ GLuint -> ArrayIndex -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> ArrayIndex -> Ptr a -> m ()
    glIndexPointer (DataType -> GLuint
    marshalDataType DataType
    d) ArrayIndex
    s Ptr a
    p

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

    texCoordPointer :: StateVar (VertexArrayDescriptor a)
    texCoordPointer :: forall a. StateVar (VertexArrayDescriptor a)
    texCoordPointer = IO (VertexArrayDescriptor a)
    -> (VertexArrayDescriptor a -> IO ())
    -> StateVar (VertexArrayDescriptor a)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar IO (VertexArrayDescriptor a)
    forall a. IO (VertexArrayDescriptor a)
    getTexCoordPointer VertexArrayDescriptor a -> IO ()
    forall a. VertexArrayDescriptor a -> IO ()
    setTexCoordPointer

    getTexCoordPointer :: IO (VertexArrayDescriptor a)
    getTexCoordPointer :: forall a. IO (VertexArrayDescriptor a)
    getTexCoordPointer = do
       n <- (ArrayIndex -> ArrayIndex) -> PName1I -> IO ArrayIndex
    forall p a. GetPName1I p => (ArrayIndex -> a) -> p -> IO a
    forall a. (ArrayIndex -> a) -> PName1I -> IO a
    getInteger1 ArrayIndex -> ArrayIndex
    forall a. a -> a
    id PName1I
    GetTextureCoordArraySize
       d <- getEnum1 unmarshalDataType GetTextureCoordArrayType
       s <- getInteger1 fromIntegral GetTextureCoordArrayStride
       p <- getPointer TextureCoordArrayPointer
       return $ VertexArrayDescriptor n d s p

    setTexCoordPointer :: VertexArrayDescriptor a -> IO ()
    setTexCoordPointer :: forall a. VertexArrayDescriptor a -> IO ()
    setTexCoordPointer (VertexArrayDescriptor ArrayIndex
    n DataType
    d ArrayIndex
    s Ptr a
    p) =
       ArrayIndex -> GLuint -> ArrayIndex -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    ArrayIndex -> GLuint -> ArrayIndex -> Ptr a -> m ()
    glTexCoordPointer ArrayIndex
    n (DataType -> GLuint
    marshalDataType DataType
    d) ArrayIndex
    s Ptr a
    p

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

    edgeFlagPointer :: StateVar (VertexArrayDescriptor a)
    edgeFlagPointer :: forall a. StateVar (VertexArrayDescriptor a)
    edgeFlagPointer = IO (VertexArrayDescriptor a)
    -> (VertexArrayDescriptor a -> IO ())
    -> StateVar (VertexArrayDescriptor a)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar IO (VertexArrayDescriptor a)
    forall a. IO (VertexArrayDescriptor a)
    getEdgeFlagPointer VertexArrayDescriptor a -> IO ()
    forall a. VertexArrayDescriptor a -> IO ()
    setEdgeFlagPointer

    getEdgeFlagPointer :: IO (VertexArrayDescriptor a)
    getEdgeFlagPointer :: forall a. IO (VertexArrayDescriptor a)
    getEdgeFlagPointer = do
       s <- (ArrayIndex -> ArrayIndex) -> PName1I -> IO ArrayIndex
    forall p a. GetPName1I p => (ArrayIndex -> a) -> p -> IO a
    forall a. (ArrayIndex -> a) -> PName1I -> IO a
    getInteger1 ArrayIndex -> ArrayIndex
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral PName1I
    GetEdgeFlagArrayStride
       p <- getPointer EdgeFlagArrayPointer
       return $ VertexArrayDescriptor 1 UnsignedByte s p

    setEdgeFlagPointer :: VertexArrayDescriptor a -> IO ()
    setEdgeFlagPointer :: forall a. VertexArrayDescriptor a -> IO ()
    setEdgeFlagPointer (VertexArrayDescriptor ArrayIndex
    n DataType
    d ArrayIndex
    s Ptr a
    p) =
       Bool -> IO () -> IO ()
    check (ArrayIndex
    n ArrayIndex -> ArrayIndex -> Bool
    forall a. Eq a => a -> a -> Bool
    == ArrayIndex
    1 Bool -> Bool -> Bool
    && DataType
    d DataType -> DataType -> Bool
    forall a. Eq a => a -> a -> Bool
    == DataType
    UnsignedByte) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ ArrayIndex -> Ptr a -> IO ()
    forall (m :: * -> *) a. MonadIO m => ArrayIndex -> Ptr a -> m ()
    glEdgeFlagPointer ArrayIndex
    s Ptr a
    p

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

    fogCoordPointer :: StateVar (VertexArrayDescriptor a)
    fogCoordPointer :: forall a. StateVar (VertexArrayDescriptor a)
    fogCoordPointer = IO (VertexArrayDescriptor a)
    -> (VertexArrayDescriptor a -> IO ())
    -> StateVar (VertexArrayDescriptor a)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar IO (VertexArrayDescriptor a)
    forall a. IO (VertexArrayDescriptor a)
    getFogCoordPointer VertexArrayDescriptor a -> IO ()
    forall a. VertexArrayDescriptor a -> IO ()
    setFogCoordPointer

    getFogCoordPointer :: IO (VertexArrayDescriptor a)
    getFogCoordPointer :: forall a. IO (VertexArrayDescriptor a)
    getFogCoordPointer = do
       d <- (GLuint -> DataType) -> PName1I -> IO DataType
    forall p a. GetPName1I p => (GLuint -> a) -> p -> IO a
    forall a. (GLuint -> a) -> PName1I -> IO a
    getEnum1 GLuint -> DataType
    unmarshalDataType PName1I
    GetFogCoordArrayType
       s <- getInteger1 fromIntegral GetFogCoordArrayStride
       p <- getPointer FogCoordArrayPointer
       return $ VertexArrayDescriptor 1 d s p

    setFogCoordPointer :: VertexArrayDescriptor a -> IO ()
    setFogCoordPointer :: forall a. VertexArrayDescriptor a -> IO ()
    setFogCoordPointer (VertexArrayDescriptor ArrayIndex
    n DataType
    d ArrayIndex
    s Ptr a
    p) =
       Bool -> IO () -> IO ()
    check (ArrayIndex
    n ArrayIndex -> ArrayIndex -> Bool
    forall a. Eq a => a -> a -> Bool
    == ArrayIndex
    1) (IO () -> IO ()) -> IO () -> IO ()
    forall a b. (a -> b) -> a -> b
    $ GLuint -> ArrayIndex -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> ArrayIndex -> Ptr a -> m ()
    glFogCoordPointer (DataType -> GLuint
    marshalDataType DataType
    d) ArrayIndex
    s Ptr a
    p

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

    secondaryColorPointer :: StateVar (VertexArrayDescriptor a)
    secondaryColorPointer :: forall a. StateVar (VertexArrayDescriptor a)
    secondaryColorPointer =
       IO (VertexArrayDescriptor a)
    -> (VertexArrayDescriptor a -> IO ())
    -> StateVar (VertexArrayDescriptor a)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar IO (VertexArrayDescriptor a)
    forall a. IO (VertexArrayDescriptor a)
    getSecondaryColorPointer VertexArrayDescriptor a -> IO ()
    forall a. VertexArrayDescriptor a -> IO ()
    setSecondaryColorPointer

    getSecondaryColorPointer :: IO (VertexArrayDescriptor a)
    getSecondaryColorPointer :: forall a. IO (VertexArrayDescriptor a)
    getSecondaryColorPointer = do
       n <- (ArrayIndex -> ArrayIndex) -> PName1I -> IO ArrayIndex
    forall p a. GetPName1I p => (ArrayIndex -> a) -> p -> IO a
    forall a. (ArrayIndex -> a) -> PName1I -> IO a
    getInteger1 ArrayIndex -> ArrayIndex
    forall a. a -> a
    id PName1I
    GetSecondaryColorArraySize
       d <- getEnum1 unmarshalDataType GetSecondaryColorArrayType
       s <- getInteger1 fromIntegral GetSecondaryColorArrayStride
       p <- getPointer SecondaryColorArrayPointer
       return $ VertexArrayDescriptor n d s p

    setSecondaryColorPointer :: (VertexArrayDescriptor a) -> IO ()
    setSecondaryColorPointer :: forall a. VertexArrayDescriptor a -> IO ()
    setSecondaryColorPointer (VertexArrayDescriptor ArrayIndex
    n DataType
    d ArrayIndex
    s Ptr a
    p) =
       ArrayIndex -> GLuint -> ArrayIndex -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    ArrayIndex -> GLuint -> ArrayIndex -> Ptr a -> m ()
    glSecondaryColorPointer ArrayIndex
    n (DataType -> GLuint
    marshalDataType DataType
    d) ArrayIndex
    s Ptr a
    p

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

    data InterleavedArrays =
         V2f
       | V3f
       | C4ubV2f
       | C4ubV3f
       | C3fV3f
       | N3fV3f
       | C4fN3fV3f
       | T2fV3f
       | T4fV4f
       | T2fC4ubV3f
       | T2fC3fV3f
       | T2fN3fV3f
       | T2fC4fN3fV3f
       | T4fC4fN3fV4f
       deriving ( InterleavedArrays -> InterleavedArrays -> Bool
    (InterleavedArrays -> InterleavedArrays -> Bool)
    -> (InterleavedArrays -> InterleavedArrays -> Bool)
    -> Eq InterleavedArrays
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: InterleavedArrays -> InterleavedArrays -> Bool
    == :: InterleavedArrays -> InterleavedArrays -> Bool
    $c/= :: InterleavedArrays -> InterleavedArrays -> Bool
    /= :: InterleavedArrays -> InterleavedArrays -> Bool
    Eq, Eq InterleavedArrays
    Eq InterleavedArrays =>
    (InterleavedArrays -> InterleavedArrays -> Ordering)
    -> (InterleavedArrays -> InterleavedArrays -> Bool)
    -> (InterleavedArrays -> InterleavedArrays -> Bool)
    -> (InterleavedArrays -> InterleavedArrays -> Bool)
    -> (InterleavedArrays -> InterleavedArrays -> Bool)
    -> (InterleavedArrays -> InterleavedArrays -> InterleavedArrays)
    -> (InterleavedArrays -> InterleavedArrays -> InterleavedArrays)
    -> Ord InterleavedArrays
    InterleavedArrays -> InterleavedArrays -> Bool
    InterleavedArrays -> InterleavedArrays -> Ordering
    InterleavedArrays -> InterleavedArrays -> InterleavedArrays
    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 :: InterleavedArrays -> InterleavedArrays -> Ordering
    compare :: InterleavedArrays -> InterleavedArrays -> Ordering
    $c< :: InterleavedArrays -> InterleavedArrays -> Bool
    < :: InterleavedArrays -> InterleavedArrays -> Bool
    $c<= :: InterleavedArrays -> InterleavedArrays -> Bool
    <= :: InterleavedArrays -> InterleavedArrays -> Bool
    $c> :: InterleavedArrays -> InterleavedArrays -> Bool
    > :: InterleavedArrays -> InterleavedArrays -> Bool
    $c>= :: InterleavedArrays -> InterleavedArrays -> Bool
    >= :: InterleavedArrays -> InterleavedArrays -> Bool
    $cmax :: InterleavedArrays -> InterleavedArrays -> InterleavedArrays
    max :: InterleavedArrays -> InterleavedArrays -> InterleavedArrays
    $cmin :: InterleavedArrays -> InterleavedArrays -> InterleavedArrays
    min :: InterleavedArrays -> InterleavedArrays -> InterleavedArrays
    Ord, Int -> InterleavedArrays -> ShowS
    [InterleavedArrays] -> ShowS
    InterleavedArrays -> String
    (Int -> InterleavedArrays -> ShowS)
    -> (InterleavedArrays -> String)
    -> ([InterleavedArrays] -> ShowS)
    -> Show InterleavedArrays
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> InterleavedArrays -> ShowS
    showsPrec :: Int -> InterleavedArrays -> ShowS
    $cshow :: InterleavedArrays -> String
    show :: InterleavedArrays -> String
    $cshowList :: [InterleavedArrays] -> ShowS
    showList :: [InterleavedArrays] -> ShowS
    Show )

    marshalInterleavedArrays :: InterleavedArrays -> GLenum
    marshalInterleavedArrays :: InterleavedArrays -> GLuint
    marshalInterleavedArrays InterleavedArrays
    x = case InterleavedArrays
    x of
       InterleavedArrays
    V2f -> GLuint
    GL_V2F
       InterleavedArrays
    V3f -> GLuint
    GL_V3F
       InterleavedArrays
    C4ubV2f -> GLuint
    GL_C4UB_V2F
       InterleavedArrays
    C4ubV3f -> GLuint
    GL_C4UB_V3F
       InterleavedArrays
    C3fV3f -> GLuint
    GL_C3F_V3F
       InterleavedArrays
    N3fV3f -> GLuint
    GL_N3F_V3F
       InterleavedArrays
    C4fN3fV3f -> GLuint
    GL_C4F_N3F_V3F
       InterleavedArrays
    T2fV3f -> GLuint
    GL_T2F_V3F
       InterleavedArrays
    T4fV4f -> GLuint
    GL_T4F_V4F
       InterleavedArrays
    T2fC4ubV3f -> GLuint
    GL_T2F_C4UB_V3F
       InterleavedArrays
    T2fC3fV3f -> GLuint
    GL_T2F_C3F_V3F
       InterleavedArrays
    T2fN3fV3f -> GLuint
    GL_T2F_N3F_V3F
       InterleavedArrays
    T2fC4fN3fV3f -> GLuint
    GL_T2F_C4F_N3F_V3F
       InterleavedArrays
    T4fC4fN3fV4f -> GLuint
    GL_T4F_C4F_N3F_V4F

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

    interleavedArrays :: InterleavedArrays -> Stride -> Ptr a -> IO ()
    interleavedArrays :: forall a. InterleavedArrays -> ArrayIndex -> Ptr a -> IO ()
    interleavedArrays = GLuint -> ArrayIndex -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> ArrayIndex -> Ptr a -> m ()
    glInterleavedArrays (GLuint -> ArrayIndex -> Ptr a -> IO ())
    -> (InterleavedArrays -> GLuint)
    -> InterleavedArrays
    -> ArrayIndex
    -> Ptr a
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . InterleavedArrays -> GLuint
    marshalInterleavedArrays

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

    clientState :: ClientArrayType -> StateVar Capability
    clientState :: ClientArrayType -> StateVar Capability
    clientState ClientArrayType
    arrayType =
       IO Capability -> (Capability -> IO ()) -> StateVar Capability
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar (ClientArrayType -> IO Capability
    getClientState ClientArrayType
    arrayType) (ClientArrayType -> Capability -> IO ()
    setClientState ClientArrayType
    arrayType)

    getClientState :: ClientArrayType -> IO Capability
    getClientState :: ClientArrayType -> IO Capability
    getClientState ClientArrayType
    arrayType = 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 -> IO Capability)
    -> (ClientArrayType -> StateVar Capability)
    -> ClientArrayType
    -> IO Capability
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . EnableCap -> StateVar Capability
    makeCapability (EnableCap -> StateVar Capability)
    -> (ClientArrayType -> EnableCap)
    -> ClientArrayType
    -> StateVar Capability
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ClientArrayType -> EnableCap
    clientArrayTypeToEnableCap (ClientArrayType -> IO Capability)
    -> ClientArrayType -> IO Capability
    forall a b. (a -> b) -> a -> b
    $ ClientArrayType
    arrayType

    setClientState :: ClientArrayType -> Capability -> IO ()
    setClientState :: ClientArrayType -> Capability -> IO ()
    setClientState ClientArrayType
    arrayType Capability
    val =
       (if Capability
    val Capability -> Capability -> Bool
    forall a. Eq a => a -> a -> Bool
    == Capability
    Enabled then GLuint -> IO ()
    forall (m :: * -> *). MonadIO m => GLuint -> m ()
    glEnableClientState else GLuint -> IO ()
    forall (m :: * -> *). MonadIO m => GLuint -> m ()
    glDisableClientState)
          (ClientArrayType -> GLuint
    marshalClientArrayType ClientArrayType
    arrayType)

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

    clientActiveTexture :: StateVar TextureUnit
    clientActiveTexture :: StateVar TextureUnit
    clientActiveTexture =
       IO TextureUnit -> (TextureUnit -> IO ()) -> StateVar TextureUnit
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar ((GLuint -> TextureUnit) -> PName1I -> IO TextureUnit
    forall p a. GetPName1I p => (GLuint -> a) -> p -> IO a
    forall a. (GLuint -> a) -> PName1I -> IO a
    getEnum1 GLuint -> TextureUnit
    unmarshalTextureUnit PName1I
    GetClientActiveTexture)
                    (GLuint -> IO ()
    forall (m :: * -> *). MonadIO m => GLuint -> m ()
    glClientActiveTexture (GLuint -> IO ())
    -> (TextureUnit -> GLuint) -> TextureUnit -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . TextureUnit -> GLuint
    marshalTextureUnit)

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

    type ArrayIndex = GLint

    type NumArrayIndices = GLsizei

    type NumIndexBlocks = GLsizei

    type NumInstances = GLsizei

    type BaseInstance = GLuint

    type BaseVertex = GLint

    -- TODO: The ranges (ArrayIndex, ArrayIndex) below should actually use GLuint:
    -- type RangeStart = GLuint
    -- type RangeEnd = GLuint

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

    arrayElement :: ArrayIndex -> IO ()
    arrayElement :: ArrayIndex -> IO ()
    arrayElement = ArrayIndex -> IO ()
    forall (m :: * -> *). MonadIO m => ArrayIndex -> m ()
    glArrayElement

    drawArrays :: PrimitiveMode -> ArrayIndex -> NumArrayIndices -> IO ()
    drawArrays :: PrimitiveMode -> ArrayIndex -> ArrayIndex -> IO ()
    drawArrays = GLuint -> ArrayIndex -> ArrayIndex -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLuint -> ArrayIndex -> ArrayIndex -> m ()
    glDrawArrays (GLuint -> ArrayIndex -> ArrayIndex -> IO ())
    -> (PrimitiveMode -> GLuint)
    -> PrimitiveMode
    -> ArrayIndex
    -> ArrayIndex
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PrimitiveMode -> GLuint
    marshalPrimitiveMode

    drawArraysInstancedBaseInstance :: PrimitiveMode -> ArrayIndex -> NumArrayIndices -> NumInstances -> BaseInstance -> IO ()
    drawArraysInstancedBaseInstance :: PrimitiveMode
    -> ArrayIndex -> ArrayIndex -> ArrayIndex -> GLuint -> IO ()
    drawArraysInstancedBaseInstance = GLuint -> ArrayIndex -> ArrayIndex -> ArrayIndex -> GLuint -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLuint -> ArrayIndex -> ArrayIndex -> ArrayIndex -> GLuint -> m ()
    glDrawArraysInstancedBaseInstance (GLuint
     -> ArrayIndex -> ArrayIndex -> ArrayIndex -> GLuint -> IO ())
    -> (PrimitiveMode -> GLuint)
    -> PrimitiveMode
    -> ArrayIndex
    -> ArrayIndex
    -> ArrayIndex
    -> GLuint
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PrimitiveMode -> GLuint
    marshalPrimitiveMode

    drawArraysInstanced :: PrimitiveMode -> ArrayIndex -> NumArrayIndices -> NumInstances -> IO ()
    drawArraysInstanced :: PrimitiveMode -> ArrayIndex -> ArrayIndex -> ArrayIndex -> IO ()
    drawArraysInstanced = GLuint -> ArrayIndex -> ArrayIndex -> ArrayIndex -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLuint -> ArrayIndex -> ArrayIndex -> ArrayIndex -> m ()
    glDrawArraysInstanced (GLuint -> ArrayIndex -> ArrayIndex -> ArrayIndex -> IO ())
    -> (PrimitiveMode -> GLuint)
    -> PrimitiveMode
    -> ArrayIndex
    -> ArrayIndex
    -> ArrayIndex
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PrimitiveMode -> GLuint
    marshalPrimitiveMode

    multiDrawArrays :: PrimitiveMode -> Ptr ArrayIndex -> Ptr NumArrayIndices -> NumIndexBlocks -> IO ()
    multiDrawArrays :: PrimitiveMode
    -> Ptr ArrayIndex -> Ptr ArrayIndex -> ArrayIndex -> IO ()
    multiDrawArrays = GLuint -> Ptr ArrayIndex -> Ptr ArrayIndex -> ArrayIndex -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLuint -> Ptr ArrayIndex -> Ptr ArrayIndex -> ArrayIndex -> m ()
    glMultiDrawArrays (GLuint -> Ptr ArrayIndex -> Ptr ArrayIndex -> ArrayIndex -> IO ())
    -> (PrimitiveMode -> GLuint)
    -> PrimitiveMode
    -> Ptr ArrayIndex
    -> Ptr ArrayIndex
    -> ArrayIndex
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . PrimitiveMode -> GLuint
    marshalPrimitiveMode

    drawElements :: PrimitiveMode -> NumArrayIndices -> DataType -> Ptr a -> IO ()
    drawElements :: forall a. PrimitiveMode -> ArrayIndex -> DataType -> Ptr a -> IO ()
    drawElements PrimitiveMode
    m ArrayIndex
    c = GLuint -> ArrayIndex -> GLuint -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> ArrayIndex -> GLuint -> Ptr a -> m ()
    glDrawElements (PrimitiveMode -> GLuint
    marshalPrimitiveMode PrimitiveMode
    m) ArrayIndex
    c (GLuint -> Ptr a -> IO ())
    -> (DataType -> GLuint) -> DataType -> Ptr a -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DataType -> GLuint
    marshalDataType

    drawElementsInstancedBaseInstance :: PrimitiveMode -> NumArrayIndices -> DataType -> Ptr a -> NumInstances -> BaseInstance -> IO ()
    drawElementsInstancedBaseInstance :: forall a.
    PrimitiveMode
    -> ArrayIndex -> DataType -> Ptr a -> ArrayIndex -> GLuint -> IO ()
    drawElementsInstancedBaseInstance PrimitiveMode
    m ArrayIndex
    c = GLuint
    -> ArrayIndex -> GLuint -> Ptr a -> ArrayIndex -> GLuint -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint
    -> ArrayIndex -> GLuint -> Ptr a -> ArrayIndex -> GLuint -> m ()
    glDrawElementsInstancedBaseInstance (PrimitiveMode -> GLuint
    marshalPrimitiveMode PrimitiveMode
    m) ArrayIndex
    c (GLuint -> Ptr a -> ArrayIndex -> GLuint -> IO ())
    -> (DataType -> GLuint)
    -> DataType
    -> Ptr a
    -> ArrayIndex
    -> GLuint
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DataType -> GLuint
    marshalDataType

    drawElementsInstanced :: PrimitiveMode -> NumArrayIndices -> DataType -> Ptr a -> NumInstances -> IO ()
    drawElementsInstanced :: forall a.
    PrimitiveMode
    -> ArrayIndex -> DataType -> Ptr a -> ArrayIndex -> IO ()
    drawElementsInstanced PrimitiveMode
    m ArrayIndex
    c = GLuint -> ArrayIndex -> GLuint -> Ptr a -> ArrayIndex -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> ArrayIndex -> GLuint -> Ptr a -> ArrayIndex -> m ()
    glDrawElementsInstanced (PrimitiveMode -> GLuint
    marshalPrimitiveMode PrimitiveMode
    m) ArrayIndex
    c (GLuint -> Ptr a -> ArrayIndex -> IO ())
    -> (DataType -> GLuint) -> DataType -> Ptr a -> ArrayIndex -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DataType -> GLuint
    marshalDataType

    multiDrawElements :: PrimitiveMode -> Ptr NumArrayIndices -> DataType -> Ptr (Ptr a) -> NumIndexBlocks -> IO ()
    multiDrawElements :: forall a.
    PrimitiveMode
    -> Ptr ArrayIndex -> DataType -> Ptr (Ptr a) -> ArrayIndex -> IO ()
    multiDrawElements PrimitiveMode
    m Ptr ArrayIndex
    c = GLuint
    -> Ptr ArrayIndex -> GLuint -> Ptr (Ptr a) -> ArrayIndex -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint
    -> Ptr ArrayIndex -> GLuint -> Ptr (Ptr a) -> ArrayIndex -> m ()
    glMultiDrawElements (PrimitiveMode -> GLuint
    marshalPrimitiveMode PrimitiveMode
    m) Ptr ArrayIndex
    c (GLuint -> Ptr (Ptr a) -> ArrayIndex -> IO ())
    -> (DataType -> GLuint)
    -> DataType
    -> Ptr (Ptr a)
    -> ArrayIndex
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DataType -> GLuint
    marshalDataType

    drawRangeElements :: PrimitiveMode -> (ArrayIndex, ArrayIndex) -> NumArrayIndices -> DataType -> Ptr a -> IO ()
    drawRangeElements :: forall a.
    PrimitiveMode
    -> (ArrayIndex, ArrayIndex)
    -> ArrayIndex
    -> DataType
    -> Ptr a
    -> IO ()
    drawRangeElements PrimitiveMode
    m (ArrayIndex
    s, ArrayIndex
    e) ArrayIndex
    c = GLuint
    -> GLuint -> GLuint -> ArrayIndex -> GLuint -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> GLuint -> GLuint -> ArrayIndex -> GLuint -> Ptr a -> m ()
    glDrawRangeElements (PrimitiveMode -> GLuint
    marshalPrimitiveMode PrimitiveMode
    m) (ArrayIndex -> GLuint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral ArrayIndex
    s) (ArrayIndex -> GLuint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral ArrayIndex
    e) ArrayIndex
    c (GLuint -> Ptr a -> IO ())
    -> (DataType -> GLuint) -> DataType -> Ptr a -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DataType -> GLuint
    marshalDataType

    drawElementsBaseVertex :: PrimitiveMode -> NumArrayIndices -> DataType -> Ptr a -> BaseVertex -> IO ()
    drawElementsBaseVertex :: forall a.
    PrimitiveMode
    -> ArrayIndex -> DataType -> Ptr a -> ArrayIndex -> IO ()
    drawElementsBaseVertex PrimitiveMode
    m ArrayIndex
    c = GLuint -> ArrayIndex -> GLuint -> Ptr a -> ArrayIndex -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> ArrayIndex -> GLuint -> Ptr a -> ArrayIndex -> m ()
    glDrawElementsBaseVertex (PrimitiveMode -> GLuint
    marshalPrimitiveMode PrimitiveMode
    m) ArrayIndex
    c (GLuint -> Ptr a -> ArrayIndex -> IO ())
    -> (DataType -> GLuint) -> DataType -> Ptr a -> ArrayIndex -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DataType -> GLuint
    marshalDataType

    drawRangeElementsBaseVertex :: PrimitiveMode -> (ArrayIndex, ArrayIndex) -> NumArrayIndices -> DataType -> Ptr a -> BaseVertex -> IO ()
    drawRangeElementsBaseVertex :: forall a.
    PrimitiveMode
    -> (ArrayIndex, ArrayIndex)
    -> ArrayIndex
    -> DataType
    -> Ptr a
    -> ArrayIndex
    -> IO ()
    drawRangeElementsBaseVertex PrimitiveMode
    m (ArrayIndex
    s, ArrayIndex
    e) ArrayIndex
    c = GLuint
    -> GLuint
    -> GLuint
    -> ArrayIndex
    -> GLuint
    -> Ptr a
    -> ArrayIndex
    -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint
    -> GLuint
    -> GLuint
    -> ArrayIndex
    -> GLuint
    -> Ptr a
    -> ArrayIndex
    -> m ()
    glDrawRangeElementsBaseVertex (PrimitiveMode -> GLuint
    marshalPrimitiveMode PrimitiveMode
    m) (ArrayIndex -> GLuint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral ArrayIndex
    s) (ArrayIndex -> GLuint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral ArrayIndex
    e) ArrayIndex
    c (GLuint -> Ptr a -> ArrayIndex -> IO ())
    -> (DataType -> GLuint) -> DataType -> Ptr a -> ArrayIndex -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DataType -> GLuint
    marshalDataType

    drawElementsInstancedBaseVertex :: PrimitiveMode -> NumArrayIndices -> DataType -> Ptr a -> NumInstances -> BaseVertex -> IO ()
    drawElementsInstancedBaseVertex :: forall a.
    PrimitiveMode
    -> ArrayIndex
    -> DataType
    -> Ptr a
    -> ArrayIndex
    -> ArrayIndex
    -> IO ()
    drawElementsInstancedBaseVertex PrimitiveMode
    m ArrayIndex
    c = GLuint
    -> ArrayIndex
    -> GLuint
    -> Ptr a
    -> ArrayIndex
    -> ArrayIndex
    -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint
    -> ArrayIndex
    -> GLuint
    -> Ptr a
    -> ArrayIndex
    -> ArrayIndex
    -> m ()
    glDrawElementsInstancedBaseVertex (PrimitiveMode -> GLuint
    marshalPrimitiveMode PrimitiveMode
    m) ArrayIndex
    c (GLuint -> Ptr a -> ArrayIndex -> ArrayIndex -> IO ())
    -> (DataType -> GLuint)
    -> DataType
    -> Ptr a
    -> ArrayIndex
    -> ArrayIndex
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DataType -> GLuint
    marshalDataType

    drawElementsInstancedBaseVertexBaseInstance :: PrimitiveMode -> NumArrayIndices -> DataType -> Ptr a -> NumInstances -> BaseVertex -> BaseInstance -> IO ()
    drawElementsInstancedBaseVertexBaseInstance :: forall a.
    PrimitiveMode
    -> ArrayIndex
    -> DataType
    -> Ptr a
    -> ArrayIndex
    -> ArrayIndex
    -> GLuint
    -> IO ()
    drawElementsInstancedBaseVertexBaseInstance PrimitiveMode
    m ArrayIndex
    c = GLuint
    -> ArrayIndex
    -> GLuint
    -> Ptr a
    -> ArrayIndex
    -> ArrayIndex
    -> GLuint
    -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint
    -> ArrayIndex
    -> GLuint
    -> Ptr a
    -> ArrayIndex
    -> ArrayIndex
    -> GLuint
    -> m ()
    glDrawElementsInstancedBaseVertexBaseInstance (PrimitiveMode -> GLuint
    marshalPrimitiveMode PrimitiveMode
    m) ArrayIndex
    c (GLuint -> Ptr a -> ArrayIndex -> ArrayIndex -> GLuint -> IO ())
    -> (DataType -> GLuint)
    -> DataType
    -> Ptr a
    -> ArrayIndex
    -> ArrayIndex
    -> GLuint
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DataType -> GLuint
    marshalDataType

    multiDrawElementsBaseVertex :: PrimitiveMode -> Ptr NumArrayIndices -> DataType -> Ptr (Ptr a) -> NumIndexBlocks -> Ptr BaseVertex -> IO ()
    multiDrawElementsBaseVertex :: forall a.
    PrimitiveMode
    -> Ptr ArrayIndex
    -> DataType
    -> Ptr (Ptr a)
    -> ArrayIndex
    -> Ptr ArrayIndex
    -> IO ()
    multiDrawElementsBaseVertex PrimitiveMode
    m Ptr ArrayIndex
    c = GLuint
    -> Ptr ArrayIndex
    -> GLuint
    -> Ptr (Ptr a)
    -> ArrayIndex
    -> Ptr ArrayIndex
    -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint
    -> Ptr ArrayIndex
    -> GLuint
    -> Ptr (Ptr a)
    -> ArrayIndex
    -> Ptr ArrayIndex
    -> m ()
    glMultiDrawElementsBaseVertex (PrimitiveMode -> GLuint
    marshalPrimitiveMode PrimitiveMode
    m) Ptr ArrayIndex
    c (GLuint -> Ptr (Ptr a) -> ArrayIndex -> Ptr ArrayIndex -> IO ())
    -> (DataType -> GLuint)
    -> DataType
    -> Ptr (Ptr a)
    -> ArrayIndex
    -> Ptr ArrayIndex
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DataType -> GLuint
    marshalDataType

    maxElementsVertices :: GettableStateVar NumArrayIndices
    maxElementsVertices :: IO ArrayIndex
    maxElementsVertices = IO ArrayIndex -> IO ArrayIndex
    forall a. IO a -> IO a
    makeGettableStateVar ((ArrayIndex -> ArrayIndex) -> PName1I -> IO ArrayIndex
    forall p a. GetPName1I p => (ArrayIndex -> a) -> p -> IO a
    forall a. (ArrayIndex -> a) -> PName1I -> IO a
    getSizei1 ArrayIndex -> ArrayIndex
    forall a. a -> a
    id PName1I
    GetMaxElementsVertices)

    maxElementsIndices :: GettableStateVar NumArrayIndices
    maxElementsIndices :: IO ArrayIndex
    maxElementsIndices = IO ArrayIndex -> IO ArrayIndex
    forall a. IO a -> IO a
    makeGettableStateVar ((ArrayIndex -> ArrayIndex) -> PName1I -> IO ArrayIndex
    forall p a. GetPName1I p => (ArrayIndex -> a) -> p -> IO a
    forall a. (ArrayIndex -> a) -> PName1I -> IO a
    getSizei1 ArrayIndex -> ArrayIndex
    forall a. a -> a
    id PName1I
    GetMaxElementsIndices)

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

    lockArrays :: StateVar (Maybe (ArrayIndex, NumArrayIndices))
    lockArrays :: StateVar (Maybe (ArrayIndex, ArrayIndex))
    lockArrays = IO (Maybe (ArrayIndex, ArrayIndex))
    -> (Maybe (ArrayIndex, ArrayIndex) -> IO ())
    -> StateVar (Maybe (ArrayIndex, ArrayIndex))
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar IO (Maybe (ArrayIndex, ArrayIndex))
    getLockArrays Maybe (ArrayIndex, ArrayIndex) -> IO ()
    setLockArrays

    getLockArrays :: IO (Maybe (ArrayIndex, NumArrayIndices))
    getLockArrays :: IO (Maybe (ArrayIndex, ArrayIndex))
    getLockArrays = do
       count <- (ArrayIndex -> ArrayIndex) -> PName1I -> IO ArrayIndex
    forall p a. GetPName1I p => (ArrayIndex -> a) -> p -> IO a
    forall a. (ArrayIndex -> a) -> PName1I -> IO a
    getInteger1 ArrayIndex -> ArrayIndex
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral PName1I
    GetArrayElementLockCount
       if count > 0
          then do first <- getInteger1 id GetArrayElementLockFirst
                  return $ Just (first, count)
          else return Nothing

    setLockArrays :: Maybe (ArrayIndex, NumArrayIndices) -> IO ()
    setLockArrays :: Maybe (ArrayIndex, ArrayIndex) -> IO ()
    setLockArrays = IO ()
    -> ((ArrayIndex, ArrayIndex) -> IO ())
    -> Maybe (ArrayIndex, ArrayIndex)
    -> IO ()
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe IO ()
    forall (m :: * -> *). MonadIO m => m ()
    glUnlockArraysEXT ((ArrayIndex -> ArrayIndex -> IO ())
    -> (ArrayIndex, ArrayIndex) -> IO ()
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry ArrayIndex -> ArrayIndex -> IO ()
    forall (m :: * -> *). MonadIO m => ArrayIndex -> ArrayIndex -> m ()
    glLockArraysEXT)

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

    primitiveRestartIndex :: StateVar (Maybe ArrayIndex)
    primitiveRestartIndex :: StateVar (Maybe ArrayIndex)
    primitiveRestartIndex =
       IO EnableCap
    -> IO ArrayIndex
    -> (ArrayIndex -> IO ())
    -> StateVar (Maybe ArrayIndex)
    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
    CapPrimitiveRestart)
          ((ArrayIndex -> ArrayIndex) -> PName1I -> IO ArrayIndex
    forall p a. GetPName1I p => (ArrayIndex -> a) -> p -> IO a
    forall a. (ArrayIndex -> a) -> PName1I -> IO a
    getInteger1 ArrayIndex -> ArrayIndex
    forall a. a -> a
    id PName1I
    GetPrimitiveRestartIndex)
          (GLuint -> IO ()
    forall (m :: * -> *). MonadIO m => GLuint -> m ()
    glPrimitiveRestartIndex (GLuint -> IO ()) -> (ArrayIndex -> GLuint) -> ArrayIndex -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ArrayIndex -> GLuint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral)

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

    -- We almost could use makeStateVarMaybe below, but, alas, this is client state.

    primitiveRestartIndexNV :: StateVar (Maybe ArrayIndex)
    primitiveRestartIndexNV :: StateVar (Maybe ArrayIndex)
    primitiveRestartIndexNV =
       IO (Maybe ArrayIndex)
    -> (Maybe ArrayIndex -> IO ()) -> StateVar (Maybe ArrayIndex)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar IO (Maybe ArrayIndex)
    getPrimitiveRestartIndexNV Maybe ArrayIndex -> IO ()
    setPrimitiveRestartIndexNV

    getPrimitiveRestartIndexNV :: IO (Maybe ArrayIndex)
    getPrimitiveRestartIndexNV :: IO (Maybe ArrayIndex)
    getPrimitiveRestartIndexNV = do
       on <- (GLboolean -> Bool) -> PName1I -> IO 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
    GetPrimitiveRestartNV
       if on
          then fmap Just $ getInteger1 fromIntegral GetPrimitiveRestartIndexNV
          else return Nothing

    setPrimitiveRestartIndexNV :: Maybe ArrayIndex -> IO ()
    setPrimitiveRestartIndexNV :: Maybe ArrayIndex -> IO ()
    setPrimitiveRestartIndexNV Maybe ArrayIndex
    maybeIdx = case Maybe ArrayIndex
    maybeIdx of
       Maybe ArrayIndex
    Nothing  -> GLuint -> IO ()
    forall (m :: * -> *). MonadIO m => GLuint -> m ()
    glDisableClientState GLuint
    GL_PRIMITIVE_RESTART_NV
       Just ArrayIndex
    idx -> do GLuint -> IO ()
    forall (m :: * -> *). MonadIO m => GLuint -> m ()
    glEnableClientState GLuint
    GL_PRIMITIVE_RESTART_NV
                      GLuint -> IO ()
    forall (m :: * -> *). MonadIO m => GLuint -> m ()
    glPrimitiveRestartIndexNV (ArrayIndex -> GLuint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral ArrayIndex
    idx)

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

    vertexAttribPointer :: AttribLocation -> StateVar (IntegerHandling, VertexArrayDescriptor a)
    vertexAttribPointer :: forall a.
    AttribLocation
    -> StateVar (IntegerHandling, VertexArrayDescriptor a)
    vertexAttribPointer AttribLocation
    location =
       IO (IntegerHandling, VertexArrayDescriptor a)
    -> ((IntegerHandling, VertexArrayDescriptor a) -> IO ())
    -> StateVar (IntegerHandling, VertexArrayDescriptor a)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar (AttribLocation -> IO (IntegerHandling, VertexArrayDescriptor a)
    forall a.
    AttribLocation -> IO (IntegerHandling, VertexArrayDescriptor a)
    getVertexAttribPointer_ AttribLocation
    location) (AttribLocation
    -> (IntegerHandling, VertexArrayDescriptor a) -> IO ()
    forall a.
    AttribLocation
    -> (IntegerHandling, VertexArrayDescriptor a) -> IO ()
    setVertexAttribPointer AttribLocation
    location)

    getVertexAttribPointer_ :: AttribLocation -> IO (IntegerHandling, VertexArrayDescriptor a)
    getVertexAttribPointer_ :: forall a.
    AttribLocation -> IO (IntegerHandling, VertexArrayDescriptor a)
    getVertexAttribPointer_ AttribLocation
    location = do
       i <- (GLboolean -> Bool)
    -> AttribLocation -> GetVertexAttribPName -> IO Bool
    forall b.
    (GLboolean -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribBoolean1 GLboolean -> Bool
    forall a. (Eq a, Num a) => a -> Bool
    unmarshalGLboolean AttribLocation
    location GetVertexAttribPName
    GetVertexAttribArrayInteger
       h <- if i
               then return KeepIntegral
               else do f <- getVertexAttribBoolean1 unmarshalGLboolean location GetVertexAttribArrayNormalized
                       return $ if f then ToNormalizedFloat else ToFloat
       n <- getVertexAttribInteger1 id location GetVertexAttribArraySize
       d <- getVertexAttribEnum1 unmarshalDataType location GetVertexAttribArrayType
       s <- getVertexAttribInteger1 fromIntegral location GetVertexAttribArrayStride
       p <- getVertexAttribPointer location VertexAttribArrayPointer
       return (h, VertexArrayDescriptor n d s p)

    setVertexAttribPointer :: AttribLocation -> (IntegerHandling, VertexArrayDescriptor a) -> IO ()
    setVertexAttribPointer :: forall a.
    AttribLocation
    -> (IntegerHandling, VertexArrayDescriptor a) -> IO ()
    setVertexAttribPointer (AttribLocation GLuint
    location) (IntegerHandling
    h, VertexArrayDescriptor ArrayIndex
    n DataType
    d ArrayIndex
    s Ptr a
    p) = case IntegerHandling
    h of
       IntegerHandling
    ToFloat -> GLuint
    -> ArrayIndex
    -> GLuint
    -> GLboolean
    -> ArrayIndex
    -> Ptr a
    -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint
    -> ArrayIndex -> GLuint -> GLboolean -> ArrayIndex -> Ptr a -> m ()
    glVertexAttribPointer GLuint
    location ArrayIndex
    n GLuint
    md (Bool -> GLboolean
    forall a. Num a => Bool -> a
    marshalGLboolean Bool
    False) ArrayIndex
    s Ptr a
    p
       IntegerHandling
    ToNormalizedFloat -> GLuint
    -> ArrayIndex
    -> GLuint
    -> GLboolean
    -> ArrayIndex
    -> Ptr a
    -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint
    -> ArrayIndex -> GLuint -> GLboolean -> ArrayIndex -> Ptr a -> m ()
    glVertexAttribPointer GLuint
    location ArrayIndex
    n GLuint
    md (Bool -> GLboolean
    forall a. Num a => Bool -> a
    marshalGLboolean Bool
    True) ArrayIndex
    s Ptr a
    p
       IntegerHandling
    KeepIntegral -> GLuint -> ArrayIndex -> GLuint -> ArrayIndex -> Ptr a -> IO ()
    forall (m :: * -> *) a.
    MonadIO m =>
    GLuint -> ArrayIndex -> GLuint -> ArrayIndex -> Ptr a -> m ()
    glVertexAttribIPointer GLuint
    location ArrayIndex
    n GLuint
    md ArrayIndex
    s Ptr a
    p
      where md :: GLuint
    md = DataType -> GLuint
    marshalDataType DataType
    d

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

    vertexAttribArray :: AttribLocation -> StateVar Capability
    vertexAttribArray :: AttribLocation -> StateVar Capability
    vertexAttribArray AttribLocation
    location =
       IO Capability -> (Capability -> IO ()) -> StateVar Capability
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar (AttribLocation -> IO Capability
    getVertexAttribArray AttribLocation
    location) ((Capability -> AttribLocation -> IO ())
    -> AttribLocation -> Capability -> IO ()
    forall a b c. (a -> b -> c) -> b -> a -> c
    flip Capability -> AttribLocation -> IO ()
    setVertexAttribArray AttribLocation
    location)

    getVertexAttribArray :: AttribLocation -> IO Capability
    getVertexAttribArray :: AttribLocation -> IO Capability
    getVertexAttribArray AttribLocation
    location =
       (GLboolean -> Capability)
    -> AttribLocation -> GetVertexAttribPName -> IO Capability
    forall b.
    (GLboolean -> b) -> AttribLocation -> GetVertexAttribPName -> IO b
    getVertexAttribBoolean1 GLboolean -> Capability
    unmarshalCapability AttribLocation
    location GetVertexAttribPName
    GetVertexAttribArrayEnabled

    setVertexAttribArray :: Capability -> AttribLocation -> IO ()
    setVertexAttribArray :: Capability -> AttribLocation -> IO ()
    setVertexAttribArray Capability
    Disabled (AttribLocation GLuint
    location) = GLuint -> IO ()
    forall (m :: * -> *). MonadIO m => GLuint -> m ()
    glDisableVertexAttribArray GLuint
    location
    setVertexAttribArray Capability
    Enabled (AttribLocation GLuint
    location) = GLuint -> IO ()
    forall (m :: * -> *). MonadIO m => GLuint -> m ()
    glEnableVertexAttribArray GLuint
    location