{-# LANGUAGE TypeSynonymInstances #-}
module Graphics.Rendering.OpenGL.GL.QueryObjects (
QueryObject, QueryIndex, maxVertexStreams, QueryTarget(..),
beginQuery, endQuery, withQuery,
currentQuery, queryCounterBits,
queryResultAvailable, QueryResult, queryResult,
timestampQuery, timestamp
) where
import Data.StateVar
import Foreign.Marshal.Alloc
import Foreign.Marshal.Utils
import Foreign.Ptr
import Foreign.Storable
import Graphics.Rendering.OpenGL.GL.Exception
import Graphics.Rendering.OpenGL.GL.GLboolean
import Graphics.Rendering.OpenGL.GL.PeekPoke
import Graphics.Rendering.OpenGL.GL.QueryObject
import Graphics.Rendering.OpenGL.GL.QueryUtils
import Graphics.GL
type QueryIndex = GLuint
maxVertexStreams :: GettableStateVar QueryIndex
maxVertexStreams =
makeGettableStateVar (getInteger1 fromIntegral GetMaxVertexStreams)
data QueryTarget =
SamplesPassed
| AnySamplesPassed
| AnySamplesPassedConservative
| TimeElapsed
| PrimitivesGenerated QueryIndex
| TransformFeedbackPrimitivesWritten QueryIndex
deriving ( Eq, Ord, Show )
marshalQueryTarget :: QueryTarget -> (GLenum, QueryIndex)
marshalQueryTarget x = case x of
SamplesPassed -> (GL_SAMPLES_PASSED, 0)
AnySamplesPassed -> (GL_ANY_SAMPLES_PASSED, 0)
AnySamplesPassedConservative -> (GL_ANY_SAMPLES_PASSED_CONSERVATIVE, 0)
TimeElapsed -> (GL_TIME_ELAPSED, 0)
PrimitivesGenerated n -> (GL_PRIMITIVES_GENERATED, n)
TransformFeedbackPrimitivesWritten n ->
(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, n)
beginQuery :: QueryTarget -> QueryObject -> IO ()
beginQuery target = case marshalQueryTarget target of
(t, 0) -> glBeginQuery t . queryID
(t, n) -> glBeginQueryIndexed t n . queryID
endQuery :: QueryTarget -> IO ()
endQuery target = case marshalQueryTarget target of
(t, 0) -> glEndQuery t
(t, n) -> glEndQueryIndexed t n
withQuery :: QueryTarget -> QueryObject -> IO a -> IO a
withQuery t q = bracket_ (beginQuery t q) (endQuery t)
data GetQueryPName =
QueryCounterBits
| CurrentQuery
marshalGetQueryPName :: GetQueryPName -> GLenum
marshalGetQueryPName x = case x of
QueryCounterBits -> GL_QUERY_COUNTER_BITS
CurrentQuery -> GL_CURRENT_QUERY
currentQuery :: QueryTarget -> GettableStateVar (Maybe QueryObject)
currentQuery = getQueryi (toMaybeQueryObject . toQueryObject) CurrentQuery
where toQueryObject = QueryObject . fromIntegral
toMaybeQueryObject q = if q == noQueryObject then Nothing else Just q
queryCounterBits :: QueryTarget -> GettableStateVar GLsizei
queryCounterBits = getQueryi fromIntegral QueryCounterBits
getQueryi :: (GLint -> a) -> GetQueryPName -> QueryTarget -> GettableStateVar a
getQueryi f p t =
makeGettableStateVar $
with 0 $ \buf -> do
getQueryiv' t p buf
peek1 f buf
getQueryiv' :: QueryTarget -> GetQueryPName -> Ptr GLint -> IO ()
getQueryiv' target = case marshalQueryTarget target of
(t, 0) -> glGetQueryiv t . marshalGetQueryPName
(t, n) -> glGetQueryIndexediv t n . marshalGetQueryPName
data GetQueryObjectPName =
QueryResultAvailable
| QueryResult
marshalGetQueryObjectPName :: GetQueryObjectPName -> GLenum
marshalGetQueryObjectPName x = case x of
QueryResultAvailable -> GL_QUERY_RESULT_AVAILABLE
QueryResult -> GL_QUERY_RESULT
queryResultAvailable :: QueryObject -> GettableStateVar Bool
queryResultAvailable =
getQueryObject (unmarshalGLboolean :: GLuint -> Bool) QueryResultAvailable
queryResult :: QueryResult a => QueryObject -> GettableStateVar a
queryResult = getQueryObject id QueryResult
class Storable a => QueryResult a where
getQueryObjectv :: GLuint -> GLenum -> Ptr a -> IO ()
instance QueryResult GLint where getQueryObjectv = glGetQueryObjectiv
instance QueryResult GLuint where getQueryObjectv = glGetQueryObjectuiv
instance QueryResult GLint64 where getQueryObjectv = glGetQueryObjecti64v
instance QueryResult GLuint64 where getQueryObjectv = glGetQueryObjectui64v
getQueryObject :: (QueryResult a)
=> (a -> b)
-> GetQueryObjectPName
-> QueryObject
-> GettableStateVar b
getQueryObject f p q =
makeGettableStateVar $
alloca $ \buf -> do
getQueryObjectv (queryID q) (marshalGetQueryObjectPName p) buf
peek1 f buf
timestampQuery :: QueryObject -> IO ()
timestampQuery q = glQueryCounter (queryID q) GL_TIMESTAMP
timestamp :: GettableStateVar GLuint64
timestamp = makeGettableStateVar (getInteger64 fromIntegral GetTimestamp)