module Graphics.Caramia.Blend.Internal where
import Graphics.Caramia.Prelude
import Graphics.Caramia.Internal.OpenGLCApi
import Graphics.Caramia.Color
import Control.Exception
import Foreign
import Foreign.C.Types
data BlendEquation =
BEAdd
| BESubtract
| BEReverseSubtract
| BEMin
| BEMax
deriving ( Eq, Ord, Show, Read, Typeable )
data BlendFunc =
BFZero
| BFOne
| BFSrcColor
| BFOneMinusSrcColor
| BFDstColor
| BFOneMinusDstColor
| BFSrcAlpha
| BFOneMinusSrcAlpha
| BFDstAlpha
| BFOneMinusDstAlpha
| BFConstantColor
| BFOneMinusConstantColor
| BFConstantAlpha
| BFOneMinusConstantAlpha
| BFSrcAlphaSaturate
deriving ( Eq, Ord, Show, Read, Typeable )
toConstantBE :: BlendEquation -> GLenum
toConstantBE BEAdd = gl_FUNC_ADD
toConstantBE BESubtract = gl_FUNC_SUBTRACT
toConstantBE BEReverseSubtract = gl_FUNC_REVERSE_SUBTRACT
toConstantBE BEMin = gl_MIN
toConstantBE BEMax = gl_MAX
toConstantBF :: BlendFunc -> GLenum
toConstantBF BFZero = gl_ZERO
toConstantBF BFOne = gl_ONE
toConstantBF BFSrcColor = gl_SRC_COLOR
toConstantBF BFOneMinusSrcColor = gl_ONE_MINUS_SRC_COLOR
toConstantBF BFDstColor = gl_DST_COLOR
toConstantBF BFOneMinusDstColor = gl_ONE_MINUS_DST_COLOR
toConstantBF BFSrcAlpha = gl_SRC_ALPHA
toConstantBF BFOneMinusSrcAlpha = gl_ONE_MINUS_SRC_ALPHA
toConstantBF BFDstAlpha = gl_DST_ALPHA
toConstantBF BFOneMinusDstAlpha = gl_ONE_MINUS_DST_ALPHA
toConstantBF BFConstantColor = gl_CONSTANT_COLOR
toConstantBF BFOneMinusConstantColor = gl_ONE_MINUS_CONSTANT_COLOR
toConstantBF BFConstantAlpha = gl_CONSTANT_ALPHA
toConstantBF BFOneMinusConstantAlpha = gl_ONE_MINUS_CONSTANT_ALPHA
toConstantBF BFSrcAlphaSaturate = gl_SRC_ALPHA_SATURATE
data BlendSpec = BlendSpec
{ alphaEquation :: !BlendEquation
, colorEquation :: !BlendEquation
, srcColorFunc :: !BlendFunc
, srcAlphaFunc :: !BlendFunc
, dstColorFunc :: !BlendFunc
, dstAlphaFunc :: !BlendFunc
, blendColor :: !Color }
deriving ( Eq, Ord, Show, Read, Typeable )
setBlendings :: BlendSpec -> IO ()
setBlendings (BlendSpec{..}) = do
glBlendFuncSeparate (toConstantBF srcColorFunc)
(toConstantBF dstColorFunc)
(toConstantBF srcAlphaFunc)
(toConstantBF dstAlphaFunc)
glBlendEquationSeparate (toConstantBE colorEquation)
(toConstantBE alphaEquation)
glBlendColor (CFloat $ viewRed blendColor)
(CFloat $ viewGreen blendColor)
(CFloat $ viewBlue blendColor)
(CFloat $ viewAlpha blendColor)
withBlendings :: BlendSpec
-> IO a
-> IO a
withBlendings spec@(BlendSpec {..}) action = do
old_be_color <- gi gl_BLEND_EQUATION_RGB
old_be_alpha <- gi gl_BLEND_EQUATION_ALPHA
old_src_color <- gi gl_BLEND_SRC_RGB
old_src_alpha <- gi gl_BLEND_SRC_ALPHA
old_dst_color <- gi gl_BLEND_DST_RGB
old_dst_alpha <- gi gl_BLEND_DST_ALPHA
allocaArray 4 $ \color_ptr -> do
glGetFloatv gl_BLEND_COLOR color_ptr
r <- peekElemOff color_ptr 0
g <- peekElemOff color_ptr 1
b <- peekElemOff color_ptr 2
a <- peekElemOff color_ptr 3
finally (setBlendings spec >> action) $ do
glBlendColor r g b a
glBlendFuncSeparate old_src_color
old_dst_color
old_src_alpha
old_dst_alpha
glBlendEquationSeparate old_be_color
old_be_alpha