Fix Render API for node addon
[platform/core/uifw/dali-toolkit.git] / plugins / dali-script-v8 / src / rendering / shader-api.cpp
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18
19 // CLASS HEADER
20 #include "shader-api.h"
21
22 // EXTERNAL INCLUDES
23 #include <dali/public-api/object/type-registry.h>
24
25 // INTERNAL INCLUDES
26 #include <v8-utils.h>
27 #include <rendering/shader-wrapper.h>
28
29 namespace Dali
30 {
31
32 namespace V8Plugin
33 {
34
35 /**
36  * ## Shader API
37  *
38  * Shaders allows custom vertex and color transformations in the GPU
39  *
40  * ### Simple example
41  *
42  *```
43  *    // this will match the default shaders for image
44  *    var vertexShader = " void main() \
45  *    { \
46  *      gl_Position = uProjection * uModelView * vec4(aPosition, 1.0); \
47  *      vTexCoord = aTexCoord; \
48  *    }; "
49  *   var fragShader = " void main() \
50  *    { \
51  *     gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\
52  *    }; "
53  *    var shaderOptions = {
54  *          vertexShader: vertexShader,
55  *          fragmentShader: fragShader
56  *    };
57  *
58  *    var shader = new dali.Shader(shaderOptions);
59  *```
60  * @class Shader
61  * @extends Handle
62  */
63
64 namespace // unnamed namespace
65 {
66
67 typedef  std::vector< std::string > HintsArray;
68
69 struct ShaderHintPair
70 {
71   const char* name;
72   Shader::ShaderHints hint;
73 };
74
75 const ShaderHintPair ShaderHintTable[]=
76 {
77     {"outputIsTransparent",    Shader::HINT_OUTPUT_IS_TRANSPARENT },
78     {"modifiesGeometry",       Shader::HINT_MODIFIES_GEOMETRY },
79 };
80
81 const unsigned int ShaderHintTableCount = sizeof(ShaderHintTable)/sizeof(ShaderHintTable[0]);
82
83 struct ShaderParameters
84 {
85   ShaderParameters()
86       : mHints( Shader::HINT_NONE )
87   {
88   }
89
90   Shader::ShaderHints GetShaderHint( const std::string& hint )
91   {
92     for( unsigned int i = 0 ; i < ShaderHintTableCount; ++i )
93     {
94       if( hint == ShaderHintTable[i].name )
95       {
96         return ShaderHintTable[i].hint;
97       }
98     }
99     return Shader::HINT_NONE;
100   }
101
102   void ProcessHintsArray( const HintsArray& hintsArray )
103   {
104     for( HintsArray::const_iterator iter  = hintsArray.begin(); iter != hintsArray.end() ; ++iter )
105     {
106       mHints= static_cast<Shader::ShaderHints>( mHints | GetShaderHint( *iter ) );
107     }
108   }
109
110   Shader NewShader()
111   {
112     return Shader::New( mVertex,
113                          mFragment,
114                          mHints);
115   }
116
117   std::string mVertex;
118   std::string mFragment;
119   Shader::ShaderHints mHints;
120 };
121
122 Shader GetShader( v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
123 {
124   v8::HandleScope handleScope( isolate );
125
126   v8::Local<v8::Object> object = args.This();
127   v8::Local<v8::External> field = v8::Local<v8::External>::Cast( object->GetInternalField(0) );
128   void* ptr = field->Value();
129
130   ShaderWrapper* wrapper = static_cast< ShaderWrapper *>(ptr);
131   return wrapper->GetShader();
132 }
133
134 } // unnamed space
135
136 /**
137  * Create a new Shader
138  * @constructor
139  * @for Shader
140  * @method Shader
141  * @param {Object} shaderOptions
142  * @param {String} [shaderOptions.vertexShader] VertexShader code for the shader. If not defined, the default version will be used
143  * @param {String} [shaderOptions.fragmentShader] FragmentShader code for the shader. If not defined, the default version will be used
144  * @param {Array}  [shaderOptions.shaderHints] Hints for rendering/subdividing geometry, e.g.  [ "requiresSelfDepthTest", "outputIsTransparent", "outputIsOpaque","modifiesGeometry" ]
145  * @return {Object} Shader
146  * @example
147
148       // this will match the default shaders for image
149       var vertexShader = " void main() \
150       { \
151         gl_Position = uProjection * uModelView * vec4(aPosition, 1.0); \
152         vTexCoord = aTexCoord; \
153       }; "
154
155       var fragShader = " void main() \
156       { \
157        gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\
158       }; "
159
160       var shaderOptions = {
161             vertexShader: vertexShader,
162             fragmentShader: fragShader
163       };
164
165       var shader = new dali.Shader(shaderOptions);
166  *
167  */
168 Shader ShaderApi::New(  v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
169 {
170   v8::HandleScope handleScope( isolate );
171
172   ShaderParameters shaderParams;
173
174   if( args[0]->IsObject() )
175   {
176     v8::Local<v8::Object > obj = args[0]->ToObject();
177
178     v8::Local<v8::Value> vertexValue = obj->Get(v8::String::NewFromUtf8( isolate, "vertexShader"));
179     if( vertexValue->IsString() )
180     {
181       shaderParams.mVertex = V8Utils::v8StringToStdString( vertexValue );
182     }
183
184     v8::Local<v8::Value> fragmentValue = obj->Get(v8::String::NewFromUtf8( isolate, "fragmentShader"));
185     if( fragmentValue->IsString() )
186     {
187       shaderParams.mFragment = V8Utils::v8StringToStdString( fragmentValue );
188     }
189     // Get any hints
190     v8::Local<v8::Value> hints = obj->Get(v8::String::NewFromUtf8( isolate, "shaderHints"));
191     if( hints->IsArray() )
192     {
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)
196       {
197         v8::Handle<v8::Value> entry = array->Get(  v8::Integer::New( isolate, i) );
198         if( entry->IsString() )
199         {
200           std::string entryString = V8Utils::v8StringToStdString( entry );
201           hintsArray.push_back( entryString );
202         }
203       }
204       shaderParams.ProcessHintsArray( hintsArray );
205     }
206   }
207
208   return shaderParams.NewShader();
209 }
210
211 Shader ShaderApi::GetShaderFromParams( int paramIndex,
212                           bool& found,
213                           v8::Isolate* isolate,
214                           const v8::FunctionCallbackInfo< v8::Value >& args )
215 {
216   found = false;
217
218   v8::HandleScope handleScope( isolate );
219   BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( paramIndex, BaseWrappedObject::SHADER, isolate, args );
220   if( wrappedObject )
221   {
222     found = true;
223     ShaderWrapper* wrapper = static_cast< ShaderWrapper *>(wrappedObject);
224     return wrapper->GetShader();
225   }
226   else
227   {
228     return Shader();
229   }
230 }
231
232 } // namespace V8Plugin
233
234 } // namespace Dali