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 {"mesh", GEOMETRY_TYPE_UNTEXTURED_MESH },
48 {"textured-mesh", GEOMETRY_TYPE_TEXTURED_MESH },
51 const unsigned int GeometryTypeTableCount = sizeof(GeometryTypeTable)/sizeof(GeometryTypeTable[0]);
53 struct GeometryHintPair
56 ShaderEffect::GeometryHints hint;
59 const GeometryHintPair GeometryHintTable[]=
61 {"gridX", ShaderEffect::HINT_GRID_X },
62 {"gridY", ShaderEffect::HINT_GRID_Y },
63 {"grid", ShaderEffect::HINT_GRID },
64 {"depthBuffer", ShaderEffect::HINT_DEPTH_BUFFER },
65 {"blending", ShaderEffect::HINT_BLENDING },
66 {"doesntModifyGeometry", ShaderEffect::HINT_DOESNT_MODIFY_GEOMETRY }
69 const unsigned int GeometryHintTableCount = sizeof(GeometryHintTable)/sizeof(GeometryHintTable[0]);
74 struct ShaderParameters
77 : mType( GEOMETRY_TYPE_IMAGE),
78 mHints( ShaderEffect::HINT_NONE )
82 void SetGeometryType( v8::Isolate* isolate, const std::string& typeName )
84 for( unsigned int i = 0; i < GeometryTypeTableCount; ++i )
86 if( typeName == GeometryTypeTable[i].name )
88 mType = GeometryTypeTable[i].type;
92 DALI_SCRIPT_EXCEPTION( isolate, "Geometry type not found\n");
95 ShaderEffect::GeometryHints GetGeometryHint( const std::string& hint )
97 for( unsigned int i = 0 ; i < GeometryHintTableCount; ++i )
99 if( hint == GeometryHintTable[i].name )
101 return GeometryHintTable[i].hint;
104 return ShaderEffect::HINT_NONE;
107 void ProcessHintsArray( const HintsArray& hintsArray )
109 for( HintsArray::const_iterator iter = hintsArray.begin(); iter != hintsArray.end() ; ++iter )
111 mHints= static_cast<ShaderEffect::GeometryHints>( mHints | GetGeometryHint( *iter ) );
117 ShaderEffect NewShader()
119 return ShaderEffect::NewWithPrefix( mVertexPrefix ,
126 std::string mVertexPrefix;
128 std::string mFragmentPrefix;
129 std::string mFragment;
131 ShaderEffect::GeometryHints mHints;
134 ShaderEffect GetShaderEffect( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
136 v8::HandleScope handleScope( isolate );
138 v8::Local<v8::Object> object = args.This();
139 v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
140 void* ptr = field->Value();
142 ShaderEffectWrapper* wrapper = static_cast< ShaderEffectWrapper *>(ptr);
143 return wrapper->GetShaderEffect();
149 * Create a new ShaderEffect
152 * @method ShaderEffect
153 * @param {Object} shaderOptions
154 * @param {String} [shaderOptions.geometryType] Type of geometry to be rendered with the effect. "image", "text", "mesh", "textured-mesh", default is image.
155 * @param {String} [shaderOptions.vertexShaderPrefix] This string will be inserted before the default uniforms for the vertex shader(ideal for #defines)
156 * @param {String} [shaderOptions.vertexShader] VertexShader code for the effect. If not defined, the default version will be used
157 * @param {String} [shaderOptions.fragmentShaderPrefix] This string will be inserted before the default uniforms for the fragment shader(ideal for #defines)
158 * @param {String} [shaderOptions.fragmentShader] FragmentShader code for the effect. If not defined, the default version will be used
159 * @param {Array} [shaderOptions.geometryHints] Hints for rendering the geometry, e.g. [ "gridX", "gridY", "grid","depthBuffer","blending","doesntModifyGeometry" ]
160 * @return {Object} ShaderEffect
163 // this will match the default shaders for image
164 var vertexShader = " void main() \
166 gl_Position = uProjection * uModelView * vec4(aPosition, 1.0); \
167 vTexCoord = aTexCoord; \
169 var fragShader = " void main() \
171 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\
173 var shaderOptions = {
174 geometryType: "image",
175 vertexShader: vertexShader,
176 fragmentShader: fragShader
179 var shader = new dali.ShaderEffect(shaderOptions);
181 imageActor.setShaderEffect( shader );
187 ShaderEffect ShaderEffectApi::New( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
191 v8::HandleScope handleScope( isolate );
193 ShaderParameters shaderParams;
195 if( args[0]->IsObject() )
197 v8::Local<v8::Object > obj = args[0]->ToObject();
199 v8::Local<v8::Value> geometryTypeValue = obj->Get(v8::String::NewFromUtf8( isolate, "geometryType"));
200 if( geometryTypeValue->IsString() )
202 std::string geometryTypeName = V8Utils::v8StringToStdString( geometryTypeValue );
203 // printf(" geometry type found %s \n", geometryTypeName.c_str() );
204 shaderParams.SetGeometryType( isolate, geometryTypeName );
207 v8::Local<v8::Value> vertexPrefixValue = obj->Get(v8::String::NewFromUtf8( isolate, "vertexShaderPrefix"));
208 if( vertexPrefixValue->IsString() )
210 shaderParams.mVertexPrefix = V8Utils::v8StringToStdString( vertexPrefixValue );
213 v8::Local<v8::Value> fragmentPrefixValue = obj->Get(v8::String::NewFromUtf8( isolate, "fragmentShaderPrefix"));
214 if( fragmentPrefixValue->IsString() )
216 shaderParams.mFragmentPrefix = V8Utils::v8StringToStdString( fragmentPrefixValue );
219 v8::Local<v8::Value> vertexValue = obj->Get(v8::String::NewFromUtf8( isolate, "vertexShader"));
220 if( vertexValue->IsString() )
222 shaderParams.mVertex = V8Utils::v8StringToStdString( vertexValue );
225 v8::Local<v8::Value> fragmentValue = obj->Get(v8::String::NewFromUtf8( isolate, "fragmentShader"));
226 if( fragmentValue->IsString() )
228 shaderParams.mFragment = V8Utils::v8StringToStdString( fragmentValue );
231 v8::Local<v8::Value> hints = obj->Get(v8::String::NewFromUtf8( isolate, "geometryHints"));
232 if( hints->IsArray() )
234 HintsArray hintsArray;
235 v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast( hints );
236 for( uint32_t i=0; i < array->Length(); ++i)
238 v8::Handle<v8::Value> entry = array->Get( v8::Integer::New( isolate, i) );
239 if( entry->IsString() )
241 std::string entryString = V8Utils::v8StringToStdString( entry );
242 hintsArray.push_back( entryString );
245 shaderParams.ProcessHintsArray( hintsArray );
248 return shaderParams.NewShader();
252 ShaderEffect ShaderEffectApi::GetShaderEffectFromParams( int paramIndex,
254 v8::Isolate* isolate,
255 const v8::FunctionCallbackInfo< v8::Value >& args )
259 v8::HandleScope handleScope( isolate );
260 BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( paramIndex, BaseWrappedObject::SHADER_EFFECT, isolate, args );
264 ShaderEffectWrapper* wrapper = static_cast< ShaderEffectWrapper *>(wrappedObject);
265 return wrapper->GetShaderEffect();
269 return ShaderEffect();
274 * Set a shader effect image.
275 * This image texture will be bound to the "sEffect" sampler
276 * so it can be used in fragment shader for effects
277 * @method setEffectImage
279 * @param {Object} image
282 * shader.setEffectImage( image );
284 * // example of a fragment shader than can use the effect image (sEffect and main texture sTexture)
288 * vec4 v4Color = (texture2D(sTexture, vTexCoord) * uColor); \
289 * v4Color = v4Color* texture2D(sEffect, vTexCoord);\
290 * gl_FragColor = v4Color; \"
293 void ShaderEffectApi::SetEffectImage( const v8::FunctionCallbackInfo< v8::Value >& args )
295 v8::Isolate* isolate = args.GetIsolate();
296 v8::HandleScope handleScope( isolate );
299 Image image = V8Utils::GetImageParameter( PARAMETER_0, found, isolate, args );
302 DALI_SCRIPT_EXCEPTION( isolate, " Image::SetEffectImage invalid params");
305 ShaderEffect effect = GetShaderEffect( isolate, args );
306 effect.SetEffectImage( image );
311 * Sets and registers a uniform property.
312 * If name matches a uniform in the shader source, this value will be uploaded when rendering.
313 * This uniform can then be animated / modified and the change will be made to the shader.
316 * @param {String} name
317 * @param {Object} value must be a: float, vector2 vector3, vector4, matrix
318 * @param {String} [uniformCoordinateType] The coordinate type of the uniform.
319 * either "viewPortPosition" or "viewPortDirection"
323 " uniform lowp vec4 uColorShift; \
328 gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor + uColorShift; \
331 var shaderOptions = {
332 geometryType: "image",
333 fragmentShader: fragShader
336 // create a new shader effect
337 var shader = new dali.ShaderEffect(shaderOptions);
339 // add the color shift uniform so we can animate it
340 // default the color shift to zero, so it has no effect
341 shader.setUniform("uColorShift", [0.0, 0.0, 0.0, 0]);
343 void ShaderEffectApi::SetUniform( const v8::FunctionCallbackInfo< v8::Value >& args )
346 v8::Isolate* isolate = args.GetIsolate();
347 v8::HandleScope handleScope( isolate );
348 ShaderEffect effect = GetShaderEffect( isolate, args );
351 std::string uniformName = V8Utils::GetStringParameter( PARAMETER_0 , found, isolate, args );
354 DALI_SCRIPT_EXCEPTION( isolate, "SetUniform: uniform name not found\n");
358 Property::Value propValue = V8Utils::GetPropertyValueParameter( PARAMETER_1 , found, isolate, args );
361 DALI_SCRIPT_EXCEPTION( isolate, "SetUniform: value not found\n");
365 std::string coordinateType = V8Utils::GetStringParameter( PARAMETER_2, found, isolate, args );
366 ShaderEffect::UniformCoordinateType uniformCoordinateType( ShaderEffect::COORDINATE_TYPE_DEFAULT );
369 if( coordinateType == "viewPortPosition")
371 uniformCoordinateType = ShaderEffect::COORDINATE_TYPE_VIEWPORT_POSITION;
373 else if ( coordinateType == "viewPortDirection ")
375 uniformCoordinateType = ShaderEffect::COORDINATE_TYPE_VIEWPORT_DIRECTION;
379 switch( propValue.GetType() )
381 case Property::FLOAT:
383 effect.SetUniform( uniformName, propValue.Get<float>(), uniformCoordinateType );
386 case Property::VECTOR2:
388 effect.SetUniform( uniformName, propValue.Get<Vector2>(), uniformCoordinateType );
391 case Property::VECTOR3:
393 effect.SetUniform( uniformName, propValue.Get<Vector3>(), uniformCoordinateType );
396 case Property::VECTOR4:
398 effect.SetUniform( uniformName, propValue.Get<Vector4>(), uniformCoordinateType );
401 case Property::MATRIX:
403 effect.SetUniform( uniformName, propValue.Get<Matrix>(), uniformCoordinateType );
406 case Property::MATRIX3:
408 effect.SetUniform( uniformName, propValue.Get<Matrix3>(), uniformCoordinateType );
413 DALI_SCRIPT_EXCEPTION( isolate, "value type not recognised \n");
420 } // namespace V8Plugin