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