Safe Haskell | None |
---|---|
Language | Haskell2010 |
- enableBlending :: Blending -> IO ()
- disableBlending :: IO ()
- basicBlending :: Blending
- data Blending = Blending {
- sFactor :: BlendFactor
- dFactor :: BlendFactor
- blendFunc :: BlendEquation
- blendColor :: (Float, Float, Float, Float)
- data BlendFactor
- data BlendEquation
Documentation
When blending is enabled, colors written to the color buffer will be blended using a formula with the color already there. The three options for the formula are:
- S*s + D*d (
FuncAdd
, the default) - S*s - D*d (
FuncSubtract
) - D*d - S*s (
FuncReverseSubtract
)
where S and D are source and destination color components respectively. The
factors s and d are computed blending factors which can depend on the alpha
component of the source pixel, the destination pixel, or a specified
constant color. See basicBlending
for a common choice.
enableBlending :: Blending -> IO () Source
Enable blending with the specified blending parameters.
disableBlending :: IO () Source
Disable alpha blending.
basicBlending :: Blending Source
This blending configuration is suitable for ordinary alpha blending transparency effects.
Blending { sFactor = BlendSourceAlpha , dFactor = BlendOneMinusSourceAlpha , blendFunc = FuncAdd }
Blending parameters.
Blending | |
|
data BlendFactor Source
Blending factors.
Eq BlendFactor Source | |
Ord BlendFactor Source | |
Read BlendFactor Source | |
Show BlendFactor Source | |
ToGL BlendFactor Source |
data BlendEquation Source
Blending functions.
FuncAdd | the default |
FuncSubtract | |
FuncReverseSubtract |
Eq BlendEquation Source | |
Ord BlendEquation Source | |
Read BlendEquation Source | |
Show BlendEquation Source | |
ToGL BlendEquation Source |
Example
This program draws two half-transparent shapes. When you press a key they are rendered in the opposite order. This makes one appear as if it were in front of the other. Because the depth test (see Graphics.GL.Low.Depth) must be disabled while using this kind of blending, there may be significant overdraw in areas with many blending layers. This can harm performance. Also the order-dependency can make using alpha blending in a 3D scene complex or impossible. It may make more sense to use an off-screen render pass (see Graphics.GL.Low.Framebuffer) and an appropriate shader to simulate transparency effects.
module Main where import Control.Monad.Loops (whileM_) import qualified Data.Vector.Storable as V import Control.Concurrent.STM import qualified Graphics.UI.GLFW as GLFW import Linear import Graphics.GL.Low main = do GLFW.init GLFW.windowHint (GLFW.WindowHint'ContextVersionMajor 3) GLFW.windowHint (GLFW.WindowHint'ContextVersionMinor 2) GLFW.windowHint (GLFW.WindowHint'OpenGLForwardCompat True) GLFW.windowHint (GLFW.WindowHint'OpenGLProfile GLFW.OpenGLProfile'Core) mwin <- GLFW.createWindow 640 480 "Blending" Nothing Nothing case mwin of Nothing -> putStrLn "createWindow failed" Just win -> do GLFW.makeContextCurrent (Just win) GLFW.swapInterval 1 shouldSwap <- newTVarIO False (GLFW.setKeyCallback win . Just) (_ _ _ _ _ -> atomically (modifyTVar shouldSwap not)) (vao, prog) <- setup whileM_ (not <$> GLFW.windowShouldClose win) $ do GLFW.pollEvents draw vao prog shouldSwap GLFW.swapBuffers win setup = do vao <- newVAO bindVAO vao vsource <- readFile "blending.vert" fsource <- readFile "blending.frag" prog <- newProgram vsource fsource useProgram prog let blob = V.fromList [ -0.5, 0.5 , 0.5, 0 , -0.5, -0.5 ] :: V.Vector Float vbo <- newBufferObject blob StaticDraw bindVBO vbo setVertexLayout [Attrib "position" 2 GLFloat] enableBlending basicBlending return (vao, prog) draw vao prog shouldSwap = do clearColorBuffer (0,0,0) yes <- readTVarIO shouldSwap if yes then sequence [drawRed, drawGreen] else sequence [drawGreen, drawRed] drawGreen = do setUniform3f "color" [V3 0 1 0] setUniform1f "alpha" [0.5] setUniform44 "move" [identity] drawTriangles 3 drawRed = do let ninety = pi/2 let move = mkTransformation (axisAngle (V3 0 0 1) ninety) (V3 0.25 0.5 0) setUniform3f "color" [V3 1 0 0] setUniform1f "alpha" [0.5] setUniform44 "move" [transpose move] drawTriangles 3
blending.vert
#version 150 in vec3 Color; in float Alpha; out vec4 outColor; void main() { outColor = vec4(Color, Alpha); }
blending.frag
#version 150 uniform vec3 color; uniform float alpha; uniform mat4 move; in vec2 position; out vec3 Color; out float Alpha; void main() { gl_Position = move * vec4(position, 0.0, 1.0); Color = color; Alpha = alpha; }