Changes following dali-core patch "Wrapped ShaderHints enum inside a struct"
[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::Hint::Value 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::Hint::Value 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::Hint::Value>( 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::Hint::Value mHints;
120 };
121
122 } // unnamed space
123
124 /**
125  * Create a new Shader
126  * @constructor
127  * @for Shader
128  * @method Shader
129  * @param {Object} shaderOptions
130  * @param {String} [shaderOptions.vertexShader] VertexShader code for the shader. If not defined, the default version will be used
131  * @param {String} [shaderOptions.fragmentShader] FragmentShader code for the shader. If not defined, the default version will be used
132  * @param {Array}  [shaderOptions.shaderHints] Hints for rendering/subdividing geometry, e.g.  [ "requiresSelfDepthTest", "outputIsTransparent", "outputIsOpaque","modifiesGeometry" ]
133  * @return {Object} Shader
134  * @example
135
136       // this will match the default shaders for image
137       var vertexShader = " void main() \
138       { \
139         gl_Position = uProjection * uModelView * vec4(aPosition, 1.0); \
140         vTexCoord = aTexCoord; \
141       }; "
142
143       var fragShader = " void main() \
144       { \
145        gl_FragColor = texture2D( sTexture, vTexCoord ) * uColor;\
146       }; "
147
148       var shaderOptions = {
149             vertexShader: vertexShader,
150             fragmentShader: fragShader
151       };
152
153       var shader = new dali.Shader(shaderOptions);
154  *
155  */
156 Shader ShaderApi::New(  v8::Isolate* isolate, const v8::FunctionCallbackInfo< v8::Value >& args )
157 {
158   v8::HandleScope handleScope( isolate );
159
160   ShaderParameters shaderParams;
161
162   if( args[0]->IsObject() )
163   {
164     v8::Local<v8::Object > obj = args[0]->ToObject();
165
166     v8::Local<v8::Value> vertexValue = obj->Get(v8::String::NewFromUtf8( isolate, "vertexShader"));
167     if( vertexValue->IsString() )
168     {
169       shaderParams.mVertex = V8Utils::v8StringToStdString( vertexValue );
170     }
171
172     v8::Local<v8::Value> fragmentValue = obj->Get(v8::String::NewFromUtf8( isolate, "fragmentShader"));
173     if( fragmentValue->IsString() )
174     {
175       shaderParams.mFragment = V8Utils::v8StringToStdString( fragmentValue );
176     }
177     // Get any hints
178     v8::Local<v8::Value> hints = obj->Get(v8::String::NewFromUtf8( isolate, "shaderHints"));
179     if( hints->IsArray() )
180     {
181       HintsArray hintsArray;
182       v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast( hints );
183       for( uint32_t i=0; i <  array->Length(); ++i)
184       {
185         v8::Handle<v8::Value> entry = array->Get(  v8::Integer::New( isolate, i) );
186         if( entry->IsString() )
187         {
188           std::string entryString = V8Utils::v8StringToStdString( entry );
189           hintsArray.push_back( entryString );
190         }
191       }
192       shaderParams.ProcessHintsArray( hintsArray );
193     }
194   }
195
196   return shaderParams.NewShader();
197 }
198
199 Shader ShaderApi::GetShaderFromParams( int paramIndex,
200                           bool& found,
201                           v8::Isolate* isolate,
202                           const v8::FunctionCallbackInfo< v8::Value >& args )
203 {
204   found = false;
205
206   v8::HandleScope handleScope( isolate );
207   BaseWrappedObject* wrappedObject = V8Utils::GetWrappedDaliObjectParameter( paramIndex, BaseWrappedObject::SHADER, isolate, args );
208   if( wrappedObject )
209   {
210     found = true;
211     ShaderWrapper* wrapper = static_cast< ShaderWrapper *>(wrappedObject);
212     return wrapper->GetShader();
213   }
214   else
215   {
216     return Shader();
217   }
218 }
219
220 } // namespace V8Plugin
221
222 } // namespace Dali