-------------------------------------------------------------------------------- -- | -- Module : Graphics.Rendering.OGL.GL.PixelRectangles.Histogram -- Copyright : (c) Sven Panne 2002-2006 -- License : BSD-style (see the file libraries/OpenGL/LICENSE) -- -- Maintainer : sven.panne@aedion.de -- Stability : stable -- Portability : portable -- -- This module corresponds to a part of section 3.6.1 (Pixel Storage Modes) of -- the OpenGL 2.1 specs. -- -------------------------------------------------------------------------------- module Graphics.Rendering.OGL.GL.PixelRectangles.Histogram ( Sink(..), histogram, Reset(..), getHistogram, resetHistogram, histogramRGBASizes, histogramLuminanceSize ) where import Foreign.Marshal.Alloc ( alloca ) import Foreign.Ptr ( Ptr ) import Graphics.Rendering.OGL.Monad import Graphics.Rendering.OGL.GL.Capability ( EnableCap(CapHistogram), makeStateVarMaybe ) import Graphics.Rendering.OGL.GL.BasicTypes ( GLboolean, GLenum, GLint, GLsizei ) import Graphics.Rendering.OGL.GL.Extensions ( FunPtr, unsafePerformIO, Invoker, getProcAddress ) import Graphics.Rendering.OGL.GL.PeekPoke ( peek1 ) import Graphics.Rendering.OGL.GL.PixelRectangles.Rasterization ( PixelData(..) ) import Graphics.Rendering.OGL.GL.PixelRectangles.ColorTable ( PixelInternalFormat ) import Graphics.Rendering.OGL.GL.PixelData ( withPixelData ) import Graphics.Rendering.OGL.GL.Texturing.PixelInternalFormat ( marshalPixelInternalFormat', unmarshalPixelInternalFormat ) import Graphics.Rendering.OGL.GL.PixelRectangles.ColorTable ( Proxy(..) ) import Graphics.Rendering.OGL.GL.PixelRectangles.Sink ( Sink(..), marshalSink, unmarshalSink ) import Graphics.Rendering.OGL.GL.PixelRectangles.Reset ( Reset(..), marshalReset ) import Graphics.Rendering.OGL.GL.StateVar ( GettableStateVar, makeGettableStateVar, StateVar ) import Graphics.Rendering.OGL.GL.VertexSpec ( Color4(..) ) -------------------------------------------------------------------------------- #include "HsOpenGLExt.h" -------------------------------------------------------------------------------- data HistogramTarget = Histogram | ProxyHistogram marshalHistogramTarget :: HistogramTarget -> GLenum marshalHistogramTarget x = case x of Histogram -> 0x8024 ProxyHistogram -> 0x8025 proxyToHistogramTarget :: Proxy -> HistogramTarget proxyToHistogramTarget x = case x of NoProxy -> Histogram Proxy -> ProxyHistogram -------------------------------------------------------------------------------- histogram :: Proxy -> StateVar (Maybe (GLsizei, PixelInternalFormat, Sink)) histogram proxy = makeStateVarMaybe (return CapHistogram) (getHistogram' proxy) (setHistogram proxy) getHistogram' :: Proxy -> IO (GLsizei, PixelInternalFormat, Sink) getHistogram' proxy = do w <- getHistogramParameteri fromIntegral proxy HistogramWidth f <- getHistogramParameteri unmarshalPixelInternalFormat proxy HistogramFormat s <- getHistogramParameteri unmarshalSink proxy HistogramSink return (w, f, s) getHistogramParameteri :: (GLint -> a) -> Proxy -> GetHistogramParameterPName -> IO a getHistogramParameteri f proxy p = alloca $ \buf -> do glGetHistogramParameteriv (marshalHistogramTarget (proxyToHistogramTarget proxy)) (marshalGetHistogramParameterPName p) buf peek1 f buf EXTENSION_ENTRY("GL_ARB_imaging",glGetHistogramParameteriv,GLenum -> GLenum -> Ptr GLint -> IO ()) setHistogram :: Proxy -> (GLsizei, PixelInternalFormat, Sink) -> IO () setHistogram proxy (w, int, sink) = glHistogram (marshalHistogramTarget (proxyToHistogramTarget proxy)) w (marshalPixelInternalFormat' int) (marshalSink sink) EXTENSION_ENTRY("GL_ARB_imaging",glHistogram,GLenum -> GLsizei -> GLenum -> GLboolean -> IO ()) -------------------------------------------------------------------------------- getHistogram :: Reset -> PixelData a -> GL () getHistogram reset pd = liftIO . withPixelData pd $ glGetHistogram (marshalHistogramTarget Histogram) (marshalReset reset) EXTENSION_ENTRY("GL_ARB_imaging",glGetHistogram,GLenum -> GLboolean -> GLenum -> GLenum -> Ptr a -> IO ()) -------------------------------------------------------------------------------- resetHistogram :: GL () resetHistogram = glResetHistogram (marshalHistogramTarget Histogram) EXTENSION_ENTRY("GL_ARB_imaging",glResetHistogram,GLenum -> GL ()) -------------------------------------------------------------------------------- data GetHistogramParameterPName = HistogramWidth | HistogramFormat | HistogramRedSize | HistogramGreenSize | HistogramBlueSize | HistogramAlphaSize | HistogramLuminanceSize | HistogramSink marshalGetHistogramParameterPName :: GetHistogramParameterPName -> GLenum marshalGetHistogramParameterPName x = case x of HistogramWidth -> 0x8026 HistogramFormat -> 0x8027 HistogramRedSize -> 0x8028 HistogramGreenSize -> 0x8029 HistogramBlueSize -> 0x802a HistogramAlphaSize -> 0x802b HistogramLuminanceSize -> 0x802c HistogramSink -> 0x802d -------------------------------------------------------------------------------- histogramRGBASizes :: Proxy -> GettableStateVar (Color4 GLsizei) histogramRGBASizes proxy = makeGettableStateVar $ do r <- getHistogramParameteri fromIntegral proxy HistogramRedSize g <- getHistogramParameteri fromIntegral proxy HistogramGreenSize b <- getHistogramParameteri fromIntegral proxy HistogramBlueSize a <- getHistogramParameteri fromIntegral proxy HistogramAlphaSize return $ Color4 r g b a histogramLuminanceSize :: Proxy -> GettableStateVar GLsizei histogramLuminanceSize proxy = makeGettableStateVar $ getHistogramParameteri id proxy HistogramLuminanceSize