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