module Graphics.Rendering.OpenGL.GL.Texturing.Environments (
TextureFunction(..), textureFunction,
TextureCombineFunction(..), combineRGB, combineAlpha,
ArgNum(..), Arg(..), Src(..), argRGB, argAlpha,
rgbScale, alphaScale,
constantColor, textureUnitLODBias
) where
import Control.Monad
import Data.StateVar
import Foreign.Marshal.Alloc
import Foreign.Marshal.Utils
import Foreign.Ptr
import Foreign.Storable
import Graphics.Rendering.OpenGL.GL.BlendingFactor
import Graphics.Rendering.OpenGL.GL.PeekPoke
import Graphics.Rendering.OpenGL.GL.Texturing.Parameters
import Graphics.Rendering.OpenGL.GL.Texturing.TextureUnit
import Graphics.Rendering.OpenGL.GL.VertexSpec
import Graphics.Rendering.OpenGL.Raw
data TextureEnvTarget =
TextureEnv
| TextureFilterControl
| PointSprite
marshalTextureEnvTarget :: TextureEnvTarget -> GLenum
marshalTextureEnvTarget x = case x of
TextureEnv -> gl_TEXTURE_ENV
TextureFilterControl -> gl_TEXTURE_FILTER_CONTROL
PointSprite -> gl_POINT_SPRITE
data TextureEnvParameter =
TexEnvParamTextureEnvMode
| TexEnvParamTextureEnvColor
| TexEnvParamCombineRGB
| TexEnvParamCombineAlpha
| TexEnvParamSrc0RGB
| TexEnvParamSrc1RGB
| TexEnvParamSrc2RGB
| TexEnvParamSrc3RGB
| TexEnvParamSrc0Alpha
| TexEnvParamSrc1Alpha
| TexEnvParamSrc2Alpha
| TexEnvParamSrc3Alpha
| TexEnvParamOperand0RGB
| TexEnvParamOperand1RGB
| TexEnvParamOperand2RGB
| TexEnvParamOperand3RGB
| TexEnvParamOperand0Alpha
| TexEnvParamOperand1Alpha
| TexEnvParamOperand2Alpha
| TexEnvParamOperand3Alpha
| TexEnvParamRGBScale
| TexEnvParamAlphaScale
| TexEnvParamLODBias
marshalTextureEnvParameter :: TextureEnvParameter -> GLenum
marshalTextureEnvParameter x = case x of
TexEnvParamTextureEnvMode -> gl_TEXTURE_ENV_MODE
TexEnvParamTextureEnvColor -> gl_TEXTURE_ENV_COLOR
TexEnvParamCombineRGB -> gl_COMBINE_RGB
TexEnvParamCombineAlpha -> gl_COMBINE_ALPHA
TexEnvParamSrc0RGB -> gl_SRC0_RGB
TexEnvParamSrc1RGB -> gl_SRC1_RGB
TexEnvParamSrc2RGB -> gl_SRC2_RGB
TexEnvParamSrc3RGB -> gl_SOURCE3_RGB_NV
TexEnvParamSrc0Alpha -> gl_SRC0_ALPHA
TexEnvParamSrc1Alpha -> gl_SRC1_ALPHA
TexEnvParamSrc2Alpha -> gl_SRC2_ALPHA
TexEnvParamSrc3Alpha -> gl_SOURCE3_ALPHA_NV
TexEnvParamOperand0RGB -> gl_OPERAND0_RGB
TexEnvParamOperand1RGB -> gl_OPERAND1_RGB
TexEnvParamOperand2RGB -> gl_OPERAND2_RGB
TexEnvParamOperand3RGB -> gl_OPERAND3_RGB_NV
TexEnvParamOperand0Alpha -> gl_OPERAND0_ALPHA
TexEnvParamOperand1Alpha -> gl_OPERAND1_ALPHA
TexEnvParamOperand2Alpha -> gl_OPERAND2_ALPHA
TexEnvParamOperand3Alpha -> gl_OPERAND3_ALPHA_NV
TexEnvParamRGBScale -> gl_RGB_SCALE
TexEnvParamAlphaScale -> gl_ALPHA_SCALE
TexEnvParamLODBias -> gl_TEXTURE_LOD_BIAS
texEnv :: (GLenum -> GLenum -> b -> IO ())
-> (a -> (b -> IO ()) -> IO ())
-> TextureEnvTarget -> TextureEnvParameter -> a -> IO ()
texEnv glTexEnv marshalAct t p x =
marshalAct x $
glTexEnv (marshalTextureEnvTarget t) (marshalTextureEnvParameter p)
glTexEnvC4f :: GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ()
glTexEnvC4f t p ptr = glTexEnvfv t p (castPtr ptr)
getTexEnv :: Storable b
=> (GLenum -> GLenum -> Ptr b -> IO ())
-> (b -> a)
-> TextureEnvTarget -> TextureEnvParameter -> IO a
getTexEnv glGetTexEnv unmarshal t p =
alloca $ \buf -> do
glGetTexEnv (marshalTextureEnvTarget t) (marshalTextureEnvParameter p) buf
peek1 unmarshal buf
glGetTexEnvC4f :: GLenum -> GLenum -> Ptr (Color4 GLfloat) -> IO ()
glGetTexEnvC4f t p ptr = glGetTexEnvfv t p (castPtr ptr)
m2a :: (a -> b) -> a -> (b -> IO ()) -> IO ()
m2a marshal x act = act (marshal x)
texEnvi ::
(GLint -> a) -> (a -> GLint) -> TextureEnvTarget -> TextureEnvParameter -> StateVar a
texEnvi unmarshal marshal t p =
makeStateVar
(getTexEnv glGetTexEnviv unmarshal t p)
(texEnv glTexEnvi (m2a marshal) t p)
texEnvf ::
(GLfloat -> a) -> (a -> GLfloat) -> TextureEnvTarget -> TextureEnvParameter -> StateVar a
texEnvf unmarshal marshal t p =
makeStateVar
(getTexEnv glGetTexEnvfv unmarshal t p)
(texEnv glTexEnvf (m2a marshal) t p)
texEnvC4f :: TextureEnvTarget -> TextureEnvParameter -> StateVar (Color4 GLfloat)
texEnvC4f t p =
makeStateVar
(getTexEnv glGetTexEnvC4f id t p)
(texEnv glTexEnvC4f with t p)
data TextureFunction =
Modulate
| Decal
| Blend
| Replace
| AddUnsigned
| Combine
| Combine4
deriving ( Eq, Ord, Show )
marshalTextureFunction :: TextureFunction -> GLint
marshalTextureFunction x = fromIntegral $ case x of
Modulate -> gl_MODULATE
Decal -> gl_DECAL
Blend -> gl_BLEND
Replace -> gl_REPLACE
AddUnsigned -> gl_ADD
Combine -> gl_COMBINE
Combine4 -> gl_COMBINE4_NV
unmarshalTextureFunction :: GLint -> TextureFunction
unmarshalTextureFunction x
| y == gl_MODULATE = Modulate
| y == gl_DECAL = Decal
| y == gl_BLEND = Blend
| y == gl_REPLACE = Replace
| y == gl_ADD = AddUnsigned
| y == gl_COMBINE = Combine
| y == gl_COMBINE4_NV = Combine4
| otherwise = error ("unmarshalTextureFunction: illegal value " ++ show x)
where y = fromIntegral x
textureFunction :: StateVar TextureFunction
textureFunction =
texEnvi unmarshalTextureFunction marshalTextureFunction TextureEnv TexEnvParamTextureEnvMode
data TextureCombineFunction =
Replace'
| Modulate'
| AddUnsigned'
| AddSigned
| Interpolate
| Subtract
| Dot3RGB
| Dot3RGBA
deriving ( Eq, Ord, Show )
marshalTextureCombineFunction :: TextureCombineFunction -> GLint
marshalTextureCombineFunction x = fromIntegral $ case x of
Replace' -> gl_REPLACE
Modulate' -> gl_MODULATE
AddUnsigned' -> gl_ADD
AddSigned -> gl_ADD_SIGNED
Interpolate -> gl_INTERPOLATE
Subtract -> gl_SUBTRACT
Dot3RGB -> gl_DOT3_RGB
Dot3RGBA -> gl_DOT3_RGBA
unmarshalTextureCombineFunction :: GLint -> TextureCombineFunction
unmarshalTextureCombineFunction x
| y == gl_REPLACE = Replace'
| y == gl_MODULATE = Modulate'
| y == gl_ADD = AddUnsigned'
| y == gl_ADD_SIGNED = AddSigned
| y == gl_INTERPOLATE = Interpolate
| y == gl_SUBTRACT = Subtract
| y == gl_DOT3_RGB = Dot3RGB
| y == gl_DOT3_RGBA = Dot3RGBA
| otherwise = error ("unmarshalTextureCombineFunction: illegal value " ++ show x)
where y = fromIntegral x
combineRGB :: StateVar TextureCombineFunction
combineRGB = combine TexEnvParamCombineRGB
combineAlpha :: StateVar TextureCombineFunction
combineAlpha = combine TexEnvParamCombineAlpha
combine :: TextureEnvParameter -> StateVar TextureCombineFunction
combine =
texEnvi unmarshalTextureCombineFunction marshalTextureCombineFunction TextureEnv
data ArgNum =
Arg0
| Arg1
| Arg2
| Arg3
deriving ( Eq, Ord, Show )
argNumToOperandRGB :: ArgNum -> TextureEnvParameter
argNumToOperandRGB x = case x of
Arg0 -> TexEnvParamOperand0RGB
Arg1 -> TexEnvParamOperand1RGB
Arg2 -> TexEnvParamOperand2RGB
Arg3 -> TexEnvParamOperand3RGB
argNumToOperandAlpha :: ArgNum -> TextureEnvParameter
argNumToOperandAlpha x = case x of
Arg0 -> TexEnvParamOperand0Alpha
Arg1 -> TexEnvParamOperand1Alpha
Arg2 -> TexEnvParamOperand2Alpha
Arg3 -> TexEnvParamOperand3Alpha
argNumToSrcRGB :: ArgNum -> TextureEnvParameter
argNumToSrcRGB x = case x of
Arg0 -> TexEnvParamSrc0RGB
Arg1 -> TexEnvParamSrc1RGB
Arg2 -> TexEnvParamSrc2RGB
Arg3 -> TexEnvParamSrc3RGB
argNumToSrcAlpha :: ArgNum -> TextureEnvParameter
argNumToSrcAlpha x = case x of
Arg0 -> TexEnvParamSrc0Alpha
Arg1 -> TexEnvParamSrc1Alpha
Arg2 -> TexEnvParamSrc2Alpha
Arg3 -> TexEnvParamSrc3Alpha
data Arg = Arg BlendingFactor Src
deriving ( Eq, Ord, Show )
data Src =
CurrentUnit
| Previous
| Crossbar TextureUnit
| Constant
| PrimaryColor
deriving ( Eq, Ord, Show )
marshalSrc :: Src -> GLint
marshalSrc x = fromIntegral $ case x of
CurrentUnit -> gl_TEXTURE
Previous -> gl_PREVIOUS
Crossbar u -> fromIntegral (marshalTextureUnit u)
Constant -> gl_CONSTANT
PrimaryColor -> gl_PRIMARY_COLOR
unmarshalSrc :: GLint -> Src
unmarshalSrc x
| y == gl_TEXTURE = CurrentUnit
| y == gl_PREVIOUS = Previous
| y == gl_CONSTANT = Constant
| y == gl_PRIMARY_COLOR = PrimaryColor
| otherwise = Crossbar (unmarshalTextureUnit (fromIntegral x))
where y = fromIntegral x
argRGB :: ArgNum -> StateVar Arg
argRGB n = arg (argNumToOperandRGB n) (argNumToSrcRGB n)
argAlpha :: ArgNum -> StateVar Arg
argAlpha n = arg (argNumToOperandAlpha n) (argNumToSrcAlpha n)
arg :: TextureEnvParameter -> TextureEnvParameter -> StateVar Arg
arg op src = combineArg (textureEnvOperand op) (textureEnvSrc src)
where combineArg :: StateVar BlendingFactor -> StateVar Src -> StateVar Arg
combineArg v w = makeStateVar
(liftM2 Arg (get v) (get w))
(\(Arg x y) -> do v $= x; w $= y)
textureEnvOperand :: TextureEnvParameter -> StateVar BlendingFactor
textureEnvOperand =
texEnvi (unmarshalBlendingFactor . fromIntegral) (fromIntegral . marshalBlendingFactor) TextureEnv
textureEnvSrc :: TextureEnvParameter -> StateVar Src
textureEnvSrc = texEnvi unmarshalSrc marshalSrc TextureEnv
rgbScale :: StateVar GLfloat
rgbScale = scale TexEnvParamRGBScale
alphaScale :: StateVar GLfloat
alphaScale = scale TexEnvParamAlphaScale
scale :: TextureEnvParameter -> StateVar GLfloat
scale = texEnvf id id TextureEnv
constantColor :: StateVar (Color4 GLfloat)
constantColor = texEnvC4f TextureEnv TexEnvParamTextureEnvColor
textureUnitLODBias :: StateVar LOD
textureUnitLODBias = texEnvf id id TextureFilterControl TexEnvParamLODBias