--------------------------------------------------------------------------------
-- |
-- 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