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 * @addtogroup CAPI_DALI_SHADER_EFFECTS_MODULE
27 #include <dali/public-api/animation/active-constraint-declarations.h>
28 #include <dali/public-api/object/constrainable.h>
30 namespace Dali DALI_IMPORT_API
34 * @brief DALI_COMPOSE_SHADER macro provides a convenient way to write shader source code.
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.
40 * [An example of double quotation marks usage]
41 * const string FRAGMENT_SHADER_SOURCE = \
44 * " gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\n"
47 * [An example of DALI_COMPOSE_SHADER usage]
48 * const string FRAGMENT_SHADER_SOURCE = DALI_COMPOSE_SHADER (
51 * gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);
52 * vTexCoord = aTexCoord;
56 #define DALI_COMPOSE_SHADER(STR) #STR
64 namespace Internal DALI_INTERNAL
70 * @brief GeometryType determines how geometry is shaped.
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
82 * @brief Shader effects provide a visual effect for actors.
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:
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;
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:
105 * gl_Position = uProjection * uModelView * vec4(aPosition, 1.0);
106 * vTexCoord = aTexCoord;
109 * For fragment shader the default part for images contains the following code:
111 * precision mediump float;
112 * uniform sampler2D sTexture;
113 * uniform sampler2D sEffect;
114 * uniform vec4 uColor;
115 * varying vec2 vTexCoord;
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;
126 * and the custom shader is expected to output the fragment color.
127 * The basic fragment shader for images would contain:
131 * gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;
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;
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
155 class ShaderEffect : public Constrainable
159 * @brief The Extension class is a base class for objects that can be attached to the
160 * ShaderEffects as extensions.
162 * Extensions are useful to create pimpled implementations of custom shaders.
163 * The shader effect will hold an intrusive pointer to the extension.
165 class Extension : public RefObject
169 * @brief Disable default constructor. This a base class is not meant to be initialised on its own.
174 * @brief Virtual destructor.
176 virtual ~Extension();
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.
183 * +---+---+ +---+---+---+
185 * +---+---+ +---+---+---+
187 * +---+---+ +---+---+---+
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)
196 static const float DEFAULT_GRID_DENSITY; ///< The default density is 40 pixels
199 * @brief Hints for rendering/subdividing geometry.
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
212 * @brief Coordinate type of the shader uniform.
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.
219 enum UniformCoordinateType
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.
228 * @brief Create an empty ShaderEffect.
230 * This can be initialised with ShaderEffect::New(...)
235 * @brief Create ShaderEffect.
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
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) );
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
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) );
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
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) );
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
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) );
304 * @brief Downcast an Object handle to ShaderEffect.
306 * If handle points to a ShaderEffect the downcast produces valid
307 * handle. If not the returned handle is left uninitialized.
309 * @param[in] handle to An object
310 * @return handle to a ShaderEffect object or an uninitialized handle
312 static ShaderEffect DownCast( BaseHandle handle );
315 * @brief Virtual destructor.
317 * Dali::Object derived classes typically do not contain member data.
319 virtual ~ShaderEffect();
322 * @brief Copy constructor
324 * @param object A reference to a ShaderEffect object
326 ShaderEffect(const ShaderEffect& object);
329 * @copydoc Dali::BaseHandle::operator=
331 using BaseHandle::operator=;
334 * @brief Sets image for using as effect texture.
336 * This image texture will be bound to the "sEffectTexture" sampler
337 * so it can be used in fragment shader for effects
339 * @param[in] image to use as effect texture
341 void SetEffectImage( Image image );
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.
352 void SetUniform( const std::string& name,
354 UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
357 * @brief Set a uniform value.
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.
366 void SetUniform( const std::string& name,
368 UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
371 * @brief Set a uniform value.
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.
380 void SetUniform( const std::string& name,
382 UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
385 * @brief Set a uniform value.
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.
394 void SetUniform( const std::string& name,
396 UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
399 * @brief Set a uniform value.
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.
408 void SetUniform( const std::string& name,
410 UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
413 * @brief Set a uniform value.
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.
422 void SetUniform( const std::string& name,
423 const Matrix3& value,
424 UniformCoordinateType uniformCoordinateType = UniformCoordinateType(COORDINATE_TYPE_DEFAULT) );
427 * @brief Attach an extension object.
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
434 void AttachExtension( Extension *object );
437 * @brief Retrieve the attached extension object.
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.
443 Extension& GetExtension();
446 * @brief Retrieve the attached extension object.
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.
452 const Extension& GetExtension() const;
455 public: // Not intended for application developers
458 * @brief This constructor is used by Dali New() methods.
459 * @param [in] effect A pointer to a newly allocated Dali resource.
461 explicit DALI_INTERNAL ShaderEffect(Internal::ShaderEffect* effect);
469 #endif // __DALI_SHADER_EFFECT_H__