    --------------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.Rendering.OpenGL.GL.PrimitiveMode
    -- Copyright   :  (c) Sven Panne 2002-2019, Tobias Markus 2016
    -- License     :  BSD3
    --
    -- Maintainer  :  Sven Panne <svenpanne@gmail.com>
    -- Stability   :  stable
    -- Portability :  portable
    --
    -- This module corresponds to section 10.1 (Primitive Types) of the OpenGL 4.4
    -- specs.
    --
    --------------------------------------------------------------------------------

    module Graphics.Rendering.OpenGL.GL.PrimitiveMode (
       -- * Primitive Modes
       PrimitiveMode(..),
       -- * Patches (Tessellation)
       patchVertices, maxPatchVertices,
       patchDefaultOuterLevel, patchDefaultInnerLevel, maxTessGenLevel
    ) where

    import Data.StateVar
    import Foreign.Marshal.Array
    import Graphics.Rendering.OpenGL.GL.PeekPoke
    import Graphics.Rendering.OpenGL.GL.QueryUtils.PName
    import Graphics.GL

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

    -- | Specification of the way the vertices given during 'renderPrimitive' are
    -- interpreted. In the description of the constructors, /n/ is an integer count
    -- starting at one, and /N/ is the total number of vertices specified.

    data PrimitiveMode =
         Points
         -- ^ Treats each vertex as a single point. Vertex /n/ defines point /n/.
         -- /N/ points are drawn.
       | Lines
         -- ^ Treats each pair of vertices as an independent line segment. Vertices
         -- 2/n/-1 and 2/n/ define line /n/. /N/\/2 lines are drawn.
       | LineLoop
         -- ^ Draws a connected group of line segments from the first vertex to the
         -- last, then back to the first. Vertices /n/ and /n/+1 define line /n/.
         -- The last line, however, is defined by vertices /N/ and 1. /N/ lines
         -- are drawn.
       | LineStrip
         -- ^ Draws a connected group of line  segments from the first vertex to the
         -- last. Vertices /n/ and /n/+1 define line /n/. /N/-1 lines are drawn.
       | Triangles
         -- ^ Treats each triplet of vertices as an independent triangle. Vertices
         -- /3n-2/, /3n-1/, and /3n/ define triangle /n/. /N\/3/ triangles are drawn.
       | TriangleStrip
         -- ^ Draws a connected group of triangles. One triangle is defined for each
         -- vertex presented after the first two vertices. For odd /n/, vertices
         -- /n/, /n/+1, and /n/+2 define triangle /n/. For even /n/, vertices /n/+1,
         -- /n/, and /n/+2 define triangle /n/. /N/-2 triangles are drawn.
       | TriangleFan
         -- ^ Draws a connected group of triangles. One triangle is defined for each
         -- vertex presented after the first two vertices. Vertices 1, /n/+1, and
         -- /n/+2 define triangle /n/. /N/-2 triangles are drawn.
       | Quads
         -- ^ Treats each group of four vertices as an independent quadrilateral.
         -- Vertices 4/n/-3, 4/n/-2, 4/n/-1, and 4/n/ define quadrilateral /n/.
         -- /N/\/4 quadrilaterals are drawn.
       | QuadStrip
         -- ^ Draws a connected group of quadrilaterals. One quadrilateral is
         --defined for each pair of vertices presented after the first pair.
         -- Vertices 2/n/-1, 2/n/, 2/n/+2, and 2/n/+1 define quadrilateral /n/.
         -- /N/\/2-1 quadrilaterals are drawn. Note that the order in which vertices
         -- are used to construct a quadrilateral from strip data is different from
         -- that used with independent data.
       | Polygon
         -- ^ Draws a single, convex polygon. Vertices 1 through /N/ define this
         -- polygon.
       | Patches
         -- ^ Only used in conjunction with tessellation. The number of vertices per
         -- patch can be set with 'patchVertices'.
       deriving ( PrimitiveMode -> PrimitiveMode -> Bool
    (PrimitiveMode -> PrimitiveMode -> Bool)
    -> (PrimitiveMode -> PrimitiveMode -> Bool) -> Eq PrimitiveMode
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: PrimitiveMode -> PrimitiveMode -> Bool
    == :: PrimitiveMode -> PrimitiveMode -> Bool
    $c/= :: PrimitiveMode -> PrimitiveMode -> Bool
    /= :: PrimitiveMode -> PrimitiveMode -> Bool
    Eq, Eq PrimitiveMode
    Eq PrimitiveMode =>
    (PrimitiveMode -> PrimitiveMode -> Ordering)
    -> (PrimitiveMode -> PrimitiveMode -> Bool)
    -> (PrimitiveMode -> PrimitiveMode -> Bool)
    -> (PrimitiveMode -> PrimitiveMode -> Bool)
    -> (PrimitiveMode -> PrimitiveMode -> Bool)
    -> (PrimitiveMode -> PrimitiveMode -> PrimitiveMode)
    -> (PrimitiveMode -> PrimitiveMode -> PrimitiveMode)
    -> Ord PrimitiveMode
    PrimitiveMode -> PrimitiveMode -> Bool
    PrimitiveMode -> PrimitiveMode -> Ordering
    PrimitiveMode -> PrimitiveMode -> PrimitiveMode
    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 :: PrimitiveMode -> PrimitiveMode -> Ordering
    compare :: PrimitiveMode -> PrimitiveMode -> Ordering
    $c< :: PrimitiveMode -> PrimitiveMode -> Bool
    < :: PrimitiveMode -> PrimitiveMode -> Bool
    $c<= :: PrimitiveMode -> PrimitiveMode -> Bool
    <= :: PrimitiveMode -> PrimitiveMode -> Bool
    $c> :: PrimitiveMode -> PrimitiveMode -> Bool
    > :: PrimitiveMode -> PrimitiveMode -> Bool
    $c>= :: PrimitiveMode -> PrimitiveMode -> Bool
    >= :: PrimitiveMode -> PrimitiveMode -> Bool
    $cmax :: PrimitiveMode -> PrimitiveMode -> PrimitiveMode
    max :: PrimitiveMode -> PrimitiveMode -> PrimitiveMode
    $cmin :: PrimitiveMode -> PrimitiveMode -> PrimitiveMode
    min :: PrimitiveMode -> PrimitiveMode -> PrimitiveMode
    Ord, Int -> PrimitiveMode -> ShowS
    [PrimitiveMode] -> ShowS
    PrimitiveMode -> String
    (Int -> PrimitiveMode -> ShowS)
    -> (PrimitiveMode -> String)
    -> ([PrimitiveMode] -> ShowS)
    -> Show PrimitiveMode
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> PrimitiveMode -> ShowS
    showsPrec :: Int -> PrimitiveMode -> ShowS
    $cshow :: PrimitiveMode -> String
    show :: PrimitiveMode -> String
    $cshowList :: [PrimitiveMode] -> ShowS
    showList :: [PrimitiveMode] -> ShowS
    Show )

    -- | 'patchVertices' is the number of vertices per patch primitive.
    --
    -- An 'Graphics.Rendering.OpenGL.GLU.Errors.InvalidValue' is generated if
    -- 'patchVertices' is set to a value less than or equal to zero or greater
    -- than the implementation-dependent maximum value 'maxPatchVertices'.

    patchVertices :: StateVar GLsizei
    patchVertices :: StateVar GLsizei
    patchVertices =
      IO GLsizei -> (GLsizei -> IO ()) -> StateVar GLsizei
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar ((GLsizei -> GLsizei) -> PName1I -> IO GLsizei
    forall p a. GetPName1I p => (GLsizei -> a) -> p -> IO a
    forall a. (GLsizei -> a) -> PName1I -> IO a
    getSizei1 GLsizei -> GLsizei
    forall a. a -> a
    id PName1I
    GetPatchVertices)
                   (GLenum -> GLsizei -> IO ()
    forall (m :: * -> *). MonadIO m => GLenum -> GLsizei -> m ()
    glPatchParameteri GLenum
    GL_PATCH_VERTICES (GLsizei -> IO ()) -> (GLsizei -> GLsizei) -> GLsizei -> IO ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . GLsizei -> GLsizei
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral)

    -- | Contains the maximumum number of vertices in a single patch.

    maxPatchVertices :: GettableStateVar GLsizei
    maxPatchVertices :: IO GLsizei
    maxPatchVertices = IO GLsizei -> IO GLsizei
    forall a. IO a -> IO a
    makeGettableStateVar (IO GLsizei -> IO GLsizei) -> IO GLsizei -> IO GLsizei
    forall a b. (a -> b) -> a -> b
    $ (GLsizei -> GLsizei) -> PName1I -> IO GLsizei
    forall p a. GetPName1I p => (GLsizei -> a) -> p -> IO a
    forall a. (GLsizei -> a) -> PName1I -> IO a
    getSizei1 GLsizei -> GLsizei
    forall a. a -> a
    id PName1I
    GetMaxPatchVertices

    -- | Contains the four default outer tessellation levels to be used when no
    -- tessellation control shader is present.

    patchDefaultOuterLevel :: StateVar (GLfloat, GLfloat, GLfloat, GLfloat)
    patchDefaultOuterLevel :: StateVar (GLfloat, GLfloat, GLfloat, GLfloat)
    patchDefaultOuterLevel =
      IO (GLfloat, GLfloat, GLfloat, GLfloat)
    -> ((GLfloat, GLfloat, GLfloat, GLfloat) -> IO ())
    -> StateVar (GLfloat, GLfloat, GLfloat, GLfloat)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
        ((GLfloat
     -> GLfloat
     -> GLfloat
     -> GLfloat
     -> (GLfloat, GLfloat, GLfloat, GLfloat))
    -> PName4F -> IO (GLfloat, GLfloat, GLfloat, GLfloat)
    forall p a.
    GetPName4F p =>
    (GLfloat -> GLfloat -> GLfloat -> GLfloat -> a) -> p -> IO a
    forall a.
    (GLfloat -> GLfloat -> GLfloat -> GLfloat -> a) -> PName4F -> IO a
    getFloat4 (,,,) PName4F
    GetPatchDefaultOuterLevel)
        (\(GLfloat
    l0, GLfloat
    l1, GLfloat
    l2, GLfloat
    l3) -> Int -> (Ptr GLfloat -> IO ()) -> IO ()
    forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
    allocaArray Int
    4 ((Ptr GLfloat -> IO ()) -> IO ())
    -> (Ptr GLfloat -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLfloat
    ptr -> do
                                Ptr GLfloat -> GLfloat -> GLfloat -> GLfloat -> GLfloat -> IO ()
    forall a. Storable a => Ptr a -> a -> a -> a -> a -> IO ()
    poke4 Ptr GLfloat
    ptr GLfloat
    l0 GLfloat
    l1 GLfloat
    l2 GLfloat
    l3
                                GLenum -> Ptr GLfloat -> IO ()
    forall (m :: * -> *). MonadIO m => GLenum -> Ptr GLfloat -> m ()
    glPatchParameterfv GLenum
    GL_PATCH_DEFAULT_OUTER_LEVEL Ptr GLfloat
    ptr)

    -- | Contains the two default inner tessellation levels to be used when no
    -- tessellation control shader is present.

    patchDefaultInnerLevel :: StateVar (GLfloat, GLfloat)
    patchDefaultInnerLevel :: StateVar (GLfloat, GLfloat)
    patchDefaultInnerLevel =
      IO (GLfloat, GLfloat)
    -> ((GLfloat, GLfloat) -> IO ()) -> StateVar (GLfloat, GLfloat)
    forall a. IO a -> (a -> IO ()) -> StateVar a
    makeStateVar
        ((GLfloat -> GLfloat -> (GLfloat, GLfloat))
    -> PName2F -> IO (GLfloat, GLfloat)
    forall p a. GetPName2F p => (GLfloat -> GLfloat -> a) -> p -> IO a
    forall a. (GLfloat -> GLfloat -> a) -> PName2F -> IO a
    getFloat2 (,) PName2F
    GetPatchDefaultInnerLevel)
        (\(GLfloat
    l0, GLfloat
    l1) -> Int -> (Ptr GLfloat -> IO ()) -> IO ()
    forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
    allocaArray Int
    2 ((Ptr GLfloat -> IO ()) -> IO ())
    -> (Ptr GLfloat -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \Ptr GLfloat
    ptr -> do
                        Ptr GLfloat -> GLfloat -> GLfloat -> IO ()
    forall a. Storable a => Ptr a -> a -> a -> IO ()
    poke2 Ptr GLfloat
    ptr GLfloat
    l0 GLfloat
    l1
                        GLenum -> Ptr GLfloat -> IO ()
    forall (m :: * -> *). MonadIO m => GLenum -> Ptr GLfloat -> m ()
    glPatchParameterfv GLenum
    GL_PATCH_DEFAULT_INNER_LEVEL Ptr GLfloat
    ptr)

    -- | Contains the maximum allowed tessellation level.

    maxTessGenLevel :: GettableStateVar GLsizei
    maxTessGenLevel :: IO GLsizei
    maxTessGenLevel = IO GLsizei -> IO GLsizei
    forall a. IO a -> IO a
    makeGettableStateVar (IO GLsizei -> IO GLsizei) -> IO GLsizei -> IO GLsizei
    forall a b. (a -> b) -> a -> b
    $ (GLsizei -> GLsizei) -> PName1I -> IO GLsizei
    forall p a. GetPName1I p => (GLsizei -> a) -> p -> IO a
    forall a. (GLsizei -> a) -> PName1I -> IO a
    getSizei1 GLsizei -> GLsizei
    forall a. a -> a
    id PName1I
    GetMaxTessGenLevel