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

    {-# LANGUAGE TypeSynonymInstances #-}

    module Graphics.Rendering.OpenGL.GL.Rectangles (
       Rect(..)
    ) where

    import Foreign.Ptr
    import Graphics.Rendering.OpenGL.GL.Tensor
    import Graphics.GL

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

    -- | 'rect' and 'rectv' support efficient specification of rectangles as two
    -- corner points. Each rectangle command takes four arguments, organized either
    -- as two consecutive pairs of (/x/, /y/) coordinates, or as two pointers to
    -- arrays, each containing an (/x/, /y/) pair. The resulting rectangle is
    -- defined in the /z/ = 0 plane.
    --
    -- @'rect' ('Vertex2' x1 y1) ('Vertex2' x2, y2)@ is exactly equivalent to the
    -- following sequence:
    --
    -- @
    --    'Graphics.Rendering.OpenGL.GL.BeginEnd.renderPrimitive' 'Graphics.Rendering.OpenGL.GL.BeginEnd.Polygon' $ do
    --        'Graphics.Rendering.OpenGL.GL.VertexSpec.vertex' ('Vertex2' x1 y1)
    --        'Graphics.Rendering.OpenGL.GL.VertexSpec.vertex' ('Vertex2' x2 y1)
    --        'Graphics.Rendering.OpenGL.GL.VertexSpec.vertex' ('Vertex2' x2 y2)
    --        'Graphics.Rendering.OpenGL.GL.VertexSpec.vertex' ('Vertex2' x1 y2)
    -- @
    --
    -- Note that if the second vertex is above and to the right of the first vertex,
    -- the rectangle is constructed with a counterclockwise winding.

    class Rect a where
       rect  :: Vertex2 a -> Vertex2 a -> IO ()
       rectv :: Ptr     a -> Ptr     a -> IO ()

    instance Rect GLshort where
       rect :: Vertex2 GLshort -> Vertex2 GLshort -> IO ()
    rect (Vertex2 GLshort
    x1 GLshort
    y1) (Vertex2 GLshort
    x2 GLshort
    y2) = GLshort -> GLshort -> GLshort -> GLshort -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLshort -> GLshort -> GLshort -> GLshort -> m ()
    glRects GLshort
    x1 GLshort
    y1 GLshort
    x2 GLshort
    y2
       rectv :: Ptr GLshort -> Ptr GLshort -> IO ()
    rectv Ptr GLshort
    ptr1 Ptr GLshort
    ptr2 = Ptr GLshort -> Ptr GLshort -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    Ptr GLshort -> Ptr GLshort -> m ()
    glRectsv Ptr GLshort
    ptr1 Ptr GLshort
    ptr2

    instance Rect GLint where
       rect :: Vertex2 GLint -> Vertex2 GLint -> IO ()
    rect (Vertex2 GLint
    x1 GLint
    y1) (Vertex2 GLint
    x2 GLint
    y2) = GLint -> GLint -> GLint -> GLint -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLint -> GLint -> GLint -> GLint -> m ()
    glRecti GLint
    x1 GLint
    y1 GLint
    x2 GLint
    y2
       rectv :: Ptr GLint -> Ptr GLint -> IO ()
    rectv Ptr GLint
    ptr1 Ptr GLint
    ptr2 = Ptr GLint -> Ptr GLint -> IO ()
    forall (m :: * -> *). MonadIO m => Ptr GLint -> Ptr GLint -> m ()
    glRectiv Ptr GLint
    ptr1 Ptr GLint
    ptr2

    instance Rect GLfloat where
       rect :: Vertex2 GLfloat -> Vertex2 GLfloat -> IO ()
    rect (Vertex2 GLfloat
    x1 GLfloat
    y1) (Vertex2 GLfloat
    x2 GLfloat
    y2) = GLfloat -> GLfloat -> GLfloat -> GLfloat -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLfloat -> GLfloat -> GLfloat -> GLfloat -> m ()
    glRectf GLfloat
    x1 GLfloat
    y1 GLfloat
    x2 GLfloat
    y2
       rectv :: Ptr GLfloat -> Ptr GLfloat -> IO ()
    rectv Ptr GLfloat
    ptr1 Ptr GLfloat
    ptr2 = Ptr GLfloat -> Ptr GLfloat -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    Ptr GLfloat -> Ptr GLfloat -> m ()
    glRectfv Ptr GLfloat
    ptr1 Ptr GLfloat
    ptr2

    instance Rect GLdouble where
       rect :: Vertex2 GLdouble -> Vertex2 GLdouble -> IO ()
    rect (Vertex2 GLdouble
    x1 GLdouble
    y1) (Vertex2 GLdouble
    x2 GLdouble
    y2) = GLdouble -> GLdouble -> GLdouble -> GLdouble -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    GLdouble -> GLdouble -> GLdouble -> GLdouble -> m ()
    glRectd GLdouble
    x1 GLdouble
    y1 GLdouble
    x2 GLdouble
    y2
       rectv :: Ptr GLdouble -> Ptr GLdouble -> IO ()
    rectv Ptr GLdouble
    ptr1 Ptr GLdouble
    ptr2 = Ptr GLdouble -> Ptr GLdouble -> IO ()
    forall (m :: * -> *).
    MonadIO m =>
    Ptr GLdouble -> Ptr GLdouble -> m ()
    glRectdv Ptr GLdouble
    ptr1 Ptr GLdouble
    ptr2