-----------------------------------------------------------------------------
-- |
-- Module      :  Graphics.Rendering.OpenGL.GL.VertexArrayObjects
-- Copyright   :  (c) Sven Panne 2011-2019, Lars Corbijn 2011-2016
-- License     :  BSD3
--
-- Maintainer  :  Sven Panne <svenpanne@gmail.com>
-- Stability   :  stable
-- Portability :  portable
--
-----------------------------------------------------------------------------

module Graphics.Rendering.OpenGL.GL.VertexArrayObjects (
   VertexArrayObject,
   bindVertexArrayObject
) where

import Control.Monad.IO.Class
import Data.ObjectName
import Data.StateVar
import Foreign.Marshal.Array ( allocaArray, peekArray, withArrayLen )
import Graphics.Rendering.OpenGL.GL.DebugOutput
import Graphics.Rendering.OpenGL.GL.GLboolean
import Graphics.Rendering.OpenGL.GL.QueryUtils
import Graphics.GL

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

newtype VertexArrayObject = VertexArrayObject { VertexArrayObject -> GLuint
vertexArrayID :: GLuint }
   deriving( VertexArrayObject -> VertexArrayObject -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: VertexArrayObject -> VertexArrayObject -> Bool
$c/= :: VertexArrayObject -> VertexArrayObject -> Bool
== :: VertexArrayObject -> VertexArrayObject -> Bool
$c== :: VertexArrayObject -> VertexArrayObject -> Bool
Eq, Eq VertexArrayObject
VertexArrayObject -> VertexArrayObject -> Bool
VertexArrayObject -> VertexArrayObject -> Ordering
VertexArrayObject -> VertexArrayObject -> VertexArrayObject
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
min :: VertexArrayObject -> VertexArrayObject -> VertexArrayObject
$cmin :: VertexArrayObject -> VertexArrayObject -> VertexArrayObject
max :: VertexArrayObject -> VertexArrayObject -> VertexArrayObject
$cmax :: VertexArrayObject -> VertexArrayObject -> VertexArrayObject
>= :: VertexArrayObject -> VertexArrayObject -> Bool
$c>= :: VertexArrayObject -> VertexArrayObject -> Bool
> :: VertexArrayObject -> VertexArrayObject -> Bool
$c> :: VertexArrayObject -> VertexArrayObject -> Bool
<= :: VertexArrayObject -> VertexArrayObject -> Bool
$c<= :: VertexArrayObject -> VertexArrayObject -> Bool
< :: VertexArrayObject -> VertexArrayObject -> Bool
$c< :: VertexArrayObject -> VertexArrayObject -> Bool
compare :: VertexArrayObject -> VertexArrayObject -> Ordering
$ccompare :: VertexArrayObject -> VertexArrayObject -> Ordering
Ord, Int -> VertexArrayObject -> ShowS
[VertexArrayObject] -> ShowS
VertexArrayObject -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [VertexArrayObject] -> ShowS
$cshowList :: [VertexArrayObject] -> ShowS
show :: VertexArrayObject -> String
$cshow :: VertexArrayObject -> String
showsPrec :: Int -> VertexArrayObject -> ShowS
$cshowsPrec :: Int -> VertexArrayObject -> ShowS
Show )

instance ObjectName VertexArrayObject where
   isObjectName :: forall (m :: * -> *). MonadIO m => VertexArrayObject -> m Bool
isObjectName =
     forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. (Eq a, Num a) => a -> Bool
unmarshalGLboolean forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (m :: * -> *). MonadIO m => GLuint -> m GLboolean
glIsVertexArray forall b c a. (b -> c) -> (a -> b) -> a -> c
. VertexArrayObject -> GLuint
vertexArrayID

   deleteObjectNames :: forall (m :: * -> *). MonadIO m => [VertexArrayObject] -> m ()
deleteObjectNames [VertexArrayObject]
bufferObjects =
      forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Storable a => [a] -> (Int -> Ptr a -> IO b) -> IO b
withArrayLen (forall a b. (a -> b) -> [a] -> [b]
map VertexArrayObject -> GLuint
vertexArrayID [VertexArrayObject]
bufferObjects) forall a b. (a -> b) -> a -> b
$
         forall (m :: * -> *). MonadIO m => GLint -> Ptr GLuint -> m ()
glDeleteVertexArrays forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral

instance GeneratableObjectName VertexArrayObject where
   genObjectNames :: forall (m :: * -> *). MonadIO m => Int -> m [VertexArrayObject]
genObjectNames Int
n = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. Storable a => Int -> (Ptr a -> IO b) -> IO b
allocaArray Int
n forall a b. (a -> b) -> a -> b
$ \Ptr GLuint
buf -> do
      forall (m :: * -> *). MonadIO m => GLint -> Ptr GLuint -> m ()
glGenVertexArrays (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n) Ptr GLuint
buf
      forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a b. (a -> b) -> [a] -> [b]
map GLuint -> VertexArrayObject
VertexArrayObject) forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
n Ptr GLuint
buf

instance CanBeLabeled VertexArrayObject where
   objectLabel :: VertexArrayObject -> StateVar (Maybe String)
objectLabel = GLuint -> GLuint -> StateVar (Maybe String)
objectNameLabel GLuint
GL_VERTEX_ARRAY forall b c a. (b -> c) -> (a -> b) -> a -> c
. VertexArrayObject -> GLuint
vertexArrayID

bindVertexArrayObject :: StateVar (Maybe VertexArrayObject)
bindVertexArrayObject :: StateVar (Maybe VertexArrayObject)
bindVertexArrayObject = forall a. IO a -> (a -> IO ()) -> StateVar a
makeStateVar IO (Maybe VertexArrayObject)
getVAO Maybe VertexArrayObject -> IO ()
bindVAO

getVAO :: IO (Maybe VertexArrayObject)
getVAO :: IO (Maybe VertexArrayObject)
getVAO = do
   VertexArrayObject
vao <- forall p a. GetPName1I p => (GLint -> a) -> p -> IO a
getInteger1 (GLuint -> VertexArrayObject
VertexArrayObject forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral) PName1I
GetVertexArrayBinding
   forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ if VertexArrayObject
vao forall a. Eq a => a -> a -> Bool
== VertexArrayObject
noVAO then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just VertexArrayObject
vao

bindVAO :: Maybe VertexArrayObject -> IO ()
bindVAO :: Maybe VertexArrayObject -> IO ()
bindVAO = forall (m :: * -> *). MonadIO m => GLuint -> m ()
glBindVertexArray forall b c a. (b -> c) -> (a -> b) -> a -> c
. VertexArrayObject -> GLuint
vertexArrayID forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall b a. b -> (a -> b) -> Maybe a -> b
maybe VertexArrayObject
noVAO forall a. a -> a
id

noVAO :: VertexArrayObject
noVAO :: VertexArrayObject
noVAO = GLuint -> VertexArrayObject
VertexArrayObject GLuint
0