1 /*
2  * DSFML - The Simple and Fast Multimedia Library for D
3  *
4  * Copyright (c) 2013 - 2017 Jeremy DeHaan (dehaan.jeremiah@gmail.com)
5  *
6  * This software is provided 'as-is', without any express or implied warranty.
7  * In no event will the authors be held liable for any damages arising from the
8  * use of this software.
9  *
10  * Permission is granted to anyone to use this software for any purpose,
11  * including commercial applications, and to alter it and redistribute it
12  * freely, subject to the following restrictions:
13  *
14  * 1. The origin of this software must not be misrepresented; you must not claim
15  * that you wrote the original software. If you use this software in a product,
16  * an acknowledgment in the product documentation would be appreciated but is
17  * not required.
18  *
19  * 2. Altered source versions must be plainly marked as such, and must not be
20  * misrepresented as being the original software.
21  *
22  * 3. This notice may not be removed or altered from any source distribution
23  */
24 
25 /**
26  * $(U BlendMode) is a structure that represents a blend mode. A blend mode
27  * determines how the colors of an object you draw are mixed with the colors
28  * that are already in the buffer.
29  *
30  * The class is composed of 6 components, each of which has its
31  * own public member variable:
32  * $(UL
33  * $(LI Color Source Factor (colorSrcFactor))
34  * $(LI Color Destination Factor (colorDstFactor))
35  * $(LI Color Blend Equation (colorEquation))
36  * $(LI Alpha Source Factor (alphaSrcFactor))
37  * $(LI Alpha Destination Factor (alphaDstFactor))
38  * $(LI Alpha Blend Equation (alphaEquation)))
39  * $(PARA
40  * The source factor specifies how the pixel you are drawing contributes to the
41  * final color. The destination factor specifies how the pixel already drawn in
42  * the buffer contributes to the final color.
43  *
44  * The color channels RGB (red, green, blue; simply referred to as color) and A
45  * (alpha; the transparency) can be treated separately. This separation can be
46  * useful for specific blend modes, but most often you won't need it and will
47  * simply treat the color as a single unit.
48  *
49  * The blend factors and equations correspond to their OpenGL equivalents. In
50  * general, the color of the resulting pixel is calculated according to the
51  * following formula ($(I src) is the color of the source pixel, $(I dst) the
52  * color of the destination pixel, the other variables correspond to the
53  * public members, with the equations being `+` or `-` operators):)
54  * ---
55  * dst.rgb = colorSrcFactor * src.rgb (colorEquation) colorDstFactor * dst.rgb
56  * dst.a   = alphaSrcFactor * src.a   (alphaEquation) alphaDstFactor * dst.a
57  * ---
58  *
59  * $(PARA All factors and colors are represented as floating point numbers
60  * between 0 and 1. Where necessary, the result is clamped to fit in that range.
61  *
62  * The most common blending modes are defined as constants inside of
63  * $(U BlendMode):)
64  * ---
65  * auto alphaBlending          = BlendMode.Alpha;
66  * auto additiveBlending       = BlendMode.Add;
67  * auto multiplicativeBlending = BlendMode.Multiply;
68  * auto noBlending             = BlendMode.None;
69  * ---
70  *
71  * $(PARA In DSFML, a blend mode can be specified every time you draw a Drawable
72  * object to a render target. It is part of the RenderStates compound
73  * that is passed to the member function RenderTarget::draw().)
74  *
75  * See_Also:
76  * $(RENDERSTATES_LINK), $(RENDERTARGET_LINK)
77  */
78 module dsfml.graphics.blendmode;
79 
80 /**
81  * Blending modes for drawing.
82  */
83 struct BlendMode
84 {
85     /**
86      * Enumeration of the blending factors.
87      *
88      * The factors are mapped directly to their OpenGL equivalents,
89      * specified by `glBlendFunc()` or `glBlendFuncSeparate()`.
90      */
91     enum Factor
92     {
93         /// (0, 0, 0, 0)
94         Zero,
95         /// (1, 1, 1, 1)
96         One,
97         /// (src.r, src.g, src.b, src.a)
98         SrcColor,
99         /// (1, 1, 1, 1) - (src.r, src.g, src.b, src.a)
100         OneMinunSrcColor,
101         /// (dst.r, dst.g, dst.b, dst.a)
102         DstColor,
103         /// (1, 1, 1, 1) - (dst.r, dst.g, dst.b, dst.a)
104         OneMinusDstColor,
105         /// (src.a, src.a, src.a, src.a)
106         SrcAlpha,
107         /// (1, 1, 1, 1) - (src.a, src.a, src.a, src.a)
108         OneMinusSrcAlpha,
109         /// (dst.a, dst.a, dst.a, dst.a)
110         DstAlpha,
111         /// (1, 1, 1, 1) - (dst.a, dst.a, dst.a, dst.a)
112         OneMinusDstAlpha
113     }
114 
115     /**
116      * Enumeration of the blending equations
117      *
118      * The equations are mapped directly to their OpenGL equivalents,
119      * specified by glBlendEquation() or glBlendEquationSeparate().
120      */
121     enum Equation
122     {
123         /// Pixel = Src * SrcFactor + Dst * DstFactor
124         Add,
125         /// Pixel = Src * SrcFactor - Dst * DstFactor
126         Subtract,
127         /// Pixel = Dst * DstFactor - Src * SrcFactor
128         ReverseSubtract
129     }
130 
131     /// Blend source and dest according to dest alpha.
132     enum Alpha = BlendMode(Factor.SrcAlpha, Factor.OneMinusSrcAlpha,
133                Equation.Add, Factor.One, Factor.OneMinusSrcAlpha, Equation.Add);
134     /// Add source to dest.
135     enum Add = BlendMode(Factor.SrcAlpha, Factor.One, Equation.Add,
136                          Factor.One, Factor.One, Equation.Add);
137     /// Multiply source and dest.
138     enum Multiply = BlendMode(Factor.DstColor, Factor.Zero, Equation.Add,
139                               Factor.DstColor, Factor.Zero, Equation.Add);
140     /// Overwrite dest with source.
141     enum None = BlendMode(Factor.One, Factor.Zero, Equation.Add, Factor.One,
142                           Factor.Zero, Equation.Add);
143 
144 
145     /// Source blending factor for the color channels.
146     Factor colorSrcFactor = Factor.SrcAlpha;
147     /// Destination blending factor for the color channels.
148     Factor colorDstFactor = Factor.OneMinusSrcAlpha;
149     /// Blending equation for the color channels.
150     Equation colorEquation = Equation.Add;
151     /// Source blending factor for the alpha channel.
152     Factor alphaSrcFactor = Factor.One;
153     /// Destination blending factor for the alpha channel.
154     Factor alphaDstFactor = Factor.OneMinusSrcAlpha;
155     /// Blending equation for the alpha channel.
156     Equation alphaEquation = Equation.Add;
157 
158     /**
159      * Construct the blend mode given the factors and equation.
160      *
161      * This constructor uses the same factors and equation for both
162      * color and alpha components. It also defaults to the Add equation.
163      *
164      * Params:
165      * sourceFactor      = Specifies how to compute the source factor for the
166                            color and alpha channels
167      * destinationFactor = Specifies how to compute the destination factor for
168                            the color and alpha channels
169      * blendEquation     = Specifies how to combine the source and destination
170                            colors and alpha
171      */
172     this(Factor sourceFactor, Factor destinationFactor,
173          Equation blendEquation = Equation.Add)
174     {
175         colorSrcFactor = sourceFactor;
176         colorDstFactor = destinationFactor;
177         colorEquation = blendEquation;
178 
179         alphaSrcFactor = sourceFactor;
180         alphaDstFactor = destinationFactor;
181         alphaEquation = blendEquation;
182     }
183 
184     /**
185      * Construct the blend mode given the factors and equation.
186      *
187      * Params:
188      * colorSourceFactor      = Specifies how to compute the source factor for
189                                 the color channels
190      * colorDestinationFactor = Specifies how to compute the destination factor
191                                 for the color channels
192      * colorBlendEquation     = Specifies how to combine the source and
193                                 destination colors
194      * alphaSourceFactor      = Specifies how to compute the source factor
195      * alphaDestinationFactor = Specifies how to compute the destination factor
196      * alphaBlendEquation     = Specifies how to combine the source and
197                                 destination alphas
198      */
199     this(Factor colorSourceFactor, Factor colorDestinationFactor,
200               Equation colorBlendEquation, Factor alphaSourceFactor,
201               Factor alphaDestinationFactor, Equation alphaBlendEquation)
202     {
203         colorSrcFactor = colorSourceFactor;
204         colorDstFactor = colorDestinationFactor;
205         colorEquation = colorBlendEquation;
206 
207         alphaSrcFactor = alphaSourceFactor;
208         alphaDstFactor = alphaDestinationFactor;
209         alphaEquation = alphaBlendEquation;
210     }
211 
212     bool opEquals(BlendMode rhs) const
213 	{
214 		return (colorSrcFactor == rhs.colorSrcFactor &&
215                 colorDstFactor == rhs.colorDstFactor &&
216                 colorEquation == rhs.colorEquation   &&
217                 alphaSrcFactor == rhs.alphaSrcFactor &&
218                 alphaDstFactor == rhs.alphaDstFactor &&
219                 alphaEquation == rhs.alphaEquation );
220 	}
221 }