source: GTP/trunk/Lib/Illum/IllumModule/OgreIllumModule/src/RenderTechniques/OgreCausticReceiverRenderTechnique.cpp @ 2475

Revision 2475, 11.7 KB checked in by szirmay, 18 years ago (diff)
Line 
1#include "OgreCausticReceiverRenderTechnique.h"
2#include "OgreTechniqueGroup.h"
3#include "OgreIlluminationManager.h"
4#include "OgreCausticCubeMapRenderingRun.h"
5#include "OgreCubeMapRenderingRun.h"
6
7OgreCausticReceiverRenderTechnique::OgreCausticReceiverRenderTechnique(
8                                                                                                int maxcasters,
9                                                                                                String causticVertexProgram,
10                                                                                                String causticFragmentProgram,
11                                                                                                SceneBlendFactor passBlendingSRC,
12                                                                                                SceneBlendFactor passBlendingDEST,
13                                                                                                bool createNewPasses,
14                                                                                                int startTextureUnitID,
15                                                                                                String casterCenterVariableName,
16                                                                                                String attenuationVariableName,
17                                                                                                bool bindDistanceMap,
18                                                                                                Pass* pass,
19                                                                                                OgreRenderable* parentRenderable,
20                                                                                                OgreTechniqueGroup* parentTechniqueGroup)
21                                                        :RenderTechnique( parentRenderable, parentTechniqueGroup),
22                                                        OgreRenderTechnique(pass, parentRenderable, parentTechniqueGroup),
23                                                        CausticReceiverRenderTechnique(parentRenderable, parentTechniqueGroup)
24{
25        this->passBlendingSRC = passBlendingSRC;
26        this->passBlendingDEST = passBlendingDEST;
27        this->maxcasters = maxcasters;
28        this->causticVertexProgram = causticVertexProgram;
29        this->causticFragmentProgram = causticFragmentProgram;
30        this->createNewPasses = createNewPasses;
31        this->startTextureUnitID = startTextureUnitID;
32        this->casterCenterVariableName = casterCenterVariableName;
33        this->attenuationVariableName = attenuationVariableName;
34        this->bindDistanceMap = bindDistanceMap;
35        bindAttenuation = false;
36        if(attenuationVariableName != "")
37                bindAttenuation = true;
38       
39        if(createNewPasses)
40        {
41                //insert new passes
42                Ogre::Technique* techn = pass->getParent();
43                Technique::PassIterator it = techn->getPassIterator();
44               
45                int index = 0;
46                while(it.hasMoreElements())
47                {
48                        if( it.getNext() == pass)
49                                break;
50                        index++;
51                        it.moveNext();
52                }
53               
54                index++;
55                for(int i = 0; i < maxcasters; i++)
56                {
57                        int lastpass = techn->getNumPasses();
58                        Pass* newpass = techn->createPass();
59                        passes.push_back(newpass);
60
61                        newpass->setVertexProgram(causticVertexProgram);
62                        newpass->setFragmentProgram(causticFragmentProgram);
63                       
64                        GpuProgramParameters* Vparams = newpass->getVertexProgramParameters().getPointer();
65                        Vparams->setNamedAutoConstant("WorldViewProj",
66                                                                                GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
67                        Vparams->setNamedAutoConstant("World",
68                                                                                GpuProgramParameters::ACT_WORLD_MATRIX);
69                        GpuProgramParameters* Fparams = newpass->getFragmentProgramParameters().getPointer();
70                        //Fparams->setNamedConstant("cubeMapCameraPosition", Vector3(0,0,0));
71
72                        TextureUnitState* st = newpass->createTextureUnitState();
73                        st->setTextureFiltering(TFO_BILINEAR);
74                        if(bindDistanceMap)
75                        {
76                                TextureUnitState* st2 = newpass->createTextureUnitState();
77                                st2->setTextureFiltering(TFO_BILINEAR);
78                        }
79
80                        newpass->setSceneBlending(passBlendingSRC, passBlendingDEST);
81                        newpass->setDepthBias(1);               
82                       
83                        techn->movePass(lastpass, index);                       
84                }
85        }
86       
87}
88
89OgreCausticReceiverRenderTechnique::~OgreCausticReceiverRenderTechnique()
90{
91
92}
93
94void OgreCausticReceiverRenderTechnique::update(unsigned long frameNum)
95{
96        //find nearest casters
97        causticCasters.clear();
98        OgreIlluminationManager::getSingleton().getNearestCausticCasters(
99                                ((OgreSharedRuns*)sharedRuns)->getRootPosition(),
100                                &causticCasters,
101                                maxcasters);
102       
103        //fill passes
104        for(unsigned int i = 0; i < maxcasters; i++)
105        {
106                if(causticCasters.size() > i)
107                {
108                        //update caustic caster
109                        causticCasters.at(i)->updateRun(ILLUMRUN_PHOTONMAP, frameNum); 
110                        causticCasters.at(i)->updateRun(ILLUMRUN_CAUSTIC_CUBEMAP, frameNum);
111
112                        //set texture to pass
113                        OgreCausticCubeMapRenderingRun* cauCubeRun =
114                                (OgreCausticCubeMapRenderingRun*) causticCasters.at(i)->
115                                        getRun(ILLUMRUN_CAUSTIC_CUBEMAP)->asOgreRenderingRun();
116                       
117                        Pass* passToSet = this->pass;
118                        int p = bindDistanceMap?i*2:i;
119                        int textureUnit = startTextureUnitID + p;
120                        if(createNewPasses)
121                        {
122                                passToSet = passes.at(i);
123                                passToSet->setActive(true);
124                                textureUnit = 0;
125                        }
126                       
127                        passToSet->getTextureUnitState(textureUnit)->setTextureName(
128                                cauCubeRun->getCausticCubeMapTextureName());
129                        if(bindDistanceMap)
130                        {
131                                OgreCubeMapRenderingRun* distCubeRun =
132                                (OgreCubeMapRenderingRun*) causticCasters.at(i)->
133                                        getRun(ILLUMRUN_DISTANCE_CUBEMAP)->asOgreRenderingRun();
134                                if(distCubeRun)
135                                passToSet->getTextureUnitState(textureUnit + 1)->setTextureName(
136                                        distCubeRun->getCubeMapTextureName());
137                        }
138       
139                        //set caster position nad caustic attenuation
140                        GpuProgramParameters* Fparams = passToSet->getFragmentProgramParameters().getPointer();
141                        String centerVarName = casterCenterVariableName;
142                        String attenuationVarName = attenuationVariableName;
143                        if(!createNewPasses)
144                        {
145                                centerVarName += StringConverter::toString(i+1);
146                                attenuationVarName += StringConverter::toString(i+1);
147                        }
148                        Fparams->setNamedConstant(centerVarName,
149                                                                                causticCasters.at(i)->getRootPosition(ILLUMRUN_CAUSTIC_CUBEMAP));
150                        if(bindAttenuation)
151                        Fparams->setNamedConstant(attenuationVarName,
152                                                                                cauCubeRun->getAttenuation());                 
153                }       
154                else if(createNewPasses)
155                        passes.at(i)->setActive(false);
156        }
157}
158
159
160namespace CausticReceiverParsers
161{
162        ///Technique parsers
163        void parseMaxCasters(String& params, RenderTechniqueFactory* factory)
164        {
165                OgreCausticReceiverRenderTechniqueFactory* f = (OgreCausticReceiverRenderTechniqueFactory*) factory;
166                f->maxcasters =  StringConverter::parseInt(params);
167        }
168
169        void parseVertexProgram(String& params, RenderTechniqueFactory* factory)
170        {
171                OgreCausticReceiverRenderTechniqueFactory* f = (OgreCausticReceiverRenderTechniqueFactory*) factory;
172                f->causticVertexProgram =  params;
173        }
174
175        void parseFragmentProgram(String& params, RenderTechniqueFactory* factory)
176        {
177                OgreCausticReceiverRenderTechniqueFactory* f = (OgreCausticReceiverRenderTechniqueFactory*) factory;
178                f->causticFragmentProgram =  params;
179        }
180       
181        SceneBlendFactor convertBlendFactor(const String& param)
182    {
183        if (param == "one")
184            return SBF_ONE;
185        else if (param == "zero")
186            return SBF_ZERO;
187        else if (param == "dest_colour")
188            return SBF_DEST_COLOUR;
189        else if (param == "src_colour")
190            return SBF_SOURCE_COLOUR;
191        else if (param == "one_minus_dest_colour")
192            return SBF_ONE_MINUS_DEST_COLOUR;
193        else if (param == "one_minus_src_colour")
194            return SBF_ONE_MINUS_SOURCE_COLOUR;
195        else if (param == "dest_alpha")
196            return SBF_DEST_ALPHA;
197        else if (param == "src_alpha")
198            return SBF_SOURCE_ALPHA;
199        else if (param == "one_minus_dest_alpha")
200            return SBF_ONE_MINUS_DEST_ALPHA;
201        else if (param == "one_minus_src_alpha")
202            return SBF_ONE_MINUS_SOURCE_ALPHA;       
203    }
204
205        void parsePassBlending(String& params, RenderTechniqueFactory* factory)
206        {
207                OgreCausticReceiverRenderTechniqueFactory* f = (OgreCausticReceiverRenderTechniqueFactory*) factory;
208                StringVector vecparams = StringUtil::split(params, " \t");
209                if(vecparams.size() == 1)
210                {
211                        if (vecparams[0] == "none")
212                        {
213                f->passBlendingSRC =  SBF_ONE;
214                                f->passBlendingDEST = SBF_ZERO;
215                        }
216                        if (vecparams[0] == "add")
217                        {
218                f->passBlendingSRC =  SBF_ONE;
219                                f->passBlendingDEST = SBF_ONE;
220                        }
221            else if (vecparams[0] == "modulate")
222            {
223                                f->passBlendingSRC =  SBF_DEST_COLOUR;
224                                f->passBlendingDEST = SBF_ZERO;
225                        }
226                        else if (vecparams[0] == "colour_blend")
227                        {
228                                f->passBlendingSRC =  SBF_SOURCE_COLOUR;
229                                f->passBlendingDEST = SBF_ONE_MINUS_SOURCE_COLOUR;
230                        }
231            else if (vecparams[0] == "alpha_blend")
232            {
233                f->passBlendingSRC =  SBF_SOURCE_ALPHA;
234                                f->passBlendingDEST = SBF_ONE_MINUS_SOURCE_ALPHA;
235                        }           
236                }
237                else if (vecparams.size() == 2)
238                {
239                  f->passBlendingSRC =  convertBlendFactor(vecparams[0]);
240                  f->passBlendingDEST = convertBlendFactor(vecparams[1]) ;
241                }               
242        }
243
244        void parseCreateNewPasses(String& params, RenderTechniqueFactory* factory)
245        {
246                OgreCausticReceiverRenderTechniqueFactory* f = (OgreCausticReceiverRenderTechniqueFactory*) factory;
247                f->createNewPasses =  StringConverter::parseBool(params);
248        }
249       
250        void parseStartTexID(String& params, RenderTechniqueFactory* factory)
251        {
252                OgreCausticReceiverRenderTechniqueFactory* f = (OgreCausticReceiverRenderTechniqueFactory*) factory;
253                f->startTextureUnitID =  StringConverter::parseInt(params);
254        }
255       
256        void parseCenterVarName(String& params, RenderTechniqueFactory* factory)
257        {
258                OgreCausticReceiverRenderTechniqueFactory* f = (OgreCausticReceiverRenderTechniqueFactory*) factory;
259                f->casterCenterVariableName =  params;
260        }
261
262        void parseAttenuationVarName(String& params, RenderTechniqueFactory* factory)
263        {
264                OgreCausticReceiverRenderTechniqueFactory* f = (OgreCausticReceiverRenderTechniqueFactory*) factory;
265                f->attenuationVariableName =  params;
266        }
267
268        void parseBindDistanceMap(String& params, RenderTechniqueFactory* factory)
269        {
270                OgreCausticReceiverRenderTechniqueFactory* f = (OgreCausticReceiverRenderTechniqueFactory*) factory;
271                f->bindDistanceMap =  StringConverter::parseBool(params);
272        }
273}
274
275OgreCausticReceiverRenderTechniqueFactory::OgreCausticReceiverRenderTechniqueFactory()
276{
277        typeName = "CausticReceiver";
278
279        using namespace CausticReceiverParsers;
280        //register parsers
281        this->attributeParsers.insert(AttribParserList::value_type("max_caster_count", (ILLUM_ATTRIBUTE_PARSER) parseMaxCasters));
282        this->attributeParsers.insert(AttribParserList::value_type("vertex_program_name", (ILLUM_ATTRIBUTE_PARSER) parseVertexProgram));
283        this->attributeParsers.insert(AttribParserList::value_type("fragment_program_name", (ILLUM_ATTRIBUTE_PARSER) parseFragmentProgram));
284        this->attributeParsers.insert(AttribParserList::value_type("pass_blending", (ILLUM_ATTRIBUTE_PARSER) parsePassBlending));
285        this->attributeParsers.insert(AttribParserList::value_type("new_passes", (ILLUM_ATTRIBUTE_PARSER) parseCreateNewPasses));
286        this->attributeParsers.insert(AttribParserList::value_type("start_tex_id", (ILLUM_ATTRIBUTE_PARSER) parseStartTexID));
287        this->attributeParsers.insert(AttribParserList::value_type("center_var_name", (ILLUM_ATTRIBUTE_PARSER) parseCenterVarName));
288        this->attributeParsers.insert(AttribParserList::value_type("attenuation_var_name", (ILLUM_ATTRIBUTE_PARSER) parseAttenuationVarName)); 
289        this->attributeParsers.insert(AttribParserList::value_type("bind_distance_map", (ILLUM_ATTRIBUTE_PARSER) parseBindDistanceMap));       
290}
291
292OgreRenderTechnique* OgreCausticReceiverRenderTechniqueFactory::createInstance(
293                                                                                IllumTechniqueParams* params,
294                                                                                Pass* pass,
295                                                                                OgreRenderable* parentRenderable,
296                                                                                OgreTechniqueGroup* parentTechniqueGroup)
297{       
298        //reset parameters
299        maxcasters = 1;
300        causticVertexProgram = "GTP/Basic/Shaded_VS";
301        causticFragmentProgram = "GTP/Caustic/GatherCaustic_Cube_PS";
302        passBlendingSRC = SBF_DEST_COLOUR;
303        passBlendingDEST = SBF_ONE;
304        createNewPasses = true;
305        startTextureUnitID = 0;
306        casterCenterVariableName = "cubeMapCameraPosition";
307        attenuationVariableName = "";
308        bindDistanceMap = false;
309
310        parseParams(params);
311
312        OgreCausticReceiverRenderTechnique* result = new OgreCausticReceiverRenderTechnique(
313                                                                                                maxcasters,
314                                                                                                causticVertexProgram,
315                                                                                                causticFragmentProgram,
316                                                                                                passBlendingSRC,
317                                                                                                passBlendingDEST,
318                                                                                                createNewPasses,
319                                                                                                startTextureUnitID,
320                                                                                                casterCenterVariableName,
321                                                                                                attenuationVariableName,
322                                                                                                bindDistanceMap,
323                                                                                                pass,
324                                                                                                parentRenderable,
325                                                                                                parentTechniqueGroup);
326
327        return result;
328}
Note: See TracBrowser for help on using the repository browser.