1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14 
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17 
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 THE SOFTWARE.
25 -----------------------------------------------------------------------------
26 */
27 
28 #include "OgreShaderPrecompiledHeaders.h"
29 
30 namespace Ogre {
31 namespace RTShader {
32 
typeFromContent(Parameter::Content content)33 static GpuConstantType typeFromContent(Parameter::Content content)
34 {
35     switch (content)
36     {
37     case Parameter::SPC_COLOR_DIFFUSE:
38     case Parameter::SPC_COLOR_SPECULAR:
39     case Parameter::SPC_POSITION_PROJECTIVE_SPACE:
40     case Parameter::SPC_POSITION_OBJECT_SPACE:
41     case Parameter::SPC_BLEND_INDICES:
42     case Parameter::SPC_BLEND_WEIGHTS:
43     case Parameter::SPC_POSITION_LIGHT_SPACE0:
44     case Parameter::SPC_POSITION_LIGHT_SPACE1:
45     case Parameter::SPC_POSITION_LIGHT_SPACE2:
46     case Parameter::SPC_POSITION_LIGHT_SPACE3:
47     case Parameter::SPC_POSITION_LIGHT_SPACE4:
48     case Parameter::SPC_POSITION_LIGHT_SPACE5:
49     case Parameter::SPC_POSITION_LIGHT_SPACE6:
50     case Parameter::SPC_POSITION_LIGHT_SPACE7:
51         return GCT_FLOAT4;
52     case Parameter::SPC_NORMAL_TANGENT_SPACE:
53     case Parameter::SPC_NORMAL_OBJECT_SPACE:
54     case Parameter::SPC_NORMAL_WORLD_SPACE:
55     case Parameter::SPC_NORMAL_VIEW_SPACE:
56     case Parameter::SPC_TANGENT_OBJECT_SPACE:
57     case Parameter::SPC_POSTOCAMERA_TANGENT_SPACE:
58     case Parameter::SPC_POSTOCAMERA_OBJECT_SPACE:
59     case Parameter::SPC_POSITION_VIEW_SPACE:
60     case Parameter::SPC_POSITION_WORLD_SPACE:
61     case Parameter::SPC_LIGHTDIRECTION_OBJECT_SPACE0:
62     case Parameter::SPC_LIGHTDIRECTION_OBJECT_SPACE1:
63     case Parameter::SPC_LIGHTDIRECTION_OBJECT_SPACE2:
64     case Parameter::SPC_LIGHTDIRECTION_OBJECT_SPACE3:
65     case Parameter::SPC_LIGHTDIRECTION_OBJECT_SPACE4:
66     case Parameter::SPC_LIGHTDIRECTION_OBJECT_SPACE5:
67     case Parameter::SPC_LIGHTDIRECTION_OBJECT_SPACE6:
68     case Parameter::SPC_LIGHTDIRECTION_OBJECT_SPACE7:
69     case Parameter::SPC_POSTOLIGHT_OBJECT_SPACE0:
70     case Parameter::SPC_POSTOLIGHT_OBJECT_SPACE1:
71     case Parameter::SPC_POSTOLIGHT_OBJECT_SPACE2:
72     case Parameter::SPC_POSTOLIGHT_OBJECT_SPACE3:
73     case Parameter::SPC_POSTOLIGHT_OBJECT_SPACE4:
74     case Parameter::SPC_POSTOLIGHT_OBJECT_SPACE5:
75     case Parameter::SPC_POSTOLIGHT_OBJECT_SPACE6:
76     case Parameter::SPC_POSTOLIGHT_OBJECT_SPACE7:
77     case Parameter::SPC_LIGHTDIRECTION_TANGENT_SPACE0:
78     case Parameter::SPC_LIGHTDIRECTION_TANGENT_SPACE1:
79     case Parameter::SPC_LIGHTDIRECTION_TANGENT_SPACE2:
80     case Parameter::SPC_LIGHTDIRECTION_TANGENT_SPACE3:
81     case Parameter::SPC_LIGHTDIRECTION_TANGENT_SPACE4:
82     case Parameter::SPC_LIGHTDIRECTION_TANGENT_SPACE5:
83     case Parameter::SPC_LIGHTDIRECTION_TANGENT_SPACE6:
84     case Parameter::SPC_LIGHTDIRECTION_TANGENT_SPACE7:
85     case Parameter::SPC_POSTOLIGHT_TANGENT_SPACE0:
86     case Parameter::SPC_POSTOLIGHT_TANGENT_SPACE1:
87     case Parameter::SPC_POSTOLIGHT_TANGENT_SPACE2:
88     case Parameter::SPC_POSTOLIGHT_TANGENT_SPACE3:
89     case Parameter::SPC_POSTOLIGHT_TANGENT_SPACE4:
90     case Parameter::SPC_POSTOLIGHT_TANGENT_SPACE5:
91     case Parameter::SPC_POSTOLIGHT_TANGENT_SPACE6:
92     case Parameter::SPC_POSTOLIGHT_TANGENT_SPACE7:
93         return GCT_FLOAT3;
94     case Parameter::SPC_POINTSPRITE_COORDINATE:
95         return GCT_FLOAT2;
96     case Parameter::SPC_POINTSPRITE_SIZE:
97     case Parameter::SPC_DEPTH_VIEW_SPACE:
98         return GCT_FLOAT1;
99     default:
100         OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "cannot derive type from content");
101         break;
102     }
103 }
104 
semanticFromContent(Parameter::Content content,bool isVSOut=false)105 static Parameter::Semantic semanticFromContent(Parameter::Content content, bool isVSOut = false)
106 {
107     switch (content)
108     {
109     case Parameter::SPC_COLOR_DIFFUSE:
110     case Parameter::SPC_COLOR_SPECULAR:
111         return Parameter::SPS_COLOR;
112     case Parameter::SPC_POSITION_PROJECTIVE_SPACE:
113         return Parameter::SPS_POSITION;
114     case Parameter::SPC_BLEND_INDICES:
115         return Parameter::SPS_BLEND_INDICES;
116     case Parameter::SPC_BLEND_WEIGHTS:
117         return Parameter::SPS_BLEND_WEIGHTS;
118     case Parameter::SPC_TANGENT_OBJECT_SPACE:
119         return Parameter::SPS_TANGENT;
120     case Parameter::SPC_POINTSPRITE_COORDINATE:
121         return Parameter::SPS_TEXTURE_COORDINATES;
122     case Parameter::SPC_POSITION_OBJECT_SPACE:
123         if(!isVSOut) return Parameter::SPS_POSITION;
124         OGRE_FALLTHROUGH;
125     case Parameter::SPC_NORMAL_OBJECT_SPACE:
126         if(!isVSOut) return Parameter::SPS_NORMAL;
127         OGRE_FALLTHROUGH;
128     // the remaining types are VS output types only (or indeed texcoord)
129     // for out types we use the TEXCOORD[n] semantics for compatibility
130     // with Cg, HLSL SM2.0 where they are the only multivariate semantics
131     default:
132         return Parameter::SPS_TEXTURE_COORDINATES;
133     }
134 }
135 
136 /// fixed index for texcoords, next free semantic slot else
indexFromContent(Parameter::Content content)137 static int indexFromContent(Parameter::Content content)
138 {
139     int c = int(content);
140     if(c < Parameter::SPC_TEXTURE_COORDINATE0 || c > Parameter::SPC_TEXTURE_COORDINATE7)
141         return -1;
142 
143     return c - Parameter::SPC_TEXTURE_COORDINATE0;
144 }
145 
callFunction(const char * name,const InOut & inout) const146 void FunctionStageRef::callFunction(const char* name, const InOut& inout) const
147 {
148     callFunction(name, std::vector<Operand>{inout});
149 }
150 
callFunction(const char * name,const std::vector<Operand> & params) const151 void FunctionStageRef::callFunction(const char* name, const std::vector<Operand>& params) const
152 {
153     auto function = new FunctionInvocation(name, mStage);
154     function->setOperands(params);
155     mParent->addAtomInstance(function);
156 }
157 
sampleTexture(const std::vector<Operand> & params) const158 void FunctionStageRef::sampleTexture(const std::vector<Operand>& params) const
159 {
160     auto function = new SampleTextureAtom(mStage);
161     function->setOperands(params);
162     mParent->addAtomInstance(function);
163 }
164 
assign(const std::vector<Operand> & params) const165 void FunctionStageRef::assign(const std::vector<Operand>& params) const
166 {
167     auto function = new AssignmentAtom(mStage);
168     function->setOperands(params);
169     mParent->addAtomInstance(function);
170 }
171 
172 //-----------------------------------------------------------------------------
Function(const String & name,const String & desc,const FunctionType functionType)173 Function::Function(const String& name, const String& desc, const FunctionType functionType)
174 {
175     mName           = name;
176     mDescription    = desc;
177     mFunctionType   = functionType;
178 }
179 
180 //-----------------------------------------------------------------------------
~Function()181 Function::~Function()
182 {
183     std::map<size_t, FunctionAtomInstanceList>::iterator jt;
184     for(jt = mAtomInstances.begin(); jt != mAtomInstances.end(); ++jt)
185     {
186         for (FunctionAtomInstanceIterator it=jt->second.begin(); it != jt->second.end(); ++it)
187             OGRE_DELETE (*it);
188     }
189 
190     mAtomInstances.clear();
191 
192     for (ShaderParameterIterator it = mInputParameters.begin(); it != mInputParameters.end(); ++it)
193         (*it).reset();
194     mInputParameters.clear();
195 
196     for (ShaderParameterIterator it = mOutputParameters.begin(); it != mOutputParameters.end(); ++it)
197         (*it).reset();
198     mOutputParameters.clear();
199 
200     for (ShaderParameterIterator it = mLocalParameters.begin(); it != mLocalParameters.end(); ++it)
201         (*it).reset();
202     mLocalParameters.clear();
203 
204 }
205 
206 //-----------------------------------------------------------------------------
resolveInputParameter(Parameter::Semantic semantic,int index,const Parameter::Content content,GpuConstantType type)207 ParameterPtr Function::resolveInputParameter(Parameter::Semantic semantic,
208                                         int index,
209                                         const Parameter::Content content,
210                                         GpuConstantType type)
211 {
212     if(type == GCT_UNKNOWN)
213         type = typeFromContent(content);
214 
215     ParameterPtr param;
216 
217     // Check if desired parameter already defined.
218     param = _getParameterByContent(mInputParameters, content, type);
219     if (param.get() != NULL)
220         return param;
221 
222     if(semantic == Parameter::SPS_UNKNOWN)
223     {
224         semantic = semanticFromContent(content);
225         index = indexFromContent(content); // create new parameter for this content
226     }
227 
228     // Case we have to create new parameter.
229     if (index == -1)
230     {
231         index = 0;
232 
233         // Find the next available index of the target semantic.
234         ShaderParameterIterator it;
235 
236         for (it = mInputParameters.begin(); it != mInputParameters.end(); ++it)
237         {
238             if ((*it)->getSemantic() == semantic)
239             {
240                 index++;
241             }
242         }
243     }
244     else
245     {
246         // Check if desired parameter already defined.
247         param = _getParameterBySemantic(mInputParameters, semantic, index);
248         if (param.get() != NULL && param->getContent() == content)
249         {
250             if (param->getType() == type)
251             {
252                 return param;
253             }
254             else
255             {
256                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
257                     "Can not resolve parameter - semantic: " + StringConverter::toString(semantic) + " - index: " + StringConverter::toString(index) + " due to type mismatch. Function <" + getName() + ">",
258                     "Function::resolveInputParameter" );
259             }
260         }
261     }
262 
263 
264 
265     // No parameter found -> create new one.
266     switch (semantic)
267     {
268     case Parameter::SPS_POSITION:
269         assert(type == GCT_FLOAT4);
270         param = ParameterFactory::createInPosition(index);
271         break;
272 
273     case Parameter::SPS_BLEND_WEIGHTS:
274         assert(type == GCT_FLOAT4);
275         param = ParameterFactory::createInWeights(index);
276         break;
277 
278     case Parameter::SPS_BLEND_INDICES:
279 		assert(type == GCT_FLOAT4);
280         param = ParameterFactory::createInIndices(index);
281         break;
282 
283     case Parameter::SPS_NORMAL:
284         assert(type == GCT_FLOAT3);
285         param = ParameterFactory::createInNormal(index);
286         break;
287 
288     case Parameter::SPS_COLOR:
289         assert(type == GCT_FLOAT4);
290         param = ParameterFactory::createInColor(index);
291         break;
292 
293     case Parameter::SPS_TEXTURE_COORDINATES:
294         param = ParameterFactory::createInTexcoord(type, index, content);
295         break;
296 
297     case Parameter::SPS_BINORMAL:
298         assert(type == GCT_FLOAT3);
299         param = ParameterFactory::createInBiNormal(index);
300         break;
301 
302     case Parameter::SPS_TANGENT:
303         assert(type == GCT_FLOAT3);
304         param = ParameterFactory::createInTangent(index);
305         break;
306     case Parameter::SPS_UNKNOWN:
307         break;
308     }
309 
310     if (param.get() != NULL)
311         addInputParameter(param);
312 
313     return param;
314 }
315 
316 //-----------------------------------------------------------------------------
resolveOutputParameter(Parameter::Semantic semantic,int index,Parameter::Content content,GpuConstantType type)317 ParameterPtr Function::resolveOutputParameter(Parameter::Semantic semantic,
318                                             int index,
319                                             Parameter::Content content,
320                                             GpuConstantType type)
321 {
322     if(type == GCT_UNKNOWN)
323         type = typeFromContent(content);
324 
325     ParameterPtr param;
326 
327     // Check if desired parameter already defined.
328     param = _getParameterByContent(mOutputParameters, content, type);
329     if (param.get() != NULL)
330         return param;
331 
332     if(semantic == Parameter::SPS_UNKNOWN)
333     {
334         semantic = semanticFromContent(content, true);
335         index = -1; // create new parameter for this content
336     }
337 
338     // Case we have to create new parameter.
339     if (index == -1)
340     {
341         index = 0;
342 
343         // Find the next available index of the target semantic.
344         ShaderParameterIterator it;
345 
346         for (it = mOutputParameters.begin(); it != mOutputParameters.end(); ++it)
347         {
348             if ((*it)->getSemantic() == semantic)
349             {
350                 index++;
351             }
352         }
353     }
354     else
355     {
356         // Check if desired parameter already defined.
357         param = _getParameterBySemantic(mOutputParameters, semantic, index);
358         if (param.get() != NULL && param->getContent() == content)
359         {
360             if (param->getType() == type)
361             {
362                 return param;
363             }
364             else
365             {
366                 OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
367                     "Can not resolve parameter - semantic: " + StringConverter::toString(semantic) + " - index: " + StringConverter::toString(index) + " due to type mismatch. Function <" + getName() + ">",
368                     "Function::resolveOutputParameter" );
369             }
370         }
371     }
372 
373 
374     // No parameter found -> create new one.
375     switch (semantic)
376     {
377     case Parameter::SPS_POSITION:
378         assert(type == GCT_FLOAT4);
379         param = ParameterFactory::createOutPosition(index);
380         break;
381 
382     case Parameter::SPS_BLEND_WEIGHTS:
383     case Parameter::SPS_BLEND_INDICES:
384         OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
385             "Can not resolve parameter - semantic: " + StringConverter::toString(semantic) + " - index: " + StringConverter::toString(index) + " since support in it is not implemented yet. Function <" + getName() + ">",
386             "Function::resolveOutputParameter" );
387         break;
388 
389     case Parameter::SPS_NORMAL:
390         assert(type == GCT_FLOAT3);
391         param = ParameterFactory::createOutNormal(index);
392         break;
393 
394     case Parameter::SPS_COLOR:
395         assert(type == GCT_FLOAT4);
396         param = ParameterFactory::createOutColor(index);
397         break;
398 
399     case Parameter::SPS_TEXTURE_COORDINATES:
400         param = ParameterFactory::createOutTexcoord(type, index, content);
401         break;
402 
403     case Parameter::SPS_BINORMAL:
404         assert(type == GCT_FLOAT3);
405         param = ParameterFactory::createOutBiNormal(index);
406         break;
407 
408     case Parameter::SPS_TANGENT:
409         assert(type == GCT_FLOAT3);
410         param = ParameterFactory::createOutTangent(index);
411         break;
412     case Parameter::SPS_UNKNOWN:
413         break;
414     }
415 
416     if (param.get() != NULL)
417         addOutputParameter(param);
418 
419     return param;
420 }
421 
422 //-----------------------------------------------------------------------------
resolveLocalParameter(Parameter::Semantic semantic,int index,const String & name,GpuConstantType type)423 ParameterPtr Function::resolveLocalParameter(Parameter::Semantic semantic, int index,
424                                            const String& name,
425                                            GpuConstantType type)
426 {
427     ParameterPtr param;
428 
429     param = _getParameterByName(mLocalParameters, name);
430     if (param.get() != NULL)
431     {
432         if (param->getType() == type &&
433             param->getSemantic() == semantic &&
434             param->getIndex() == index)
435         {
436             return param;
437         }
438         else
439         {
440             OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
441                 "Can not resolve local parameter due to type mismatch. Function <" + getName() + ">",
442                 "Function::resolveLocalParameter" );
443         }
444     }
445 
446     param = ParameterPtr(OGRE_NEW Parameter(type, name, semantic, index, Parameter::SPC_UNKNOWN));
447     addParameter(mLocalParameters, param);
448 
449     return param;
450 }
451 
452 //-----------------------------------------------------------------------------
resolveLocalParameter(Parameter::Semantic semantic,int index,const Parameter::Content content,GpuConstantType type)453 ParameterPtr Function::resolveLocalParameter(Parameter::Semantic semantic, int index,
454                                            const Parameter::Content content,
455                                            GpuConstantType type)
456 {
457     ParameterPtr param;
458 
459     if(type == GCT_UNKNOWN) type = typeFromContent(content);
460 
461     param = _getParameterByContent(mLocalParameters, content, type);
462     if (param.get() != NULL)
463         return param;
464 
465     param = ParameterPtr(OGRE_NEW Parameter(type, "lLocalParam_" + StringConverter::toString(mLocalParameters.size()), semantic, index, content));
466     addParameter(mLocalParameters, param);
467 
468     return param;
469 }
470 
471 //-----------------------------------------------------------------------------
addInputParameter(ParameterPtr parameter)472 void Function::addInputParameter(ParameterPtr parameter)
473 {
474 
475     // Check that parameter with the same semantic and index in input parameters list.
476     if (_getParameterBySemantic(mInputParameters, parameter->getSemantic(), parameter->getIndex()).get() != NULL)
477     {
478         OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
479             "Parameter <" + parameter->getName() + "> has equal sematic parameter in function <" + getName() + ">",
480             "Function::addInputParameter" );
481     }
482 
483     addParameter(mInputParameters, parameter);
484 }
485 
486 //-----------------------------------------------------------------------------
addOutputParameter(ParameterPtr parameter)487 void Function::addOutputParameter(ParameterPtr parameter)
488 {
489     // Check that parameter with the same semantic and index in output parameters list.
490     if (_getParameterBySemantic(mOutputParameters, parameter->getSemantic(), parameter->getIndex()).get() != NULL)
491     {
492         OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
493             "Parameter <" + parameter->getName() + "> has equal sematic parameter in function <" + getName() + ">",
494             "Function::addOutputParameter" );
495     }
496 
497     addParameter(mOutputParameters, parameter);
498 }
499 
500 //-----------------------------------------------------------------------------
deleteInputParameter(ParameterPtr parameter)501 void Function::deleteInputParameter(ParameterPtr parameter)
502 {
503     deleteParameter(mInputParameters, parameter);
504 }
505 
506 //-----------------------------------------------------------------------------
deleteOutputParameter(ParameterPtr parameter)507 void Function::deleteOutputParameter(ParameterPtr parameter)
508 {
509     deleteParameter(mOutputParameters, parameter);
510 }
511 
512 //-----------------------------------------------------------------------------
deleteAllInputParameters()513 void Function::deleteAllInputParameters()
514 {
515     mInputParameters.clear();
516 }
517 
518 //-----------------------------------------------------------------------------
deleteAllOutputParameters()519 void Function::deleteAllOutputParameters()
520 {
521     mOutputParameters.clear();
522 }
523 //-----------------------------------------------------------------------------
addParameter(ShaderParameterList & parameterList,ParameterPtr parameter)524 void Function::addParameter(ShaderParameterList& parameterList, ParameterPtr parameter)
525 
526 {
527     // Check that parameter with the same name doest exist in input parameters list.
528     if (_getParameterByName(mInputParameters, parameter->getName()).get() != NULL)
529     {
530         OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
531             "Parameter <" + parameter->getName() + "> already declared in function <" + getName() + ">",
532             "Function::addParameter" );
533     }
534 
535     // Check that parameter with the same name doest exist in output parameters list.
536     if (_getParameterByName(mOutputParameters, parameter->getName()).get() != NULL)
537     {
538         OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS,
539             "Parameter <" + parameter->getName() + "> already declared in function <" + getName() + ">",
540             "Function::addParameter" );
541     }
542 
543 
544     // Add to given parameters list.
545     parameterList.push_back(parameter);
546 }
547 
548 //-----------------------------------------------------------------------------
deleteParameter(ShaderParameterList & parameterList,ParameterPtr parameter)549 void Function::deleteParameter(ShaderParameterList& parameterList, ParameterPtr parameter)
550 {
551     ShaderParameterIterator it;
552 
553     for (it = parameterList.begin(); it != parameterList.end(); ++it)
554     {
555         if (*it == parameter)
556         {
557             (*it).reset();
558             parameterList.erase(it);
559             break;
560         }
561     }
562 }
563 
564 //-----------------------------------------------------------------------------
_getParameterByName(const ShaderParameterList & parameterList,const String & name)565 ParameterPtr Function::_getParameterByName( const ShaderParameterList& parameterList, const String& name )
566 {
567     ShaderParameterConstIterator it;
568 
569     for (it = parameterList.begin(); it != parameterList.end(); ++it)
570     {
571         if ((*it)->getName() == name)
572         {
573             return *it;
574         }
575     }
576 
577     return ParameterPtr();
578 }
579 
580 //-----------------------------------------------------------------------------
_getParameterBySemantic(const ShaderParameterList & parameterList,const Parameter::Semantic semantic,int index)581 ParameterPtr Function::_getParameterBySemantic(const ShaderParameterList& parameterList,
582                                                 const Parameter::Semantic semantic,
583                                                 int index)
584 {
585     ShaderParameterConstIterator it;
586 
587     for (it = parameterList.begin(); it != parameterList.end(); ++it)
588     {
589         if ((*it)->getSemantic() == semantic &&
590             (*it)->getIndex() == index)
591         {
592             return *it;
593         }
594     }
595 
596     return ParameterPtr();
597 }
598 
599 //-----------------------------------------------------------------------------
_getParameterByContent(const ShaderParameterList & parameterList,const Parameter::Content content,GpuConstantType type)600 ParameterPtr Function::_getParameterByContent(const ShaderParameterList& parameterList, const Parameter::Content content, GpuConstantType type)
601 {
602     ShaderParameterConstIterator it;
603 
604     if(type == GCT_UNKNOWN)
605         type = typeFromContent(content);
606 
607     // Search only for known content.
608     if (content != Parameter::SPC_UNKNOWN)
609     {
610         for (it = parameterList.begin(); it != parameterList.end(); ++it)
611         {
612             if ((*it)->getContent() == content &&
613                 (*it)->getType() == type)
614             {
615                 return *it;
616             }
617         }
618     }
619 
620     return ParameterPtr();
621 }
622 
623 
624 //-----------------------------------------------------------------------------
addAtomInstance(FunctionAtom * atomInstance)625 void Function::addAtomInstance(FunctionAtom* atomInstance)
626 {
627     mAtomInstances[atomInstance->getGroupExecutionOrder()].push_back(atomInstance);
628     mSortedAtomInstances.clear();
629 }
630 
631 //-----------------------------------------------------------------------------
addAtomAssign(ParameterPtr lhs,ParameterPtr rhs,int groupOrder)632 void Function::addAtomAssign(ParameterPtr lhs, ParameterPtr rhs, int groupOrder)
633 {
634     addAtomInstance(OGRE_NEW AssignmentAtom(lhs, rhs, groupOrder));
635 }
636 
637 //-----------------------------------------------------------------------------
deleteAtomInstance(FunctionAtom * atomInstance)638 bool Function::deleteAtomInstance(FunctionAtom* atomInstance)
639 {
640     FunctionAtomInstanceIterator it;
641     size_t g = atomInstance->getGroupExecutionOrder();
642     for (it=mAtomInstances[g].begin(); it != mAtomInstances[g].end(); ++it)
643     {
644         if (*it == atomInstance)
645         {
646             OGRE_DELETE atomInstance;
647             mAtomInstances[g].erase(it);
648             mSortedAtomInstances.clear();
649             return true;
650         }
651     }
652 
653     return false;
654 
655 }
656 
657 //-----------------------------------------------------------------------------
getAtomInstances()658 const FunctionAtomInstanceList& Function::getAtomInstances()
659 {
660     if(!mSortedAtomInstances.empty())
661         return mSortedAtomInstances;
662 
663     // put atom instances into order
664     std::map<size_t, FunctionAtomInstanceList>::const_iterator it;
665     for(it = mAtomInstances.begin(); it != mAtomInstances.end(); ++it)
666     {
667         mSortedAtomInstances.insert(mSortedAtomInstances.end(), it->second.begin(),
668                                     it->second.end());
669     }
670 
671     return mSortedAtomInstances;
672 }
673 
674 //-----------------------------------------------------------------------------
getFunctionType() const675 Ogre::RTShader::Function::FunctionType Function::getFunctionType() const
676 {
677     return mFunctionType;
678 }
679 
680 }
681 }
682