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

    module Graphics.Rendering.OpenGL.GLU.Mipmapping (
       scaleImage, build1DMipmaps, build2DMipmaps
    ) where

    import Graphics.GLU
    import Graphics.Rendering.OpenGL.GL.CoordTrans ( Size(..) )
    import Graphics.Rendering.OpenGL.GL.Texturing.PixelInternalFormat
    import Graphics.Rendering.OpenGL.GL.PixelData ( PixelData, withPixelData )
    import Graphics.Rendering.OpenGL.GL.Texturing.TextureTarget
    import Graphics.Rendering.OpenGL.GLU.ErrorsInternal ( recordInvalidValue )
    import Graphics.GL

    --------------------------------------------------------------------------------
    -- Section 3.1 (Image Scaling)

    scaleImage :: Size -> PixelData a -> Size -> PixelData b -> IO ()
    scaleImage :: forall a b. Size -> PixelData a -> Size -> PixelData b -> IO ()
    scaleImage (Size GLsizei
    widthIn  GLsizei
    heightIn)  PixelData a
    pdIn (Size GLsizei
    widthOut GLsizei
    heightOut) PixelData b
    pdOut =
       PixelData a -> (GLenum -> GLenum -> Ptr a -> IO ()) -> IO ()
    forall a b. PixelData a -> (GLenum -> GLenum -> Ptr a -> b) -> b
    withPixelData PixelData a
    pdIn ((GLenum -> GLenum -> Ptr a -> IO ()) -> IO ())
    -> (GLenum -> GLenum -> Ptr a -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \GLenum
    fIn GLenum
    dIn Ptr a
    pIn ->
          PixelData b -> (GLenum -> GLenum -> Ptr b -> IO ()) -> IO ()
    forall a b. PixelData a -> (GLenum -> GLenum -> Ptr a -> b) -> b
    withPixelData PixelData b
    pdOut ((GLenum -> GLenum -> Ptr b -> IO ()) -> IO ())
    -> (GLenum -> GLenum -> Ptr b -> IO ()) -> IO ()
    forall a b. (a -> b) -> a -> b
    $ \GLenum
    fOut GLenum
    dOut Ptr b
    pOut ->
             if GLenum
    fIn GLenum -> GLenum -> Bool
    forall a. Eq a => a -> a -> Bool
    == GLenum
    fOut
                then do _ <- GLenum
    -> GLsizei
    -> GLsizei
    -> GLenum
    -> Ptr a
    -> GLsizei
    -> GLsizei
    -> GLenum
    -> Ptr b
    -> IO GLsizei
    forall (m :: * -> *) a b.
    MonadIO m =>
    GLenum
    -> GLsizei
    -> GLsizei
    -> GLenum
    -> Ptr a
    -> GLsizei
    -> GLsizei
    -> GLenum
    -> Ptr b
    -> m GLsizei
    gluScaleImage
                          GLenum
    fIn GLsizei
    widthIn GLsizei
    heightIn GLenum
    dIn Ptr a
    pIn GLsizei
    widthOut GLsizei
    heightOut GLenum
    dOut Ptr b
    pOut
                        return ()   -- TODO: Should we use the return value?
                else IO ()
    recordInvalidValue

    --------------------------------------------------------------------------------
    -- Section 3.2 (Automatic Mipmapping)
    -- Missing for GLU 1.3: gluBuild3DMipmaps, gluBuild{1,2,3}DMipmapLevels

    build1DMipmaps ::
       TextureTarget1D -> PixelInternalFormat -> GLsizei -> PixelData a -> IO ()
    build1DMipmaps :: forall a.
    TextureTarget1D
    -> PixelInternalFormat -> GLsizei -> PixelData a -> IO ()
    build1DMipmaps TextureTarget1D
    target PixelInternalFormat
    internalFormat GLsizei
    height PixelData a
    pd = do
       _ <- PixelData a
    -> (GLenum -> GLenum -> Ptr a -> IO GLsizei) -> IO GLsizei
    forall a b. PixelData a -> (GLenum -> GLenum -> Ptr a -> b) -> b
    withPixelData PixelData a
    pd ((GLenum -> GLenum -> Ptr a -> IO GLsizei) -> IO GLsizei)
    -> (GLenum -> GLenum -> Ptr a -> IO GLsizei) -> IO GLsizei
    forall a b. (a -> b) -> a -> b
    $
          GLenum
    -> GLsizei -> GLsizei -> GLenum -> GLenum -> Ptr a -> IO GLsizei
    forall (m :: * -> *) a.
    MonadIO m =>
    GLenum
    -> GLsizei -> GLsizei -> GLenum -> GLenum -> Ptr a -> m GLsizei
    gluBuild1DMipmaps
             (TextureTarget1D -> GLenum
    forall t. GettableTextureTarget t => t -> GLenum
    marshalGettableTextureTarget TextureTarget1D
    target)
             (PixelInternalFormat -> GLsizei
    marshalPixelInternalFormat PixelInternalFormat
    internalFormat)
             GLsizei
    height
       return ()   -- TODO: Should we use the return value?

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

    build2DMipmaps :: TextureTarget2D -> PixelInternalFormat -> GLsizei -> GLsizei
                   -> PixelData a -> IO ()
    build2DMipmaps :: forall a.
    TextureTarget2D
    -> PixelInternalFormat
    -> GLsizei
    -> GLsizei
    -> PixelData a
    -> IO ()
    build2DMipmaps TextureTarget2D
    target PixelInternalFormat
    internalFormat GLsizei
    width GLsizei
    height PixelData a
    pd = do
       _ <- PixelData a
    -> (GLenum -> GLenum -> Ptr a -> IO GLsizei) -> IO GLsizei
    forall a b. PixelData a -> (GLenum -> GLenum -> Ptr a -> b) -> b
    withPixelData PixelData a
    pd ((GLenum -> GLenum -> Ptr a -> IO GLsizei) -> IO GLsizei)
    -> (GLenum -> GLenum -> Ptr a -> IO GLsizei) -> IO GLsizei
    forall a b. (a -> b) -> a -> b
    $
          GLenum
    -> GLsizei
    -> GLsizei
    -> GLsizei
    -> GLenum
    -> GLenum
    -> Ptr a
    -> IO GLsizei
    forall (m :: * -> *) a.
    MonadIO m =>
    GLenum
    -> GLsizei
    -> GLsizei
    -> GLsizei
    -> GLenum
    -> GLenum
    -> Ptr a
    -> m GLsizei
    gluBuild2DMipmaps
             (TextureTarget2D -> GLenum
    forall t. GettableTextureTarget t => t -> GLenum
    marshalGettableTextureTarget TextureTarget2D
    target)
             (PixelInternalFormat -> GLsizei
    marshalPixelInternalFormat PixelInternalFormat
    internalFormat)
             GLsizei
    width GLsizei
    height
       return ()   -- TODO: Should we use the return value?