2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include "shader-effect-api.h"
23 #include <dali/public-api/object/type-registry.h>
27 #include <shader-effects/shader-effect-wrapper.h>
35 namespace // un named namespace
38 typedef std::vector< std::string > HintsArray;
40 struct GeometryHintPair
43 ShaderEffect::GeometryHints hint;
46 const GeometryHintPair GeometryHintTable[]=
48 {"gridX", ShaderEffect::HINT_GRID_X },
49 {"gridY", ShaderEffect::HINT_GRID_Y },
50 {"grid", ShaderEffect::HINT_GRID },
51 {"depthBuffer", ShaderEffect::HINT_DEPTH_BUFFER },
52 {"blending", ShaderEffect::HINT_BLENDING },
53 {"doesntModifyGeometry", ShaderEffect::HINT_DOESNT_MODIFY_GEOMETRY }
56 const unsigned int GeometryHintTableCount = sizeof(GeometryHintTable)/sizeof(GeometryHintTable[0]);
61 struct ShaderParameters
64 : mHints( ShaderEffect::HINT_NONE )
68 ShaderEffect::GeometryHints GetGeometryHint( const std::string& hint )
70 for( unsigned int i = 0 ; i < GeometryHintTableCount; ++i )
72 if( hint == GeometryHintTable[i].name )
74 return GeometryHintTable[i].hint;
77 return ShaderEffect::HINT_NONE;
80 void ProcessHintsArray( const HintsArray& hintsArray )
82 for( HintsArray::const_iterator iter = hintsArray.begin(); iter != hintsArray.end() ; ++iter )
84 mHints= static_cast<ShaderEffect::GeometryHints>( mHints | GetGeometryHint( *iter ) );
88 ShaderEffect NewShader()
90 return ShaderEffect::NewWithPrefix( mVertexPrefix ,
96 std::string mVertexPrefix;
98 std::string mFragmentPrefix;
99 std::string mFragment;
100 ShaderEffect::GeometryHints mHints;
103 ShaderEffect GetShaderEffect( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
105 v8::HandleScope handleScope( isolate );
107 v8::Local<v8::Object> object = args.This();
108 v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
109 void* ptr = field->Value();
111 ShaderEffectWrapper* wrapper = static_cast< ShaderEffectWrapper *>(ptr);
112 return wrapper->GetShaderEffect();
118 * Create a new ShaderEffect
121 * @method ShaderEffect
122 * @param {Object} shaderOptions
123 * @param {String} [shaderOptions.geometryType] Type of geometry to be rendered with the effect. "image", "text", "mesh", "textured-mesh", default is image.
124 * @param {String} [shaderOptions.vertexShaderPrefix] This string will be inserted before the default uniforms for the vertex shader(ideal for #defines)
125 * @param {String} [shaderOptions.vertexShader] VertexShader code for the effect. If not defined, the default version will be used
126 * @param {String} [shaderOptions.fragmentShaderPrefix] This string will be inserted before the default uniforms for the fragment shader(ideal for #defines)
127 * @param {String} [shaderOptions.fragmentShader] FragmentShader code for the effect. If not defined, the default version will be used
128 * @param {Array} [shaderOptions.geometryHints] Hints for rendering the geometry, e.g. [ "gridX", "gridY", "grid","depthBuffer","blending","doesntModifyGeometry" ]
129 * @return {Object} ShaderEffect
132 // this will match the default shaders for image
133 var vertexShader = " void main() \
135 gl_Position = uProjection * uModelView * vec4(aPosition, 1.0); \
136 vTexCoord = aTexCoord; \
138 var fragShader = " void main() \
140 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\
142 var shaderOptions = {
143 geometryType: "image",
144 vertexShader: vertexShader,
145 fragmentShader: fragShader
148 var shader = new dali.ShaderEffect(shaderOptions);
150 imageActor.setShaderEffect( shader );
156 ShaderEffect ShaderEffectApi::New( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
158 v8::HandleScope handleScope( isolate );
160 if( args[0]->IsObject() )
162 ShaderParameters shaderParams;
164 v8::Local<v8::Object > obj = args[0]->ToObject();
166 v8::Local<v8::Value> vertexPrefixValue = obj->Get(v8::String::NewFromUtf8( isolate, "vertexShaderPrefix"));
167 if( vertexPrefixValue->IsString() )
169 shaderParams.mVertexPrefix = V8Utils::v8StringToStdString( vertexPrefixValue );
172 v8::Local<v8::Value> fragmentPrefixValue = obj->Get(v8::String::NewFromUtf8( isolate, "fragmentShaderPrefix"));
173 if( fragmentPrefixValue->IsString() )
175 shaderParams.mFragmentPrefix = V8Utils::v8StringToStdString( fragmentPrefixValue );
178 v8::Local<v8::Value> vertexValue = obj->Get(v8::String::NewFromUtf8( isolate, "vertexShader"));
179 if( vertexValue->IsString() )
181 shaderParams.mVertex = V8Utils::v8StringToStdString( vertexValue );
184 v8::Local<v8::Value> fragmentValue = obj->Get(v8::String::NewFromUtf8( isolate, "fragmentShader"));
185 if( fragmentValue->IsString() )
187 shaderParams.mFragment = V8Utils::v8StringToStdString( fragmentValue );
190 v8::Local<v8::Value> hints = obj->Get(v8::String::NewFromUtf8( isolate, "geometryHints"));
191 if( hints->IsArray() )
193 HintsArray hintsArray;
194 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast( hints );
195 for( uint32_t i=0; i < array->Length(); ++i)
197 v8::Handle<v8::Value> entry = array->Get( v8::Integer::New( isolate, i) );
198 if( entry->IsString() )
200 std::string entryString = V8Utils::v8StringToStdString( entry );
201 hintsArray.push_back( entryString );
204 shaderParams.ProcessHintsArray( hintsArray );
207 return shaderParams.NewShader();
214 std::string typeName = V8Utils::GetStringParameter( PARAMETER_0, found, isolate, args );
217 DALI_SCRIPT_EXCEPTION( isolate, "string parameter missing" );
221 // create a new shader effect based on type, using the type registry.
222 Dali::TypeInfo typeInfo = Dali::TypeRegistry::Get().GetTypeInfo( typeName );
223 if( typeInfo ) // handle, check if it has a value
225 Dali::BaseHandle handle = typeInfo.CreateInstance();
228 effect = ShaderEffect::DownCast( handle );
233 DALI_SCRIPT_EXCEPTION(isolate,"Unknown shader effect type");
241 ShaderEffect ShaderEffectApi::GetShaderEffectFromParams( int paramIndex,
243 v8::Isolate* isolate,
244 const v8::FunctionCallbackInfo< v8::Value >& args )
248 v8::HandleScope handleScope( isolate );
249 BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( paramIndex, BaseWrappedObject::SHADER_EFFECT, isolate, args );
253 ShaderEffectWrapper* wrapper = static_cast< ShaderEffectWrapper *>(wrappedObject);
254 return wrapper->GetShaderEffect();
258 return ShaderEffect();
263 * Set a shader effect image.
264 * This image texture will be bound to the "sEffect" sampler
265 * so it can be used in fragment shader for effects
266 * @method setEffectImage
268 * @param {Object} image
271 * shader.setEffectImage( image );
273 * // example of a fragment shader than can use the effect image (sEffect and main texture sTexture)
277 * vec4 v4Color = (texture2D(sTexture, vTexCoord) * uColor); \
278 * v4Color = v4Color* texture2D(sEffect, vTexCoord);\
279 * gl_FragColor = v4Color; \"
282 void ShaderEffectApi::SetEffectImage( const v8::FunctionCallbackInfo< v8::Value >& args )
284 v8::Isolate* isolate = args.GetIsolate();
285 v8::HandleScope handleScope( isolate );
288 Image image = V8Utils::GetImageParameter( PARAMETER_0, found, isolate, args );
291 DALI_SCRIPT_EXCEPTION( isolate, " Image::SetEffectImage invalid params");
294 ShaderEffect effect = GetShaderEffect( isolate, args );
295 effect.SetEffectImage( image );
300 * Sets and registers a uniform property.
301 * If name matches a uniform in the shader source, this value will be uploaded when rendering.
302 * This uniform can then be animated / modified and the change will be made to the shader.
305 * @param {String} name
306 * @param {Object} value must be a: float, vector2 vector3, vector4, matrix
307 * @param {String} [uniformCoordinateType] The coordinate type of the uniform.
308 * either "viewPortPosition" or "viewPortDirection"
312 " uniform lowp vec4 uColorShift; \
317 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor + uColorShift; \
320 var shaderOptions = {
321 geometryType: "image",
322 fragmentShader: fragShader
325 // create a new shader effect
326 var shader = new dali.ShaderEffect(shaderOptions);
328 // add the color shift uniform so we can animate it
329 // default the color shift to zero, so it has no effect
330 shader.setUniform("uColorShift", [0.0, 0.0, 0.0, 0]);
332 void ShaderEffectApi::SetUniform( const v8::FunctionCallbackInfo< v8::Value >& args )
335 v8::Isolate* isolate = args.GetIsolate();
336 v8::HandleScope handleScope( isolate );
337 ShaderEffect effect = GetShaderEffect( isolate, args );
340 std::string uniformName = V8Utils::GetStringParameter( PARAMETER_0 , found, isolate, args );
343 DALI_SCRIPT_EXCEPTION( isolate, "SetUniform: uniform name not found\n");
347 Property::Value propValue = V8Utils::GetPropertyValueParameter( PARAMETER_1 , found, isolate, args );
350 DALI_SCRIPT_EXCEPTION( isolate, "SetUniform: value not found\n");
354 std::string coordinateType = V8Utils::GetStringParameter( PARAMETER_2, found, isolate, args );
355 ShaderEffect::UniformCoordinateType uniformCoordinateType( ShaderEffect::COORDINATE_TYPE_DEFAULT );
358 if( coordinateType == "viewPortPosition")
360 uniformCoordinateType = ShaderEffect::COORDINATE_TYPE_VIEWPORT_POSITION;
362 else if ( coordinateType == "viewPortDirection ")
364 uniformCoordinateType = ShaderEffect::COORDINATE_TYPE_VIEWPORT_DIRECTION;
368 switch( propValue.GetType() )
370 case Property::FLOAT:
372 effect.SetUniform( uniformName, propValue.Get<float>(), uniformCoordinateType );
375 case Property::VECTOR2:
377 effect.SetUniform( uniformName, propValue.Get<Vector2>(), uniformCoordinateType );
380 case Property::VECTOR3:
382 effect.SetUniform( uniformName, propValue.Get<Vector3>(), uniformCoordinateType );
385 case Property::VECTOR4:
387 effect.SetUniform( uniformName, propValue.Get<Vector4>(), uniformCoordinateType );
390 case Property::MATRIX:
392 effect.SetUniform( uniformName, propValue.Get<Matrix>(), uniformCoordinateType );
395 case Property::MATRIX3:
397 effect.SetUniform( uniformName, propValue.Get<Matrix3>(), uniformCoordinateType );
402 DALI_SCRIPT_EXCEPTION( isolate, "value type not recognised \n");
409 } // namespace V8Plugin