1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4     (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2013 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #ifndef __BLENDMODE_H__
29 #define __BLENDMODE_H__
30 
31 #include "OgrePrerequisites.h"
32 #include "OgreColourValue.h"
33 
34 namespace Ogre {
35 	/** \addtogroup Core
36 	*  @{
37 	*/
38 	/** \addtogroup Materials
39 	*  @{
40 	*/
41 
42     /** Type of texture blend mode.
43     */
44     enum LayerBlendType
45     {
46         LBT_COLOUR,
47         LBT_ALPHA
48     };
49 
50     /** List of valid texture blending operations, for use with TextureUnitState::setColourOperation.
51         @remarks
52             This list is a more limited list than LayerBlendOperationEx because it only
53             includes operations that are supportable in both multipass and multitexture
54             rendering and thus provides automatic fallback if multitexture hardware
55             is lacking or insufficient.
56     */
57     enum LayerBlendOperation {
58         /// Replace all colour with texture with no adjustment
59         LBO_REPLACE,
60         /// Add colour components together.
61         LBO_ADD,
62         /// Multiply colour components together.
63         LBO_MODULATE,
64         /// Blend based on texture alpha
65         LBO_ALPHA_BLEND
66 
67     };
68 
69     /** Expert list of valid texture blending operations, for use with TextureUnitState::setColourOperationEx
70         and TextureUnitState::setAlphaOperation, and internally in the LayerBlendModeEx class. It's worth
71         noting that these operations are for blending <i>between texture layers</i> and not between rendered objects
72         and the existing scene. Because all of these modes are only supported in multitexture hardware it may be
73         required to set up a fallback operation where this hardware is not available.
74     */
75     enum LayerBlendOperationEx {
76         /// use source1 without modification
77         LBX_SOURCE1,
78         /// use source2 without modification
79         LBX_SOURCE2,
80         /// multiply source1 and source2 together
81         LBX_MODULATE,
82         /// as LBX_MODULATE but brighten afterwards (x2)
83         LBX_MODULATE_X2,
84         /// as LBX_MODULATE but brighten more afterwards (x4)
85         LBX_MODULATE_X4,
86         /// add source1 and source2 together
87         LBX_ADD,
88         /// as LBX_ADD, but subtract 0.5 from the result
89         LBX_ADD_SIGNED,
90         /// as LBX_ADD, but subtract product from the sum
91         LBX_ADD_SMOOTH,
92         /// subtract source2 from source1
93         LBX_SUBTRACT,
94         /// use interpolated alpha value from vertices to scale source1, then add source2 scaled by (1-alpha)
95         LBX_BLEND_DIFFUSE_ALPHA,
96         /// as LBX_BLEND_DIFFUSE_ALPHA, but use alpha from texture
97         LBX_BLEND_TEXTURE_ALPHA,
98         /// as LBX_BLEND_DIFFUSE_ALPHA, but use current alpha from previous stages
99         LBX_BLEND_CURRENT_ALPHA,
100         /// as LBX_BLEND_DIFFUSE_ALPHA but use a constant manual blend value (0.0-1.0)
101         LBX_BLEND_MANUAL,
102         /// dot product of color1 and color2
103         LBX_DOTPRODUCT,
104         /// use interpolated color values from vertices to scale source1, then add source2 scaled by (1-color)
105         LBX_BLEND_DIFFUSE_COLOUR
106     };
107 
108     /** List of valid sources of values for blending operations used
109         in TextureUnitState::setColourOperation and TextureUnitState::setAlphaOperation,
110         and internally in the LayerBlendModeEx class.
111     */
112     enum LayerBlendSource
113     {
114         /// the colour as built up from previous stages
115         LBS_CURRENT,
116         /// the colour derived from the texture assigned to this layer
117         LBS_TEXTURE,
118         /// the interpolated diffuse colour from the vertices
119         LBS_DIFFUSE,
120         /// the interpolated specular colour from the vertices
121         LBS_SPECULAR,
122         /// a colour supplied manually as a separate argument
123         LBS_MANUAL
124     };
125     /** Class which manages blending of both colour and alpha components.
126         @remarks
127             This class is a utility class used by both TextureUnitState and
128             RenderSystem to wrap up the details of a blending operation. This blending
129             operation could be used for blending colour or alpha in a texture layer.
130             This class is really only for use by OGRE, since apps can deal with
131             blending modes through the TextureUnitState class methods
132             setColourOperation and setAlphaOperation.
133         @par
134             It's worth noting that these operations are for blending <i>between texture
135             layers</i> and not between rendered objects and the existing scene. If
136             you wish to make an object blend with others in the scene, e.g. to make
137             transparent objects etc, use the Material::setSceneBlending method.
138     */
139     class _OgreExport LayerBlendModeEx
140     {
141     public:
142         /// The type of blending (colour or alpha)
143         LayerBlendType blendType;
144         /// The operation to be applied
145         LayerBlendOperationEx operation;
146         /// The first source of colour/alpha
147         LayerBlendSource source1;
148         /// The second source of colour/alpha
149         LayerBlendSource source2;
150 
151         /// Manual colour value for manual source1
152         ColourValue colourArg1;
153         /// Manual colour value for manual source2
154         ColourValue colourArg2;
155         /// Manual alpha value for manual source1
156         Real alphaArg1;
157         /// Manual alpha value for manual source2
158         Real alphaArg2;
159         /// Manual blending factor
160         Real factor;
161 
162         bool operator==(const LayerBlendModeEx& rhs) const
163         {
164             if (blendType != rhs.blendType) return false;
165 
166             if (blendType == LBT_COLOUR)
167             {
168 
169                 if (operation == rhs.operation &&
170                     source1 == rhs.source1 &&
171                     source2 == rhs.source2 &&
172                     colourArg1 == rhs.colourArg1 &&
173                     colourArg2 == rhs.colourArg2 &&
174                     factor == rhs.factor)
175                 {
176                     return true;
177                 }
178             }
179             else // if (blendType == LBT_ALPHA)
180             {
181                 if (operation == rhs.operation &&
182                     source1 == rhs.source1 &&
183                     source2 == rhs.source2 &&
184                     alphaArg1 == rhs.alphaArg1 &&
185                     alphaArg2 == rhs.alphaArg2 &&
186                     factor == rhs.factor)
187                 {
188                     return true;
189                 }
190             }
191             return false;
192         }
193 
194         bool operator!=(const LayerBlendModeEx& rhs) const
195         {
196             return !(*this == rhs);
197         }
198 
199 
200 
201     };
202 
203     /** Types of blending that you can specify between an object and the existing contents of the scene.
204         @remarks
205             As opposed to the LayerBlendType, which classifies blends between texture layers, these blending
206             types blend between the output of the texture units and the pixels already in the viewport,
207             allowing for object transparency, glows, etc.
208         @par
209             These types are provided to give quick and easy access to common effects. You can also use
210             the more manual method of supplying source and destination blending factors.
211             See Material::setSceneBlending for more details.
212         @see
213             Material::setSceneBlending
214     */
215     enum SceneBlendType
216     {
217         /// Make the object transparent based on the final alpha values in the texture
218         SBT_TRANSPARENT_ALPHA,
219         /// Make the object transparent based on the colour values in the texture (brighter = more opaque)
220         SBT_TRANSPARENT_COLOUR,
221         /// Add the texture values to the existing scene content
222         SBT_ADD,
223 		/// Multiply the 2 colours together
224 		SBT_MODULATE,
225         /// The default blend mode where source replaces destination
226         SBT_REPLACE
227         // TODO : more
228     };
229 
230     /** Blending factors for manually blending objects with the scene. If there isn't a predefined
231         SceneBlendType that you like, then you can specify the blending factors directly to affect the
232         combination of object and the existing scene. See Material::setSceneBlending for more details.
233     */
234     enum SceneBlendFactor
235     {
236         SBF_ONE,
237         SBF_ZERO,
238         SBF_DEST_COLOUR,
239         SBF_SOURCE_COLOUR,
240         SBF_ONE_MINUS_DEST_COLOUR,
241         SBF_ONE_MINUS_SOURCE_COLOUR,
242         SBF_DEST_ALPHA,
243         SBF_SOURCE_ALPHA,
244         SBF_ONE_MINUS_DEST_ALPHA,
245         SBF_ONE_MINUS_SOURCE_ALPHA
246 
247     };
248 
249 	/** Blending operations controls how objects are blended into the scene. The default operation
250 		is add (+) but by changing this you can change how drawn objects are blended into the
251 		existing scene.
252 	*/
253 	enum SceneBlendOperation
254 	{
255 		SBO_ADD,
256 		SBO_SUBTRACT,
257 		SBO_REVERSE_SUBTRACT,
258 		SBO_MIN,
259 		SBO_MAX
260 	};
261 	/** @} */
262 	/** @} */
263 
264 }
265 
266 #endif
267