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"
24 #include <shader-effects/shader-effect-wrapper.h>
32 namespace // un named namespace
35 typedef std::vector< std::string > HintsArray;
38 struct GeometryTypePair
44 const GeometryTypePair GeometryTypeTable[]=
46 {"image", GEOMETRY_TYPE_IMAGE },
47 {"text", GEOMETRY_TYPE_TEXT },
48 {"mesh", GEOMETRY_TYPE_UNTEXTURED_MESH },
49 {"textured-mesh", GEOMETRY_TYPE_TEXTURED_MESH },
52 const unsigned int GeometryTypeTableCount = sizeof(GeometryTypeTable)/sizeof(GeometryTypeTable[0]);
54 struct GeometryHintPair
57 ShaderEffect::GeometryHints hint;
60 const GeometryHintPair GeometryHintTable[]=
62 {"gridX", ShaderEffect::HINT_GRID_X },
63 {"gridY", ShaderEffect::HINT_GRID_Y },
64 {"grid", ShaderEffect::HINT_GRID },
65 {"depthBuffer", ShaderEffect::HINT_DEPTH_BUFFER },
66 {"blending", ShaderEffect::HINT_BLENDING },
67 {"doesntModifyGeometry", ShaderEffect::HINT_DOESNT_MODIFY_GEOMETRY }
70 const unsigned int GeometryHintTableCount = sizeof(GeometryHintTable)/sizeof(GeometryHintTable[0]);
75 struct ShaderParameters
78 : mType( GEOMETRY_TYPE_IMAGE),
79 mHints( ShaderEffect::HINT_NONE )
83 void SetGeometryType( v8::Isolate* isolate, const std::string& typeName )
85 for( unsigned int i = 0; i < GeometryTypeTableCount; ++i )
87 if( typeName == GeometryTypeTable[i].name )
89 mType = GeometryTypeTable[i].type;
93 DALI_SCRIPT_EXCEPTION( isolate, "Geometry type not found\n");
96 ShaderEffect::GeometryHints GetGeometryHint( const std::string& hint )
98 for( unsigned int i = 0 ; i < GeometryHintTableCount; ++i )
100 if( hint == GeometryHintTable[i].name )
102 return GeometryHintTable[i].hint;
105 return ShaderEffect::HINT_NONE;
108 void ProcessHintsArray( const HintsArray& hintsArray )
110 for( HintsArray::const_iterator iter = hintsArray.begin(); iter != hintsArray.end() ; ++iter )
112 mHints= static_cast<ShaderEffect::GeometryHints>( mHints | GetGeometryHint( *iter ) );
118 ShaderEffect NewShader()
120 return ShaderEffect::NewWithPrefix( mVertexPrefix ,
127 std::string mVertexPrefix;
129 std::string mFragmentPrefix;
130 std::string mFragment;
132 ShaderEffect::GeometryHints mHints;
135 ShaderEffect GetShaderEffect( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
137 v8::HandleScope handleScope( isolate );
139 v8::Local<v8::Object> object = args.This();
140 v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
141 void* ptr = field->Value();
143 ShaderEffectWrapper* wrapper = static_cast< ShaderEffectWrapper *>(ptr);
144 return wrapper->GetShaderEffect();
150 * Create a new ShaderEffect
153 * @method ShaderEffect
154 * @param {Object} shaderOptions
155 * @param {String} [shaderOptions.geometryType] Type of geometry to be rendered with the effect. "image", "text", "mesh", "textured-mesh", default is image.
156 * @param {String} [shaderOptions.vertexShaderPrefix] This string will be inserted before the default uniforms for the vertex shader(ideal for #defines)
157 * @param {String} [shaderOptions.vertexShader] VertexShader code for the effect. If not defined, the default version will be used
158 * @param {String} [shaderOptions.fragmentShaderPrefix] This string will be inserted before the default uniforms for the fragment shader(ideal for #defines)
159 * @param {String} [shaderOptions.fragmentShader] FragmentShader code for the effect. If not defined, the default version will be used
160 * @param {Array} [shaderOptions.geometryHints] Hints for rendering the geometry, e.g. [ "gridX", "gridY", "grid","depthBuffer","blending","doesntModifyGeometry" ]
161 * @return {Object} ShaderEffect
164 // this will match the default shaders for image
165 var vertexShader = " void main() \
167 gl_Position = uProjection * uModelView * vec4(aPosition, 1.0); \
168 vTexCoord = aTexCoord; \
170 var fragShader = " void main() \
172 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\
174 var shaderOptions = {
175 geometryType: "image",
176 vertexShader: vertexShader,
177 fragmentShader: fragShader
180 var shader = new dali.ShaderEffect(shaderOptions);
182 imageActor.setShaderEffect( shader );
188 ShaderEffect ShaderEffectApi::New( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
192 v8::HandleScope handleScope( isolate );
194 ShaderParameters shaderParams;
196 if( args[0]->IsObject() )
198 v8::Local<v8::Object > obj = args[0]->ToObject();
200 v8::Local<v8::Value> geometryTypeValue = obj->Get(v8::String::NewFromUtf8( isolate, "geometryType"));
201 if( geometryTypeValue->IsString() )
203 std::string geometryTypeName = V8Utils::v8StringToStdString( geometryTypeValue );
204 // printf(" geometry type found %s \n", geometryTypeName.c_str() );
205 shaderParams.SetGeometryType( isolate, geometryTypeName );
208 v8::Local<v8::Value> vertexPrefixValue = obj->Get(v8::String::NewFromUtf8( isolate, "vertexShaderPrefix"));
209 if( vertexPrefixValue->IsString() )
211 shaderParams.mVertexPrefix = V8Utils::v8StringToStdString( vertexPrefixValue );
214 v8::Local<v8::Value> fragmentPrefixValue = obj->Get(v8::String::NewFromUtf8( isolate, "fragmentShaderPrefix"));
215 if( fragmentPrefixValue->IsString() )
217 shaderParams.mFragmentPrefix = V8Utils::v8StringToStdString( fragmentPrefixValue );
220 v8::Local<v8::Value> vertexValue = obj->Get(v8::String::NewFromUtf8( isolate, "vertexShader"));
221 if( vertexValue->IsString() )
223 shaderParams.mVertex = V8Utils::v8StringToStdString( vertexValue );
226 v8::Local<v8::Value> fragmentValue = obj->Get(v8::String::NewFromUtf8( isolate, "fragmentShader"));
227 if( fragmentValue->IsString() )
229 shaderParams.mFragment = V8Utils::v8StringToStdString( fragmentValue );
232 v8::Local<v8::Value> hints = obj->Get(v8::String::NewFromUtf8( isolate, "geometryHints"));
233 if( hints->IsArray() )
235 HintsArray hintsArray;
236 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast( hints );
237 for( uint32_t i=0; i < array->Length(); ++i)
239 v8::Handle<v8::Value> entry = array->Get( v8::Integer::New( isolate, i) );
240 if( entry->IsString() )
242 std::string entryString = V8Utils::v8StringToStdString( entry );
243 hintsArray.push_back( entryString );
246 shaderParams.ProcessHintsArray( hintsArray );
249 return shaderParams.NewShader();
253 ShaderEffect ShaderEffectApi::GetShaderEffectFromParams( int paramIndex,
255 v8::Isolate* isolate,
256 const v8::FunctionCallbackInfo< v8::Value >& args )
260 v8::HandleScope handleScope( isolate );
261 BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( paramIndex, BaseWrappedObject::SHADER_EFFECT, isolate, args );
265 ShaderEffectWrapper* wrapper = static_cast< ShaderEffectWrapper *>(wrappedObject);
266 return wrapper->GetShaderEffect();
270 return ShaderEffect();
275 * Set a shader effect image.
276 * This image texture will be bound to the "sEffect" sampler
277 * so it can be used in fragment shader for effects
278 * @method setEffectImage
280 * @param {Object} image
283 * shader.setEffectImage( image );
285 * // example of a fragment shader than can use the effect image (sEffect and main texture sTexture)
289 * vec4 v4Color = (texture2D(sTexture, vTexCoord) * uColor); \
290 * v4Color = v4Color* texture2D(sEffect, vTexCoord);\
291 * gl_FragColor = v4Color; \"
294 void ShaderEffectApi::SetEffectImage( const v8::FunctionCallbackInfo< v8::Value >& args )
296 v8::Isolate* isolate = args.GetIsolate();
297 v8::HandleScope handleScope( isolate );
300 Image image = V8Utils::GetImageParameter( PARAMETER_0, found, isolate, args );
303 DALI_SCRIPT_EXCEPTION( isolate, " Image::SetEffectImage invalid params");
306 ShaderEffect effect = GetShaderEffect( isolate, args );
307 effect.SetEffectImage( image );
312 * Sets and registers a uniform property.
313 * If name matches a uniform in the shader source, this value will be uploaded when rendering.
314 * This uniform can then be animated / modified and the change will be made to the shader.
317 * @param {String} name
318 * @param {Object} value must be a: float, vector2 vector3, vector4, matrix
319 * @param {String} [uniformCoordinateType] The coordinate type of the uniform.
320 * either "viewPortPosition" or "viewPortDirection"
324 " uniform lowp vec4 uColorShift; \
329 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor + uColorShift; \
332 var shaderOptions = {
333 geometryType: "image",
334 fragmentShader: fragShader
337 // create a new shader effect
338 var shader = new dali.ShaderEffect(shaderOptions);
340 // add the color shift uniform so we can animate it
341 // default the color shift to zero, so it has no effect
342 shader.setUniform("uColorShift", [0.0, 0.0, 0.0, 0]);
344 void ShaderEffectApi::SetUniform( const v8::FunctionCallbackInfo< v8::Value >& args )
347 v8::Isolate* isolate = args.GetIsolate();
348 v8::HandleScope handleScope( isolate );
349 ShaderEffect effect = GetShaderEffect( isolate, args );
352 std::string uniformName = V8Utils::GetStringParameter( PARAMETER_0 , found, isolate, args );
355 DALI_SCRIPT_EXCEPTION( isolate, "SetUniform: uniform name not found\n");
359 Property::Value propValue = V8Utils::GetPropertyValueParameter( PARAMETER_1 , found, isolate, args );
362 DALI_SCRIPT_EXCEPTION( isolate, "SetUniform: value not found\n");
366 std::string coordinateType = V8Utils::GetStringParameter( PARAMETER_2, found, isolate, args );
367 ShaderEffect::UniformCoordinateType uniformCoordinateType( ShaderEffect::COORDINATE_TYPE_DEFAULT );
370 if( coordinateType == "viewPortPosition")
372 uniformCoordinateType = ShaderEffect::COORDINATE_TYPE_VIEWPORT_POSITION;
374 else if ( coordinateType == "viewPortDirection ")
376 uniformCoordinateType = ShaderEffect::COORDINATE_TYPE_VIEWPORT_DIRECTION;
380 switch( propValue.GetType() )
382 case Property::FLOAT:
384 effect.SetUniform( uniformName, propValue.Get<float>(), uniformCoordinateType );
387 case Property::VECTOR2:
389 effect.SetUniform( uniformName, propValue.Get<Vector2>(), uniformCoordinateType );
392 case Property::VECTOR3:
394 effect.SetUniform( uniformName, propValue.Get<Vector3>(), uniformCoordinateType );
397 case Property::VECTOR4:
399 effect.SetUniform( uniformName, propValue.Get<Vector4>(), uniformCoordinateType );
402 case Property::MATRIX:
404 effect.SetUniform( uniformName, propValue.Get<Matrix>(), uniformCoordinateType );
407 case Property::MATRIX3:
409 effect.SetUniform( uniformName, propValue.Get<Matrix3>(), uniformCoordinateType );
414 DALI_SCRIPT_EXCEPTION( isolate, "value type not recognised \n");
421 } // namespace V8Plugin