1 #ifndef __DALI_SHADER_EFFECT_H__
2 #define __DALI_SHADER_EFFECT_H__
5 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
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>
30 * @brief DALI_COMPOSE_SHADER macro provides a convenient way to write shader source code.
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.
36 * [An example of double quotation marks usage]
37 * const string FRAGMENT_SHADER_SOURCE = \
40 * " gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n"
43 * [An example of DALI_COMPOSE_SHADER usage]
44 * const string VERTEX_SHADER_SOURCE = DALI_COMPOSE_SHADER (
47 * gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);
48 * vTexCoord = aTexCoord;
52 #define DALI_COMPOSE_SHADER(STR) #STR
60 namespace Internal DALI_INTERNAL
66 * @brief GeometryType determines how geometry is shaped.
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
78 * @brief Shader effects provide a visual effect for actors.
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:
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;
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:
101 * gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);
102 * vTexCoord = aTexCoord;
105 * For fragment shader the default part for images contains the following code:
107 * precision mediump float;
108 * uniform sampler2D sTexture;
109 * uniform sampler2D sEffect;
110 * uniform vec4 uColor;
111 * varying vec2 vTexCoord;
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;
122 * and the custom shader is expected to output the fragment color.
123 * The basic fragment shader for images would contain:
127 * gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;
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;
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
151 class DALI_IMPORT_API ShaderEffect : public Handle
155 // Default Properties
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.
161 * +---+---+ +---+---+---+
163 * +---+---+ +---+---+---+
165 * +---+---+ +---+---+---+
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
180 static const float DEFAULT_GRID_DENSITY; ///< The default density is 40 pixels
183 * @brief The Extension class is a base class for objects that can be attached to the
184 * ShaderEffects as extensions.
186 * Extensions are useful to create pimpled implementations of custom shaders.
187 * The shader effect will hold an intrusive pointer to the extension.
189 class Extension : public RefObject
193 * @brief Disable default constructor. This a base class is not meant to be initialised on its own.
198 * @brief Virtual destructor.
200 virtual ~Extension();
204 * @brief Hints for rendering/subdividing geometry.
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)
218 * @brief Coordinate type of the shader uniform.
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.
225 enum UniformCoordinateType
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.
233 * @brief Create an empty ShaderEffect.
235 * This can be initialised with ShaderEffect::New(...)
240 * @brief Create ShaderEffect.
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
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) );
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
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) );
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
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) );
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
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) );
309 * @brief Downcast an Object handle to ShaderEffect.
311 * If handle points to a ShaderEffect the downcast produces valid
312 * handle. If not the returned handle is left uninitialized.
314 * @param[in] handle to An object
315 * @return handle to a ShaderEffect object or an uninitialized handle
317 static ShaderEffect DownCast( BaseHandle handle );
322 * This is non-virtual since derived Handle types must not contain data or virtual methods.
327 * @brief Copy constructor
329 * @param object A reference to a ShaderEffect object
331 ShaderEffect(const ShaderEffect& object);
334 * @brief This assignment operator is required for (smart) pointer semantics.
336 * @param [in] rhs A reference to the copied handle
337 * @return A reference to this
339 ShaderEffect& operator=(const ShaderEffect& rhs);
342 * @brief Sets image for using as effect texture.
344 * This image texture will be bound to the "sEffect" sampler
345 * so it can be used in fragment shader for effects
347 * @param[in] image to use as effect texture
349 void SetEffectImage( Image image );
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.
360 void SetUniform( const std::string& name,
362 UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
365 * @brief Set a uniform value.
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.
374 void SetUniform( const std::string& name,
376 UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
379 * @brief Set a uniform value.
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.
388 void SetUniform( const std::string& name,
390 UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
393 * @brief Set a uniform value.
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.
402 void SetUniform( const std::string& name,
404 UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
407 * @brief Set a uniform value.
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.
416 void SetUniform( const std::string& name,
418 UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
421 * @brief Set a uniform value.
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.
430 void SetUniform( const std::string& name,
431 const Matrix3& value,
432 UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
435 * @brief Attach an extension object.
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
442 void AttachExtension( Extension *object );
445 * @brief Retrieve the attached extension object.
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.
451 Extension& GetExtension();
454 * @brief Retrieve the attached extension object.
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.
460 const Extension& GetExtension() const;
463 public: // Not intended for application developers
466 * @brief This constructor is used by Dali New() methods.
467 * @param [in] effect A pointer to a newly allocated Dali resource.
469 explicit DALI_INTERNAL ShaderEffect(Internal::ShaderEffect* effect);
474 #endif // __DALI_SHADER_EFFECT_H__