New Constraints
[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/object/handle.h>
23 #include <dali/public-api/object/property-index-ranges.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 Image;
54 struct Vector2;
55 struct Vector3;
56 struct Vector4;
57
58 namespace Internal DALI_INTERNAL
59 {
60 class ShaderEffect;
61 }
62
63 /**
64  * @brief GeometryType determines how geometry is shaped.
65  */
66 enum GeometryType
67 {
68   GEOMETRY_TYPE_IMAGE = 0x01,           ///< image, with flat color or texture
69   GEOMETRY_TYPE_TEXT = 0x02,            ///< text, with flat color or texture
70   GEOMETRY_TYPE_UNTEXTURED_MESH = 0x04, ///< Complex meshes, with flat color
71   GEOMETRY_TYPE_TEXTURED_MESH = 0x08,   ///< Complex meshes, with texture
72   GEOMETRY_TYPE_LAST = 0x10
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  * and for text:
112  * <pre>
113  * \#extension GL_OES_standard_derivatives : enable
114  * uniform   mediump sampler2D sTexture;
115  * uniform   lowp    vec4      uColor;
116  * uniform   lowp    vec4      uTextColor;
117  * uniform   mediump float     uSmoothing;
118  * varying   mediump vec2      vTexCoord;
119  * </pre>
120  * and the custom shader is expected to output the fragment color.
121  * The basic fragment shader for images would contain:
122  * <pre>
123  * void main()
124  * {
125  *   gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;
126  * }
127  * </pre>
128  * and for text::
129  * <pre>
130  *  void main()
131  *  {
132  *    // sample distance field
133  *    mediump float distance = texture2D(sTexture, vTexCoord).a;
134  *    mediump float smoothWidth = fwidth(distance);
135  *    // set fragment color
136  *    lowp vec4 color = uTextColor;
137  *    // adjust alpha by sampled distance
138  *    color.a *= smoothstep(uSmoothing - smoothWidth, uSmoothing + smoothWidth, distance);
139  *    // fragment color multiplied with uColor.
140  *    glFragColor = color * uColor;
141  *  }
142  * </pre>
143  * <BR>
144  * <B>
145  * Note: In order for fade and color animations to work, the fragment shader needs to multiply the fragment color
146  * with the uniform color "uColor" of the node
147  * </B>
148  */
149 class DALI_IMPORT_API ShaderEffect : public Handle
150 {
151 public:
152
153   // Default Properties
154   /**
155    * @brief An enumeration of properties belonging to the Path class.
156    * Grid Density defines the spacing of vertex coordinates in world units.
157    * ie a larger actor will have more grids at the same spacing.
158    *
159    *  +---+---+         +---+---+---+
160    *  |   |   |         |   |   |   |
161    *  +---+---+         +---+---+---+
162    *  |   |   |         |   |   |   |
163    *  +---+---+         +---+---+---+
164    *                    |   |   |   |
165    *                    +---+---+---+
166    */
167   struct Property
168   {
169     enum
170     {
171       GRID_DENSITY = DEFAULT_ACTOR_PROPERTY_START_INDEX, ///< name "grid-density",   type float
172       IMAGE,                                             ///< name "image",          type Map {"filename":"", "load-policy":...}
173       PROGRAM,                                           ///< name "program",        type Map {"vertex-prefix":"","fragment-prefix":"","vertex":"","fragment":""}
174       GEOMETRY_HINTS                                     ///< name "geometry-hints", type int (bitfield) values from enum GeometryHints
175     };
176   };
177
178   static const float DEFAULT_GRID_DENSITY;              ///< The default density is 40 pixels
179
180   /**
181    * @brief The Extension class is a base class for objects that can be attached to the
182    * ShaderEffects as extensions.
183    *
184    * Extensions are useful to create pimpled implementations of custom shaders.
185    * The shader effect will hold an intrusive pointer to the extension.
186    */
187   class Extension : public RefObject
188   {
189   protected:
190     /**
191      * @brief Disable default constructor. This a base class is not meant to be initialised on its own.
192      */
193     Extension();
194
195     /**
196      * @brief Virtual destructor.
197      */
198     virtual ~Extension();
199   };
200
201   /**
202    * @brief Hints for rendering/subdividing geometry.
203    */
204   enum GeometryHints
205   {
206     HINT_NONE           = 0x00,   ///< no hints
207     HINT_GRID_X         = 0x01,   ///< Geometry must be subdivided in X
208     HINT_GRID_Y         = 0x02,   ///< Geometry must be subdivided in Y
209     HINT_GRID           = (HINT_GRID_X | HINT_GRID_Y),
210     HINT_DEPTH_BUFFER   = 0x04,   ///< Needs depth buffering turned on
211     HINT_BLENDING       = 0x08,   ///< Notifies the actor to use blending even if it's fully opaque. Needs actor's blending set to BlendingMode::AUTO
212     HINT_DOESNT_MODIFY_GEOMETRY = 0x10 ///< Notifies that the vertex shader will not change geometry (enables bounding box culling)
213   };
214
215   /**
216    * @brief Coordinate type of the shader uniform.
217    *
218    * Viewport coordinate types will convert from viewport to view space.
219    * Use this coordinate type if your are doing a transformation in view space.
220    * The texture coordinate type converts a value in actor local space to texture coodinates.
221    * This is useful for pixel shaders and accounts for texture atlas.
222    */
223   enum UniformCoordinateType
224   {
225     COORDINATE_TYPE_DEFAULT,           ///< Default, No transformation to be applied
226     COORDINATE_TYPE_VIEWPORT_POSITION, ///< The uniform is a position vector in viewport coordinates that needs to be converted to GL view space coordinates.
227     COORDINATE_TYPE_VIEWPORT_DIRECTION ///< The uniform is a directional vector in viewport coordinates that needs to be converted to GL view space coordinates.
228   };
229
230   /**
231    * @brief Create an empty ShaderEffect.
232    *
233    * This can be initialised with ShaderEffect::New(...)
234    */
235   ShaderEffect();
236
237   /**
238    * @brief Create ShaderEffect.
239    *
240    * @param vertexShader code for the effect. If you pass in an empty string, the default version will be used
241    * @param fragmentShader code for the effect. If you pass in an empty string, the default version will be used
242    * @param type GeometryType to define the shape of the geometry
243    * @param hints GeometryHints to define the geometry of the rendered object
244    * @return A handle to a shader effect
245    */
246   static ShaderEffect New( const std::string& vertexShader,
247                            const std::string& fragmentShader,
248                            GeometryType type = GeometryType(GEOMETRY_TYPE_IMAGE),
249                            GeometryHints hints = GeometryHints(HINT_NONE) );
250
251   /**
252    * @brief Create ShaderEffect.
253    * @param vertexShaderPrefix code for the effect. It will be inserted before the default uniforms (ideal for \#defines)
254    * @param vertexShader code for the effect. If you pass in an empty string, the default version will be used
255    * @param fragmentShaderPrefix code for the effect. It will be inserted before the default uniforms (ideal for \#defines)
256    * @param fragmentShader code for the effect. If you pass in an empty string, the default version will be used
257    * @param type GeometryType to define the shape of the geometry
258    * @param hints GeometryHints to define the geometry of the rendered object
259    * @return A handle to a shader effect
260    */
261   static ShaderEffect NewWithPrefix(const std::string& vertexShaderPrefix,
262                                     const std::string& vertexShader,
263                                     const std::string& fragmentShaderPrefix,
264                                     const std::string& fragmentShader,
265                                     GeometryType type = GeometryType(GEOMETRY_TYPE_IMAGE),
266                                     GeometryHints hints = GeometryHints(HINT_NONE) );
267
268   /**
269    * @brief Create ShaderEffect.
270    * @param imageVertexShader code for the effect. If you pass in an empty string, the default version will be used
271    * @param imageFragmentShader code for the effect. If you pass in an empty string, the default version will be used
272    * @param textVertexShader code for the effect. If you pass in an empty string, the default version will be used
273    * @param textFragmentShader code for the effect. If you pass in an empty string, the default version will be used
274    * @param hints GeometryHints to define the geometry of the rendered object
275    * @return A handle to a shader effect
276    */
277   static ShaderEffect New( const std::string& imageVertexShader,
278                            const std::string& imageFragmentShader,
279                            const std::string& textVertexShader,
280                            const std::string& textFragmentShader,
281                            GeometryHints hints = GeometryHints(HINT_NONE) );
282
283   /**
284    * @brief Create ShaderEffect.
285    * @param imageVertexShader code for the effect. If you pass in an empty string, the default version will be used
286    * @param imageFragmentShader code for the effect. If you pass in an empty string, the default version will be used
287    * @param textVertexShader code for the effect. If you pass in an empty string, the default version will be used
288    * @param textFragmentShader code for the effect. If you pass in an empty string, the default version will be used
289    * @param texturedMeshVertexShader code for the effect. If you pass in an empty string, the default version will be used
290    * @param texturedMeshFragmentShader code for the effect. If you pass in an empty string, the default version will be used
291    * @param meshVertexShader code for the effect. If you pass in an empty string, the default version will be used
292    * @param meshFragmentShader code for the effect. If you pass in an empty string, the default version will be used
293    * @param hints GeometryHints to define the geometry of the rendered object
294    * @return A handle to a shader effect
295    */
296   static ShaderEffect New( const std::string& imageVertexShader,
297                            const std::string& imageFragmentShader,
298                            const std::string& textVertexShader,
299                            const std::string& textFragmentShader,
300                            const std::string& texturedMeshVertexShader,
301                            const std::string& texturedMeshFragmentShader,
302                            const std::string& meshVertexShader,
303                            const std::string& meshFragmentShader,
304                            GeometryHints hints = GeometryHints(HINT_NONE) );
305
306   /**
307    * @brief Downcast an Object handle to ShaderEffect.
308    *
309    * If handle points to a ShaderEffect the downcast produces valid
310    * handle. If not the returned handle is left uninitialized.
311    *
312    * @param[in] handle to An object
313    * @return handle to a ShaderEffect object or an uninitialized handle
314    */
315   static ShaderEffect DownCast( BaseHandle handle );
316
317   /**
318    * @brief Destructor
319    *
320    * This is non-virtual since derived Handle types must not contain data or virtual methods.
321    */
322   ~ShaderEffect();
323
324   /**
325    * @brief Copy constructor
326    *
327    * @param object A reference to a ShaderEffect object
328    */
329   ShaderEffect(const ShaderEffect& object);
330
331   /**
332    * @brief This assignment operator is required for (smart) pointer semantics.
333    *
334    * @param [in] rhs  A reference to the copied handle
335    * @return A reference to this
336    */
337   ShaderEffect& operator=(const ShaderEffect& rhs);
338
339   /**
340    * @brief Sets image for using as effect texture.
341    *
342    * This image texture will be bound to the "sEffect" sampler
343    * so it can be used in fragment shader for effects
344    *
345    * @param[in] image to use as effect texture
346    */
347   void SetEffectImage( Image image );
348
349   /**
350    * @brief Set a uniform value.
351    * This will register a property of type Property::FLOAT; see Object::RegisterProperty() for more details.
352    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
353    * @pre Either the property name is not in use, or a property exists with the correct name & type.
354    * @param name The name of the uniform.
355    * @param value The value to to set.
356    * @param uniformCoordinateType The coordinate type of the uniform.
357    */
358   void SetUniform( const std::string& name,
359                    float value,
360                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
361
362   /**
363    * @brief Set a uniform value.
364    *
365    * This will register a property of type Property::VECTOR2; see Object::RegisterProperty() for more details.
366    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
367    * @pre Either the property name is not in use, or a property exists with the correct name & type.
368    * @param name The name of the uniform.
369    * @param value The value to to set.
370    * @param uniformCoordinateType The coordinate type of the uniform.
371    */
372   void SetUniform( const std::string& name,
373                    Vector2 value,
374                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
375
376   /**
377    * @brief Set a uniform value.
378    *
379    * This will register a property of type Property::VECTOR3; see Object::RegisterProperty() for more details.
380    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
381    * @pre Either the property name is not in use, or a property exists with the correct name & type.
382    * @param name The name of the uniform.
383    * @param value The value to to set.
384    * @param uniformCoordinateType The coordinate type of the uniform.
385    */
386   void SetUniform( const std::string& name,
387                    Vector3 value,
388                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
389
390   /**
391    * @brief Set a uniform value.
392    *
393    * This will register a property of type Property::VECTOR4; see Object::RegisterProperty() for more details.
394    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
395    * @pre Either the property name is not in use, or a property exists with the correct name & type.
396    * @param name The name of the uniform.
397    * @param value The value to to set.
398    * @param uniformCoordinateType The coordinate type of the uniform.
399    */
400   void SetUniform( const std::string& name,
401                    Vector4 value,
402                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
403
404   /**
405    * @brief Set a uniform value.
406    *
407    * This will register a property of type Property::MATRIX; see Object::RegisterProperty() for more details.
408    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
409    * @pre Either the property name is not in use, or a property exists with the correct name & type.
410    * @param name The name of the uniform.
411    * @param value The value to to set.
412    * @param uniformCoordinateType The coordinate type of the uniform.
413    */
414   void SetUniform( const std::string& name,
415                    const Matrix& value,
416                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
417
418   /**
419    * @brief Set a uniform value.
420    *
421    * This will register a property of type Property::MATRIX3; see Object::RegisterProperty() for more details.
422    * If name matches a uniform in the shader source, this value will be uploaded when rendering.
423    * @pre Either the property name is not in use, or a property exists with the correct name & type.
424    * @param name The name of the uniform.
425    * @param value The value to to set.
426    * @param uniformCoordinateType The coordinate type of the uniform.
427    */
428   void SetUniform( const std::string& name,
429                    const Matrix3& value,
430                    UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
431
432   /**
433    * @brief Attach an extension object.
434    *
435    * This object is reference counted and will be automatically deleted.
436    * This object can be retrieved back with the GetExtension function.
437    * @param object Pointer to a Extension.
438    * @pre extension is not NULL
439    */
440   void AttachExtension( Extension *object );
441
442   /**
443    * @brief Retrieve the attached extension object.
444    *
445    * This object can be set with the AttachExtension function.
446    * @return implementation Pointer to a Extension.
447    * @pre An extension needs to be attached previously.
448    */
449   Extension& GetExtension();
450
451   /**
452    * @brief Retrieve the attached extension object.
453    *
454    * This object can be set with the AttachExtension function.
455    * @return implementation Pointer to a Extension.
456    * @pre An extension needs to be attached previously.
457    */
458   const Extension& GetExtension() const;
459
460
461 public: // Not intended for application developers
462
463   /**
464    * @brief This constructor is used by Dali New() methods.
465    * @param [in] effect A pointer to a newly allocated Dali resource.
466    */
467   explicit DALI_INTERNAL ShaderEffect(Internal::ShaderEffect* effect);
468 };
469
470 } // namespace Dali
471
472 #endif // __DALI_SHADER_EFFECT_H__