luminance-0.10: src/Graphics/Luminance/Core/Blending.hs
-----------------------------------------------------------------------------
-- |
-- Copyright : (C) 2015, 2016 Dimitri Sabadie
-- License : BSD3
--
-- Maintainer : Dimitri Sabadie <dimitri.sabadie@gmail.com>
-- Stability : experimental
-- Portability : portable
--
-- That module exports blending-related types and functions.
--
-- Given two pixels @src@ and @dst@ – source and destination, we associate
-- each pixel a /blending factor/ – respectively, @srcK@ and @dstK@. @src@ is
-- the pixel being computed, and @dst@ is the pixel that is already stored in
-- the framebuffer.
--
-- The pixels can be blended in several ways. See the documentation of
-- 'BlendingMode' for further details.
--
-- The factors are encoded with 'BlendingFactor'.
-----------------------------------------------------------------------------
module Graphics.Luminance.Core.Blending where
import Control.Monad.IO.Class ( MonadIO(..) )
import Graphics.GL
-- |All different blending modes.
--
-- 'Additive' represents the following blending equation:
--
-- @blended = src * srcK + dst * dstK@
--
-- 'Subtract' represents the following blending equation:
--
-- @blended = src * srcK - dst * dstK@
--
-- Because subtracting is not commutating, 'ReverseSubtract' represents the following additional
-- blending equation:
--
-- @blended = dst * dstK - src * srcK@
--
-- 'Min' represents the following blending equation:
--
-- @blended = 'min' src dst@
--
-- 'Max' represents the following blending equation:
--
-- @blended = 'max' src dst@
data BlendingMode
= Additive
| Subtract
| ReverseSubtract
| Min
| Max
deriving (Eq,Show)
fromBlendingMode :: BlendingMode -> GLenum
fromBlendingMode m = case m of
Additive -> GL_FUNC_ADD
Subtract -> GL_FUNC_SUBTRACT
ReverseSubtract -> GL_FUNC_REVERSE_SUBTRACT
Min -> GL_MIN
Max -> GL_MAX
-- |Blending factors.
data BlendingFactor
= One -- ^ 1 * color = factor
| Zero -- ^ 0 * color = 0
| SrcColor -- ^ src * color
| NegativeSrcColor -- ^ (1 - src) * color
| DestColor -- ^ dst * color
| NegativeDestColor -- ^ (1 - dst) * color
| SrcAlpha -- ^ srcA * color
| NegativeSrcAlpha -- ^ (1 - src) * color
| DstAlpha -- ^ dstA * color
| NegativeDstAlpha -- ^ (1 - dstA) * color
{-
| ConstantColor
| NegativeConstantColor
| ConstantAlpha
| NegativeConstantAlpha
-}
| SrcAlphaSaturate
deriving (Eq,Show)
fromBlendingFactor :: BlendingFactor -> GLenum
fromBlendingFactor f = case f of
One -> GL_ONE
Zero -> GL_ZERO
SrcColor -> GL_SRC_COLOR
NegativeSrcColor -> GL_ONE_MINUS_SRC_COLOR
DestColor -> GL_DST_COLOR
NegativeDestColor -> GL_ONE_MINUS_DST_COLOR
SrcAlpha -> GL_SRC_ALPHA
NegativeSrcAlpha -> GL_ONE_MINUS_SRC_ALPHA
DstAlpha -> GL_DST_ALPHA
NegativeDstAlpha -> GL_ONE_MINUS_DST_ALPHA
-- ConstantColor -> GL_CONSTANT_COLOR
-- NegativeConstantColor -> GL_ONE_MINUS_CONSTANT_COLOR
-- ConstantAlpha -> GL_CONSTANT_ALPHA
-- NegativeConstantAlpha -> GL_ONE_MINUS_CONSTANT_ALPHA
SrcAlphaSaturate -> GL_SRC_ALPHA_SATURATE
-- Sets blending mode and both factors after having initialized the blending if something is
-- passed. If 'Nothing', that function disables the blending.
setBlending :: (MonadIO m) => Maybe (BlendingMode,BlendingFactor,BlendingFactor) -> m ()
setBlending blending = liftIO $ case blending of
Just (mode,src,dst) -> do
glEnable GL_BLEND
glBlendEquation (fromBlendingMode mode)
glBlendFunc (fromBlendingFactor src) (fromBlendingFactor dst)
Nothing -> glDisable GL_BLEND