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