d84bfff6934c1fe6bfd75899b716af4dd6686ce3
[platform/core/uifw/dali-core.git] / dali / public-api / shader-effects / shader-effect.h
1 #ifndef __DALI_SHADER_EFFECT_H__
2 #define __DALI_SHADER_EFFECT_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // INTERNAL INCLUDES
22 #include <dali/public-api/animation/active-constraint-declarations.h>
23 #include <dali/public-api/object/constrainable.h>
24
25 namespace Dali
26 {
27
28 /**
29  * @brief DALI_COMPOSE_SHADER macro provides a convenient way to write shader source code.
30  *
31  * We normally use double quotation marks to write a string such as "Hello World".
32  * However many symbols are needed to add multiple lines of string.
33  * We don't need to write quotation marks using this macro at every line.
34  *
35  * [An example of double quotation marks usage]
36  * const string FRAGMENT_SHADER_SOURCE = \
37  * "  void main()\n"
38  * "  {\n"
39  * "    gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n"
40  * "  }\n";
41  *
42  * [An example of DALI_COMPOSE_SHADER usage]
43  * const string VERTEX_SHADER_SOURCE = DALI_COMPOSE_SHADER (
44  *   void main()
45  *   {
46  *     gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);
47  *     vTexCoord = aTexCoord;
48  *   }
49  * );
50  */
51 #define DALI_COMPOSE_SHADER(STR) #STR
52
53 class Constraint;
54 class Image;
55 struct Vector2;
56 struct Vector3;
57 struct Vector4;
58
59 namespace Internal DALI_INTERNAL
60 {
61 class ShaderEffect;
62 }
63
64 /**
65  * @brief GeometryType determines how geometry is shaped.
66  */
67 enum GeometryType
68 {
69   GEOMETRY_TYPE_IMAGE = 0x01,         ///< image, with flat color or texture
70   GEOMETRY_TYPE_UNTEXTURED_MESH = 0x02,///< Complex meshes, with flat color
71   GEOMETRY_TYPE_TEXTURED_MESH = 0x04, ///< Complex meshes, with texture
72   GEOMETRY_TYPE_LAST = 0x08
73 };
74
75 /**
76  * @brief Shader effects provide a visual effect for actors.
77  *
78  * For a Custom shader you can provide the vertex and fragment shader code as strings.
79  * These shader snippets get concatenated with the default attributes and uniforms.
80  * For a vertex shader this part contains the following code:
81  * <pre>
82  * precision highp float;
83  * attribute vec3  aPosition;
84  * attribute vec2  aTexCoord;
85  * uniform   mat4  uMvpMatrix;
86  * uniform   mat4  uModelMatrix;
87  * uniform   mat4  uViewMatrix;
88  * uniform   mat4  uModelView;
89  * uniform   mat3  uNormalMatrix;
90  * uniform   mat4  uProjection;
91  * uniform   vec4  uColor;
92  * varying   vec2  vTexCoord;
93  * </pre>
94  * The custom shader part is expected to output the vertex position and texture coordinate.
95  * A basic custom vertex shader would contain the following code:
96  * <pre>
97  * void main()
98  * {
99  *   gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);
100  *   vTexCoord = aTexCoord;
101  * }
102  * </pre>
103  * For fragment shader the default part for images contains the following code:
104  * <pre>
105  * precision mediump float;
106  * uniform   sampler2D sTexture;
107  * uniform   sampler2D sEffect;
108  * uniform   vec4      uColor;
109  * varying   vec2      vTexCoord;
110  * </pre>
111  * <BR>
112  * <B>
113  * Note: In order for fade and color animations to work, the fragment shader needs to multiply the fragment color
114  * with the uniform color "uColor" of the node
115  * </B>
116  */
117 class DALI_IMPORT_API ShaderEffect : public Constrainable
118 {
119 public:
120   /**
121    * @brief The Extension class is a base class for objects that can be attached to the
122    * ShaderEffects as extensions.
123    *
124    * Extensions are useful to create pimpled implementations of custom shaders.
125    * The shader effect will hold an intrusive pointer to the extension.
126    */
127   class Extension : public RefObject
128   {
129   protected:
130     /**
131      * @brief Disable default constructor. This a base class is not meant to be initialised on its own.
132      */
133     Extension();
134
135     /**
136      * @brief Virtual destructor.
137      */
138     virtual ~Extension();
139   };
140
141   // Default Properties
142   /* Grid Density defines the spacing of vertex coordinates in world units.
143    * ie a larger actor will have more grids at the same spacing.
144    *
145    *  +---+---+         +---+---+---+
146    *  |   |   |         |   |   |   |
147    *  +---+---+         +---+---+---+
148    *  |   |   |         |   |   |   |
149    *  +---+---+         +---+---+---+
150    *                    |   |   |   |
151    *                    +---+---+---+
152    */
153   static const Property::Index GRID_DENSITY;       ///< name "grid-density",   type FLOAT
154   static const Property::Index IMAGE;              ///< name "image",          type MAP; {"filename":"", "load-policy":...}
155   static const Property::Index PROGRAM;            ///< name "program",        type MAP; {"vertex-prefix":"","fragment-prefix":"","vertex":"","fragment":""}
156   static const Property::Index GEOMETRY_HINTS;     ///< name "geometry-hints", type INT (bitfield) values from enum GeometryHints
157
158   static const float DEFAULT_GRID_DENSITY;         ///< The default density is 40 pixels
159
160   /**
161    * @brief Hints for rendering/subdividing geometry.
162    */
163   enum GeometryHints
164   {
165     HINT_NONE           = 0x00,   ///< no hints
166     HINT_GRID_X         = 0x01,   ///< Geometry must be subdivided in X
167     HINT_GRID_Y         = 0x02,   ///< Geometry must be subdivided in Y
168     HINT_GRID           = (HINT_GRID_X | HINT_GRID_Y),
169     HINT_DEPTH_BUFFER   = 0x04,   ///< Needs depth buffering turned on
170     HINT_BLENDING       = 0x08,   ///< Notifies the actor to use blending even if it's fully opaque. Needs actor's blending set to BlendingMode::AUTO
171     HINT_DOESNT_MODIFY_GEOMETRY = 0x10 ///< Notifies that the vertex shader will not change geometry (enables bounding box culling)
172   };
173
174   /**
175    * @brief Coordinate type of the shader uniform.
176    *
177    * Viewport coordinate types will convert from viewport to view space.
178    * Use this coordinate type if your are doing a transformation in view space.
179    * The texture coordinate type converts a value in actor local space to texture coodinates.
180    * This is useful for pixel shaders and accounts for texture atlas.
181    */
182   enum UniformCoordinateType
183   {
184     COORDINATE_TYPE_DEFAULT,           ///< Default, No transformation to be applied
185     COORDINATE_TYPE_VIEWPORT_POSITION, ///< The uniform is a position vector in viewport coordinates that needs to be converted to GL view space coordinates.
186     COORDINATE_TYPE_VIEWPORT_DIRECTION ///< The uniform is a directional vector in viewport coordinates that needs to be converted to GL view space coordinates.
187   };
188
189   /**
190    * @brief Create an empty ShaderEffect.
191    *
192    * This can be initialised with ShaderEffect::New(...)
193    */
194   ShaderEffect();
195
196   /**
197    * @brief Create ShaderEffect.
198    *
199    * @param vertexShader code for the effect. If you pass in an empty string, the default version will be used
200    * @param fragmentShader code for the effect. If you pass in an empty string, the default version will be used
201    * @param type GeometryType to define the shape of the geometry
202    * @param hints GeometryHints to define the geometry of the rendered object
203    * @return A handle to a shader effect
204    */
205   static ShaderEffect New( const std::string& vertexShader,
206                            const std::string& fragmentShader,
207                            GeometryType type = GeometryType(GEOMETRY_TYPE_IMAGE),
208                            GeometryHints hints = GeometryHints(HINT_NONE) );
209
210   /**
211    * @brief Create ShaderEffect.
212    * @param vertexShaderPrefix code for the effect. It will be inserted before the default uniforms (ideal for \#defines)
213    * @param vertexShader code for the effect. If you pass in an empty string, the default version will be used
214    * @param fragmentShaderPrefix code for the effect. It will be inserted before the default uniforms (ideal for \#defines)
215    * @param fragmentShader code for the effect. If you pass in an empty string, the default version will be used
216    * @param type GeometryType to define the shape of the geometry
217    * @param hints GeometryHints to define the geometry of the rendered object
218    * @return A handle to a shader effect
219    */
220   static ShaderEffect NewWithPrefix(const std::string& vertexShaderPrefix,
221                                     const std::string& vertexShader,
222                                     const std::string& fragmentShaderPrefix,
223                                     const std::string& fragmentShader,
224                                     GeometryType type = GeometryType(GEOMETRY_TYPE_IMAGE),
225                                     GeometryHints hints = GeometryHints(HINT_NONE) );
226
227   /**
228    * @brief Downcast an Object handle to ShaderEffect.
229    *
230    * If handle points to a ShaderEffect the downcast produces valid
231    * handle. If not the returned handle is left uninitialized.
232    *
233    * @param[in] handle to An object
234    * @return handle to a ShaderEffect object or an uninitialized handle
235    */
236   static ShaderEffect DownCast( BaseHandle handle );
237
238   /**
239    * @brief Destructor
240    *
241    * This is non-virtual since derived Handle types must not contain data or virtual methods.
242    */
243   ~ShaderEffect();
244
245   /**
246    * @brief Copy constructor
247    *
248    * @param object A reference to a ShaderEffect object
249    */
250   ShaderEffect(const ShaderEffect& object);
251
252   /**
253    * @brief This assignment operator is required for (smart) pointer semantics.
254    *
255    * @param [in] rhs  A reference to the copied handle
256    * @return A reference to this
257    */
258   ShaderEffect& operator=(const ShaderEffect& rhs);
259
260   /**
261    * @brief Sets image for using as effect texture.
262    *
263    * This image texture will be bound to the "sEffect" sampler
264    * so it can be used in fragment shader for effects
265    *
266    * @param[in] image to use as effect texture
267    */
268   void SetEffectImage( Image image );
269
270   /**
271    * @brief Set a uniform value.
272    * This will register a property of type Property::FLOAT; see Object::RegisterProperty() for more details.
273    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
274    * @pre Either the property name is not in use, or a property exists with the correct name & type.
275    * @param name The name of the uniform.
276    * @param value The value to to set.
277    * @param uniformCoordinateType The coordinate type of the uniform.
278    */
279   void SetUniform( const std::string& name,
280                    float value,
281                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
282
283   /**
284    * @brief Set a uniform value.
285    *
286    * This will register a property of type Property::VECTOR2; see Object::RegisterProperty() for more details.
287    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
288    * @pre Either the property name is not in use, or a property exists with the correct name & type.
289    * @param name The name of the uniform.
290    * @param value The value to to set.
291    * @param uniformCoordinateType The coordinate type of the uniform.
292    */
293   void SetUniform( const std::string& name,
294                    Vector2 value,
295                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
296
297   /**
298    * @brief Set a uniform value.
299    *
300    * This will register a property of type Property::VECTOR3; see Object::RegisterProperty() for more details.
301    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
302    * @pre Either the property name is not in use, or a property exists with the correct name & type.
303    * @param name The name of the uniform.
304    * @param value The value to to set.
305    * @param uniformCoordinateType The coordinate type of the uniform.
306    */
307   void SetUniform( const std::string& name,
308                    Vector3 value,
309                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
310
311   /**
312    * @brief Set a uniform value.
313    *
314    * This will register a property of type Property::VECTOR4; see Object::RegisterProperty() for more details.
315    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
316    * @pre Either the property name is not in use, or a property exists with the correct name & type.
317    * @param name The name of the uniform.
318    * @param value The value to to set.
319    * @param uniformCoordinateType The coordinate type of the uniform.
320    */
321   void SetUniform( const std::string& name,
322                    Vector4 value,
323                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
324
325   /**
326    * @brief Set a uniform value.
327    *
328    * This will register a property of type Property::MATRIX; see Object::RegisterProperty() for more details.
329    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
330    * @pre Either the property name is not in use, or a property exists with the correct name & type.
331    * @param name The name of the uniform.
332    * @param value The value to to set.
333    * @param uniformCoordinateType The coordinate type of the uniform.
334    */
335   void SetUniform( const std::string& name,
336                    const Matrix& value,
337                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
338
339   /**
340    * @brief Set a uniform value.
341    *
342    * This will register a property of type Property::MATRIX3; see Object::RegisterProperty() for more details.
343    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
344    * @pre Either the property name is not in use, or a property exists with the correct name & type.
345    * @param name The name of the uniform.
346    * @param value The value to to set.
347    * @param uniformCoordinateType The coordinate type of the uniform.
348    */
349   void SetUniform( const std::string& name,
350                    const Matrix3& value,
351                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
352
353   /**
354    * @brief Attach an extension object.
355    *
356    * This object is reference counted and will be automatically deleted.
357    * This object can be retrieved back with the GetExtension function.
358    * @param object Pointer to a Extension.
359    * @pre extension is not NULL
360    */
361   void AttachExtension( Extension *object );
362
363   /**
364    * @brief Retrieve the attached extension object.
365    *
366    * This object can be set with the AttachExtension function.
367    * @return implementation Pointer to a Extension.
368    * @pre An extension needs to be attached previously.
369    */
370   Extension& GetExtension();
371
372   /**
373    * @brief Retrieve the attached extension object.
374    *
375    * This object can be set with the AttachExtension function.
376    * @return implementation Pointer to a Extension.
377    * @pre An extension needs to be attached previously.
378    */
379   const Extension& GetExtension() const;
380
381
382 public: // Not intended for application developers
383
384   /**
385    * @brief This constructor is used by Dali New() methods.
386    * @param [in] effect A pointer to a newly allocated Dali resource.
387    */
388   explicit DALI_INTERNAL ShaderEffect(Internal::ShaderEffect* effect);
389 };
390
391 } // namespace Dali
392
393 #endif // __DALI_SHADER_EFFECT_H__