    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.Rendering.OpenGL.GL.Shaders.ShaderObjects
    -- Copyright   :  (c) Sven Panne 2006-2019
    -- License     :  BSD3
    --
    -- Maintainer  :  Sven Panne <svenpanne@gmail.com>
    -- Stability   :  stable
    -- Portability :  portable
    --
    -- This module corresponds to section 7.1 (Shader Objects) and 7.13 (Shader,
    -- Program, and Program Pipeline Queries) of the OpenGL 4.4 spec.
    --
    -----------------------------------------------------------------------------

    module Graphics.Rendering.OpenGL.GL.Shaders.ShaderObjects (
       -- * Shader Objects
       shaderCompiler,
       ShaderType(..), Shader, createShader,
       shaderSourceBS, shaderSource, compileShader, releaseShaderCompiler,

       -- * Shader Queries
       shaderType, shaderDeleteStatus, compileStatus, shaderInfoLog,
       PrecisionType, shaderPrecisionFormat,

       -- * Bytestring utilities
       packUtf8, unpackUtf8
    ) where

    import Control.Monad
    import Data.StateVar
    import Foreign.Marshal.Alloc
    import Foreign.Marshal.Array
    import Foreign.Marshal.Utils
    import Foreign.Storable
    import Graphics.Rendering.OpenGL.GL.ByteString
    import Graphics.Rendering.OpenGL.GL.GLboolean
    import Graphics.Rendering.OpenGL.GL.PeekPoke
    import Graphics.Rendering.OpenGL.GL.QueryUtils
    import Graphics.Rendering.OpenGL.GL.Shaders.Shader
    import Graphics.GL

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

    shaderCompiler :: GettableStateVar Bool
    shaderCompiler :: GettableStateVar Bool
    shaderCompiler =
       GettableStateVar Bool -> GettableStateVar Bool
    forall a. IO a -> IO a
    makeGettableStateVar ((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
    GetShaderCompiler)

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

    data ShaderType =
         VertexShader
       | TessControlShader
       | TessEvaluationShader
       | GeometryShader
       | FragmentShader
       | ComputeShader
       deriving ( ShaderType -> ShaderType -> Bool
    (ShaderType -> ShaderType -> Bool)
    -> (ShaderType -> ShaderType -> Bool) -> Eq ShaderType
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ShaderType -> ShaderType -> Bool
    == :: ShaderType -> ShaderType -> Bool
    $c/= :: ShaderType -> ShaderType -> Bool
    /= :: ShaderType -> ShaderType -> Bool
    Eq, Eq ShaderType
    Eq ShaderType =>
    (ShaderType -> ShaderType -> Ordering)
    -> (ShaderType -> ShaderType -> Bool)
    -> (ShaderType -> ShaderType -> Bool)
    -> (ShaderType -> ShaderType -> Bool)
    -> (ShaderType -> ShaderType -> Bool)
    -> (ShaderType -> ShaderType -> ShaderType)
    -> (ShaderType -> ShaderType -> ShaderType)
    -> Ord ShaderType
    ShaderType -> ShaderType -> Bool
    ShaderType -> ShaderType -> Ordering
    ShaderType -> ShaderType -> ShaderType
    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 :: ShaderType -> ShaderType -> Ordering
    compare :: ShaderType -> ShaderType -> Ordering
    $c< :: ShaderType -> ShaderType -> Bool
    < :: ShaderType -> ShaderType -> Bool
    $c<= :: ShaderType -> ShaderType -> Bool
    <= :: ShaderType -> ShaderType -> Bool
    $c> :: ShaderType -> ShaderType -> Bool
    > :: ShaderType -> ShaderType -> Bool
    $c>= :: ShaderType -> ShaderType -> Bool
    >= :: ShaderType -> ShaderType -> Bool
    $cmax :: ShaderType -> ShaderType -> ShaderType
    max :: ShaderType -> ShaderType -> ShaderType
    $cmin :: ShaderType -> ShaderType -> ShaderType
    min :: ShaderType -> ShaderType -> ShaderType
    Ord, Int -> ShaderType -> ShowS
    [ShaderType] -> ShowS
    ShaderType -> String
    (Int -> ShaderType -> ShowS)
    -> (ShaderType -> String)
    -> ([ShaderType] -> ShowS)
    -> Show ShaderType
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ShaderType -> ShowS
    showsPrec :: Int -> ShaderType -> ShowS
    $cshow :: ShaderType -> String
    show :: ShaderType -> String
    $cshowList :: [ShaderType] -> ShowS
    showList :: [ShaderType] -> ShowS
    Show )

    marshalShaderType :: ShaderType -> GLenum
    marshalShaderType :: ShaderType -> GLenum
    marshalShaderType ShaderType
    x = case ShaderType
    x of
       ShaderType
    VertexShader -> GLenum
    GL_VERTEX_SHADER
       ShaderType
    TessControlShader -> GLenum
    GL_TESS_CONTROL_SHADER
       ShaderType
    TessEvaluationShader -> GLenum
    GL_TESS_EVALUATION_SHADER
       ShaderType
    GeometryShader -> GLenum
    GL_GEOMETRY_SHADER
       ShaderType
    FragmentShader -> GLenum
    GL_FRAGMENT_SHADER
       ShaderType
    ComputeShader -> GLenum
    GL_COMPUTE_SHADER

    unmarshalShaderType :: GLenum -> ShaderType
    unmarshalShaderType :: GLenum -> ShaderType
    unmarshalShaderType GLenum
    x
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_VERTEX_SHADER = ShaderType
    VertexShader
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_TESS_CONTROL_SHADER = ShaderType
    TessControlShader
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_TESS_EVALUATION_SHADER = ShaderType
    TessEvaluationShader
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_GEOMETRY_SHADER = ShaderType
    GeometryShader
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_FRAGMENT_SHADER = ShaderType
    FragmentShader
       | GLenum
    x GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    GL_COMPUTE_SHADER = ShaderType
    ComputeShader
       | Bool
    otherwise = String -> ShaderType
    forall a. HasCallStack => String -> a
    error (String
    "unmarshalShaderType: illegal value " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ GLenum -> String
    forall a. Show a => a -> String
    show GLenum
    x)

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

    createShader :: ShaderType -> IO Shader
    createShader :: ShaderType -> IO Shader
    createShader = (GLenum -> Shader) -> IO GLenum -> IO Shader
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap GLenum -> Shader
    Shader (IO GLenum -> IO Shader)
    -> (ShaderType -> IO GLenum) -> ShaderType -> IO Shader
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GLenum -> IO GLenum
    forall (m :: * -> *). MonadIO m => GLenum -> m GLenum
    glCreateShader (GLenum -> IO GLenum)
    -> (ShaderType -> GLenum) -> ShaderType -> IO GLenum
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ShaderType -> GLenum
    marshalShaderType

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

    -- | UTF8 encoded.
    shaderSourceBS :: Shader -> StateVar ByteString
    shaderSourceBS :: Shader -> StateVar ByteString
    shaderSourceBS Shader
    shader =
       IO ByteString -> (ByteString -> IO ()) -> StateVar ByteString
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar (Shader -> IO ByteString
    getShaderSource Shader
    shader) (Shader -> ByteString -> IO ()
    setShaderSource Shader
    shader)

    getShaderSource :: Shader -> IO ByteString
    getShaderSource :: Shader -> IO ByteString
    getShaderSource = (Shader -> GettableStateVar GLint)
    -> (Shader -> GLint -> Ptr GLint -> Ptr GLchar -> IO ())
    -> Shader
    -> IO ByteString
    forall a.
    (a -> GettableStateVar GLint)
    -> (a -> GLint -> Ptr GLint -> Ptr GLchar -> IO ())
    -> a
    -> IO ByteString
    stringQuery Shader -> GettableStateVar GLint
    shaderSourceLength (GLenum -> GLint -> Ptr GLint -> Ptr GLchar -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLenum -> GLint -> Ptr GLint -> Ptr GLchar -> m ()
    glGetShaderSource (GLenum -> GLint -> Ptr GLint -> Ptr GLchar -> IO ())
    -> (Shader -> GLenum)
    -> Shader
    -> GLint
    -> Ptr GLint
    -> Ptr GLchar
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Shader -> GLenum
    shaderID)

    shaderSourceLength :: Shader -> GettableStateVar GLsizei
    shaderSourceLength :: Shader -> GettableStateVar GLint
    shaderSourceLength = (GLint -> GLint)
    -> GetShaderPName -> Shader -> GettableStateVar GLint
    forall a.
    (GLint -> a) -> GetShaderPName -> Shader -> GettableStateVar a
    shaderVar GLint -> GLint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GetShaderPName
    ShaderSourceLength

    setShaderSource :: Shader -> ByteString -> IO ()
    setShaderSource :: Shader -> ByteString -> IO ()
    setShaderSource Shader
    shader ByteString
    src =
       ByteString -> (Ptr GLchar -> GLint -> IO ()) -> IO ()
    forall b. ByteString -> (Ptr GLchar -> GLint -> IO b) -> IO b
    withByteString ByteString
    src ((Ptr GLchar -> GLint -> IO ()) -> IO ())
    -> (Ptr GLchar -> GLint -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLchar
    srcPtr GLint
    srcLength ->
          Ptr GLchar -> (Ptr (Ptr GLchar) -> IO ()) -> IO ()
    forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
    with Ptr GLchar
    srcPtr ((Ptr (Ptr GLchar) -> IO ()) -> IO ())
    -> (Ptr (Ptr GLchar) -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr (Ptr GLchar)
    srcPtrBuf ->
             GLint -> (Ptr GLint -> IO ()) -> IO ()
    forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
    with GLint
    srcLength ((Ptr GLint -> IO ()) -> IO ()) -> (Ptr GLint -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLint
    srcLengthBuf ->
                GLenum -> GLint -> Ptr (Ptr GLchar) -> Ptr GLint -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLenum -> GLint -> Ptr (Ptr GLchar) -> Ptr GLint -> m ()
    glShaderSource (Shader -> GLenum
    shaderID Shader
    shader) GLint
    1 Ptr (Ptr GLchar)
    srcPtrBuf Ptr GLint
    srcLengthBuf

    {-# DEPRECATED shaderSource "Use a combination of 'shaderSourceBS' and 'packUtf8' or 'unpackUtf8' instead." #-}
    shaderSource :: Shader -> StateVar [String]
    shaderSource :: Shader -> StateVar [String]
    shaderSource Shader
    shader =
       IO [String] -> ([String] -> IO ()) -> StateVar [String]
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
         ((ByteString -> [String]) -> IO ByteString -> IO [String]
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ((String -> [String] -> [String]
    forall a. a -> [a] -> [a]
    :[]) (String -> [String])
    -> (ByteString -> String) -> ByteString -> [String]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> String
    unpackUtf8) (IO ByteString -> IO [String]) -> IO ByteString -> IO [String]
    forall a b. (a -> b) -> a -> b
    $ StateVar ByteString -> IO ByteString
    forall t a (m :: * -> *). (HasGetter t a, MonadIO m) => t -> m a
    forall (m :: * -> *).
    MonadIO m =>
    StateVar ByteString -> m ByteString
    get (Shader -> StateVar ByteString
    shaderSourceBS Shader
    shader))
         ((Shader -> StateVar ByteString
    shaderSourceBS Shader
    shader StateVar ByteString -> ByteString -> IO ()
    forall t a (m :: * -> *).
    (HasSetter t a, MonadIO m) =>
    t -> a -> m ()
    forall (m :: * -> *).
    MonadIO m =>
    StateVar ByteString -> ByteString -> m ()
    $=) (ByteString -> IO ())
    -> ([String] -> ByteString) -> [String] -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> ByteString
    packUtf8 (String -> ByteString)
    -> ([String] -> String) -> [String] -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [String] -> String
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat)

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

    compileShader :: Shader -> IO ()
    compileShader :: Shader -> IO ()
    compileShader = GLenum -> IO ()
    forall (m :: * -> *). MonadIO m => GLenum -> m ()
    glCompileShader (GLenum -> IO ()) -> (Shader -> GLenum) -> Shader -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Shader -> GLenum
    shaderID

    releaseShaderCompiler :: IO ()
    releaseShaderCompiler :: IO ()
    releaseShaderCompiler = IO ()
    forall (m :: * -> *). MonadIO m => m ()
    glReleaseShaderCompiler

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

    shaderType :: Shader -> GettableStateVar ShaderType
    shaderType :: Shader -> GettableStateVar ShaderType
    shaderType = (GLint -> ShaderType)
    -> GetShaderPName -> Shader -> GettableStateVar ShaderType
    forall a.
    (GLint -> a) -> GetShaderPName -> Shader -> GettableStateVar a
    shaderVar (GLenum -> ShaderType
    unmarshalShaderType (GLenum -> ShaderType) -> (GLint -> GLenum) -> GLint -> ShaderType
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GLint -> GLenum
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral) GetShaderPName
    ShaderType

    shaderDeleteStatus :: Shader -> GettableStateVar Bool
    shaderDeleteStatus :: Shader -> GettableStateVar Bool
    shaderDeleteStatus = (GLint -> Bool)
    -> GetShaderPName -> Shader -> GettableStateVar Bool
    forall a.
    (GLint -> a) -> GetShaderPName -> Shader -> GettableStateVar a
    shaderVar GLint -> Bool
    forall a. (Eq a, Num a) => a -> Bool
    unmarshalGLboolean GetShaderPName
    ShaderDeleteStatus

    compileStatus :: Shader -> GettableStateVar Bool
    compileStatus :: Shader -> GettableStateVar Bool
    compileStatus = (GLint -> Bool)
    -> GetShaderPName -> Shader -> GettableStateVar Bool
    forall a.
    (GLint -> a) -> GetShaderPName -> Shader -> GettableStateVar a
    shaderVar GLint -> Bool
    forall a. (Eq a, Num a) => a -> Bool
    unmarshalGLboolean GetShaderPName
    CompileStatus

    shaderInfoLog :: Shader -> GettableStateVar String
    shaderInfoLog :: Shader -> GettableStateVar String
    shaderInfoLog =
       GettableStateVar String -> GettableStateVar String
    forall a. IO a -> IO a
    makeGettableStateVar (GettableStateVar String -> GettableStateVar String)
    -> (Shader -> GettableStateVar String)
    -> Shader
    -> GettableStateVar String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
          (ByteString -> String) -> IO ByteString -> GettableStateVar String
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap ByteString -> String
    unpackUtf8 (IO ByteString -> GettableStateVar String)
    -> (Shader -> IO ByteString) -> Shader -> GettableStateVar String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .
             (Shader -> GettableStateVar GLint)
    -> (Shader -> GLint -> Ptr GLint -> Ptr GLchar -> IO ())
    -> Shader
    -> IO ByteString
    forall a.
    (a -> GettableStateVar GLint)
    -> (a -> GLint -> Ptr GLint -> Ptr GLchar -> IO ())
    -> a
    -> IO ByteString
    stringQuery Shader -> GettableStateVar GLint
    shaderInfoLogLength (GLenum -> GLint -> Ptr GLint -> Ptr GLchar -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLenum -> GLint -> Ptr GLint -> Ptr GLchar -> m ()
    glGetShaderInfoLog (GLenum -> GLint -> Ptr GLint -> Ptr GLchar -> IO ())
    -> (Shader -> GLenum)
    -> Shader
    -> GLint
    -> Ptr GLint
    -> Ptr GLchar
    -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Shader -> GLenum
    shaderID)

    shaderInfoLogLength :: Shader -> GettableStateVar GLsizei
    shaderInfoLogLength :: Shader -> GettableStateVar GLint
    shaderInfoLogLength = (GLint -> GLint)
    -> GetShaderPName -> Shader -> GettableStateVar GLint
    forall a.
    (GLint -> a) -> GetShaderPName -> Shader -> GettableStateVar a
    shaderVar GLint -> GLint
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral GetShaderPName
    ShaderInfoLogLength

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

    data GetShaderPName =
         ShaderDeleteStatus
       | CompileStatus
       | ShaderInfoLogLength
       | ShaderSourceLength
       | ShaderType

    marshalGetShaderPName :: GetShaderPName -> GLenum
    marshalGetShaderPName :: GetShaderPName -> GLenum
    marshalGetShaderPName GetShaderPName
    x = case GetShaderPName
    x of
       GetShaderPName
    ShaderDeleteStatus -> GLenum
    GL_DELETE_STATUS
       GetShaderPName
    CompileStatus -> GLenum
    GL_COMPILE_STATUS
       GetShaderPName
    ShaderInfoLogLength -> GLenum
    GL_INFO_LOG_LENGTH
       GetShaderPName
    ShaderSourceLength -> GLenum
    GL_SHADER_SOURCE_LENGTH
       GetShaderPName
    ShaderType -> GLenum
    GL_SHADER_TYPE

    shaderVar :: (GLint -> a) -> GetShaderPName -> Shader -> GettableStateVar a
    shaderVar :: forall a.
    (GLint -> a) -> GetShaderPName -> Shader -> GettableStateVar a
    shaderVar GLint -> a
    f GetShaderPName
    p Shader
    shader =
       IO a -> IO a
    forall a. IO a -> IO a
    makeGettableStateVar (IO a -> IO a) -> IO a -> IO a
    forall a b. (a -> b) -> a -> b
    $
          GLint -> (Ptr GLint -> IO a) -> IO a
    forall a b. Storable a => a -> (Ptr a -> IO b) -> IO b
    with GLint
    0 ((Ptr GLint -> IO a) -> IO a) -> (Ptr GLint -> IO a) -> IO a
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLint
    buf -> do
             GLenum -> GLenum -> Ptr GLint -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLenum -> GLenum -> Ptr GLint -> m ()
    glGetShaderiv (Shader -> GLenum
    shaderID Shader
    shader) (GetShaderPName -> GLenum
    marshalGetShaderPName GetShaderPName
    p) Ptr GLint
    buf
             (GLint -> a) -> Ptr GLint -> IO a
    forall a b. Storable a => (a -> b) -> Ptr a -> IO b
    peek1 GLint -> a
    f Ptr GLint
    buf

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

    data PrecisionType =
         LowFloat
       | MediumFloat
       | HighFloat
       | LowInt
       | MediumInt
       | HighInt
       deriving ( PrecisionType -> PrecisionType -> Bool
    (PrecisionType -> PrecisionType -> Bool)
    -> (PrecisionType -> PrecisionType -> Bool) -> Eq PrecisionType
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PrecisionType -> PrecisionType -> Bool
    == :: PrecisionType -> PrecisionType -> Bool
    $c/= :: PrecisionType -> PrecisionType -> Bool
    /= :: PrecisionType -> PrecisionType -> Bool
    Eq, Eq PrecisionType
    Eq PrecisionType =>
    (PrecisionType -> PrecisionType -> Ordering)
    -> (PrecisionType -> PrecisionType -> Bool)
    -> (PrecisionType -> PrecisionType -> Bool)
    -> (PrecisionType -> PrecisionType -> Bool)
    -> (PrecisionType -> PrecisionType -> Bool)
    -> (PrecisionType -> PrecisionType -> PrecisionType)
    -> (PrecisionType -> PrecisionType -> PrecisionType)
    -> Ord PrecisionType
    PrecisionType -> PrecisionType -> Bool
    PrecisionType -> PrecisionType -> Ordering
    PrecisionType -> PrecisionType -> PrecisionType
    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 :: PrecisionType -> PrecisionType -> Ordering
    compare :: PrecisionType -> PrecisionType -> Ordering
    $c< :: PrecisionType -> PrecisionType -> Bool
    < :: PrecisionType -> PrecisionType -> Bool
    $c<= :: PrecisionType -> PrecisionType -> Bool
    <= :: PrecisionType -> PrecisionType -> Bool
    $c> :: PrecisionType -> PrecisionType -> Bool
    > :: PrecisionType -> PrecisionType -> Bool
    $c>= :: PrecisionType -> PrecisionType -> Bool
    >= :: PrecisionType -> PrecisionType -> Bool
    $cmax :: PrecisionType -> PrecisionType -> PrecisionType
    max :: PrecisionType -> PrecisionType -> PrecisionType
    $cmin :: PrecisionType -> PrecisionType -> PrecisionType
    min :: PrecisionType -> PrecisionType -> PrecisionType
    Ord, Int -> PrecisionType -> ShowS
    [PrecisionType] -> ShowS
    PrecisionType -> String
    (Int -> PrecisionType -> ShowS)
    -> (PrecisionType -> String)
    -> ([PrecisionType] -> ShowS)
    -> Show PrecisionType
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PrecisionType -> ShowS
    showsPrec :: Int -> PrecisionType -> ShowS
    $cshow :: PrecisionType -> String
    show :: PrecisionType -> String
    $cshowList :: [PrecisionType] -> ShowS
    showList :: [PrecisionType] -> ShowS
    Show )

    marshalPrecisionType :: PrecisionType -> GLenum
    marshalPrecisionType :: PrecisionType -> GLenum
    marshalPrecisionType PrecisionType
    x = case PrecisionType
    x of
       PrecisionType
    LowFloat -> GLenum
    GL_LOW_FLOAT
       PrecisionType
    MediumFloat -> GLenum
    GL_MEDIUM_FLOAT
       PrecisionType
    HighFloat -> GLenum
    GL_HIGH_FLOAT
       PrecisionType
    LowInt -> GLenum
    GL_LOW_INT
       PrecisionType
    MediumInt -> GLenum
    GL_MEDIUM_INT
       PrecisionType
    HighInt -> GLenum
    GL_HIGH_INT

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

    shaderPrecisionFormat :: ShaderType
                          -> PrecisionType
                          -> GettableStateVar ((GLint,GLint),GLint)
    shaderPrecisionFormat :: ShaderType
    -> PrecisionType -> GettableStateVar ((GLint, GLint), GLint)
    shaderPrecisionFormat ShaderType
    st PrecisionType
    pt =
       GettableStateVar ((GLint, GLint), GLint)
    -> GettableStateVar ((GLint, GLint), GLint)
    forall a. IO a -> IO a
    makeGettableStateVar (GettableStateVar ((GLint, GLint), GLint)
     -> GettableStateVar ((GLint, GLint), GLint))
    -> GettableStateVar ((GLint, GLint), GLint)
    -> GettableStateVar ((GLint, GLint), GLint)
    forall a b. (a -> b) -> a -> b
    $
          Int
    -> (Ptr GLint -> GettableStateVar ((GLint, GLint), GLint))
    -> GettableStateVar ((GLint, GLint), GLint)
    forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
    allocaArray Int
    2 ((Ptr GLint -> GettableStateVar ((GLint, GLint), GLint))
     -> GettableStateVar ((GLint, GLint), GLint))
    -> (Ptr GLint -> GettableStateVar ((GLint, GLint), GLint))
    -> GettableStateVar ((GLint, GLint), GLint)
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLint
    rangeBuf ->
             (Ptr GLint -> GettableStateVar ((GLint, GLint), GLint))
    -> GettableStateVar ((GLint, GLint), GLint)
    forall a b. Storable a => (Ptr a -> IO b) -> IO b
    alloca ((Ptr GLint -> GettableStateVar ((GLint, GLint), GLint))
     -> GettableStateVar ((GLint, GLint), GLint))
    -> (Ptr GLint -> GettableStateVar ((GLint, GLint), GLint))
    -> GettableStateVar ((GLint, GLint), GLint)
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLint
    precisionBuf -> do
                GLenum -> GLenum -> Ptr GLint -> Ptr GLint -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLenum -> GLenum -> Ptr GLint -> Ptr GLint -> m ()
    glGetShaderPrecisionFormat (ShaderType -> GLenum
    marshalShaderType ShaderType
    st)
                                           (PrecisionType -> GLenum
    marshalPrecisionType PrecisionType
    pt)
                                           Ptr GLint
    rangeBuf
                                           Ptr GLint
    precisionBuf
                ((GLint, GLint) -> GLint -> ((GLint, GLint), GLint))
    -> IO (GLint, GLint)
    -> GettableStateVar GLint
    -> GettableStateVar ((GLint, GLint), GLint)
    forall (m :: * -> *) a1 a2 r.
    Monad m =>
    (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
    liftM2 (,) ((GLint -> GLint -> (GLint, GLint))
    -> Ptr GLint -> IO (GLint, GLint)
    forall a b. Storable a => (a -> a -> b) -> Ptr a -> IO b
    peek2 (,) Ptr GLint
    rangeBuf) (Ptr GLint -> GettableStateVar GLint
    forall a. Storable a => Ptr a -> IO a
    peek Ptr GLint
    precisionBuf)