source: GTP/trunk/Lib/Illum/IllumModule/OgreIllumModule/src/RenderTechniques/OgreDepthShadowReceiverRenderTechnique.cpp @ 2406

Revision 2406, 16.5 KB checked in by szirmay, 18 years ago (diff)
Line 
1#include "OgreDepthShadowReceiverRenderTechnique.h"
2#include "OgreTechniqueGroup.h"
3#include "OgreIlluminationManager.h"
4#include "OgreDepthShadowMapRenderingRun.h"
5
6OgreDepthShadowReceiverRenderTechnique::OgreDepthShadowReceiverRenderTechnique(
7                                                                                                int maxlights,
8                                                                                                String shadowVertexProgram,
9                                                                                                String shadowFragmentProgram,
10                                                                                                String WorldViewProjParamName,
11                                                                                                String WorldParamName,
12                                                                                                bool setLightViewMatrix,
13                                                                                                bool setLightViewProjMatrix,
14                                                                                                bool setLightProjFarPlane,
15                                                                                                String lightViewProjParamName,
16                                                                                                String lightViewParamName,
17                                                                                                String lightFarPlaneParamName,
18                                                                                                SceneBlendFactor passBlendingSRC,
19                                                                                                SceneBlendFactor passBlendingDEST,
20                                                                                                bool createNewPasses,
21                                                                                                int startTextureUnitID,
22                                                                                                bool nearestLightsFromCamera,
23                                                                                                Pass* pass,
24                                                                                                OgreRenderable* parentRenderable,
25                                                                                                OgreTechniqueGroup* parentTechniqueGroup)
26                                                        :RenderTechnique( parentRenderable, parentTechniqueGroup),
27                                                        OgreRenderTechnique(pass, parentRenderable, parentTechniqueGroup),
28                                                        DepthShadowReceiverRenderTechnique(parentRenderable, parentTechniqueGroup)
29{
30        this->passBlendingSRC = passBlendingSRC;
31        this->passBlendingDEST = passBlendingDEST;
32        this->maxlights = maxlights;
33        this->shadowVertexProgram = shadowVertexProgram ;
34        this->shadowFragmentProgram = shadowFragmentProgram;
35        this->setLightViewMatrix = setLightViewMatrix;
36        this->setLightViewProjMatrix = setLightViewProjMatrix;
37        this->setLightProjFarPlane = setLightProjFarPlane;
38        this->lightViewProjParamName = lightViewProjParamName;
39        this->lightViewParamName = lightViewParamName;
40        this->lightFarPlaneParamName = lightFarPlaneParamName;
41        this->WorldParamName = WorldParamName;
42        this->WorldViewProjParamName = WorldViewProjParamName;
43        this->createNewPasses = createNewPasses;
44        this->startTextureUnitID = startTextureUnitID;
45
46        this->nearestLightsFromCamera = nearestLightsFromCamera;
47                                                       
48        if(createNewPasses)
49        {
50                //insert new passes
51                Ogre::Technique* techn = pass->getParent();
52                Technique::PassIterator it = techn->getPassIterator();
53               
54                int index = 0;
55                while(it.hasMoreElements())
56                {
57                        if( it.getNext() == pass)
58                                break;
59                        index++;
60                        it.moveNext();
61                }
62               
63                index++;
64                for(int i = 0; i < maxlights; i++)
65                {
66                        int lastpass = techn->getNumPasses();
67                        Pass* newpass = techn->createPass();
68                        passes.push_back(newpass);
69                       
70                        TextureUnitState* st = newpass->createTextureUnitState();               
71                        st->setTextureFiltering(TFO_NONE);
72                        st->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
73                        st->setTextureBorderColour(ColourValue::White);
74
75                        newpass->setSceneBlending(passBlendingSRC, passBlendingDEST);
76                       
77                        newpass->setDepthBias(1);
78                        techn->movePass(lastpass, index);                       
79                }
80        }       
81}
82
83OgreDepthShadowReceiverRenderTechnique::~OgreDepthShadowReceiverRenderTechnique()
84{
85
86}
87
88void OgreDepthShadowReceiverRenderTechnique::update(unsigned long frameNum)
89{
90        LightList lights;
91        Vector3 center = OgreIlluminationManager::getSingleton().getMainCamera()->getWorldPosition();
92        if(!nearestLightsFromCamera)
93                center = ((OgreSharedRuns*) sharedRuns)->getRootPosition();
94        Root::getSingleton()._getCurrentSceneManager()->_populateLightList(
95                                                        center,
96                                                        100000.0,
97                                                        lights);
98
99        //fill passes
100        unsigned int l = 0;
101        for(unsigned int i = 0; i < maxlights; i++)
102        {
103                int lightcount = lights.size();
104                while( lightcount > l)
105                {
106                 if(!lights.at(l)->getCastShadows())
107                        l++;
108                 else
109                        break;
110                }
111
112                if(lightcount > l)
113                {
114                       
115                                //create run if not exists
116                                OgreIlluminationManager::getSingleton().createPerLightRun(lights.at(l)->getName(),
117                                                                                                                                                        ILLUMRUN_DEPTH_SHADOWMAP);
118                                //update light depth map
119                                OgreIlluminationManager::getSingleton().updatePerLightRun(lights.at(l)->getName(),
120                                                                                                                                                        ILLUMRUN_DEPTH_SHADOWMAP,
121                                                                                                                                                        frameNum);
122                               
123                                //set texture to pass
124                                OgreDepthShadowMapRenderingRun* depthRun =
125                                        (OgreDepthShadowMapRenderingRun*) OgreIlluminationManager::getSingleton()
126                                                                                                                .getPerLightRun(lights.at(l)->getName(),
127                                                                                                                ILLUMRUN_DEPTH_SHADOWMAP)->asOgreRenderingRun();
128                               
129                                Pass* passToSet = this->pass;
130                                int textureUnit = startTextureUnitID + i;
131                                if(createNewPasses)
132                                {
133                                        passToSet = passes.at(i);
134                                        passToSet->setActive(true);
135                                        textureUnit = 0;
136                                        passes.at(i)->setActive(true);
137                                }
138                                passToSet->getTextureUnitState(textureUnit)->setTextureName(
139                                        depthRun->getDepthMapTextureName());
140                       
141                                if(createNewPasses)
142                                {
143                                        //TODO: ask programs from illummanager
144                                        passes.at(i)->setVertexProgram(shadowVertexProgram);
145                                        passes.at(i)->setFragmentProgram(shadowFragmentProgram);
146                                }
147               
148                                GpuProgramParametersSharedPtr fpParams = passToSet->getFragmentProgramParameters();
149                                GpuProgramParametersSharedPtr vpParams = passToSet->getVertexProgramParameters();
150
151                                String LightViewProjParamName = lightViewProjParamName;
152                                String LightViewParamName = lightViewParamName;
153                                String LightFarPlaneParamName = lightFarPlaneParamName;
154                                if(!createNewPasses)
155                                {
156                                        LightViewProjParamName += StringConverter::toString(i+1);
157                                        LightViewParamName += StringConverter::toString(i+1);
158                                        LightFarPlaneParamName += StringConverter::toString(i+1);
159                                }
160                                else
161                                {
162                                        vpParams->setNamedAutoConstant(WorldViewProjParamName,
163                                                                                GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);       
164                                        vpParams->setNamedAutoConstant(WorldParamName,
165                                                                                GpuProgramParameters::ACT_WORLD_MATRIX);
166                                }
167               
168                                if(setLightViewProjMatrix)
169                                {
170                                        if(createNewPasses)
171                                        vpParams->setNamedConstant(LightViewProjParamName, depthRun->getLightViewProjMatrix());
172                                        else
173                                        fpParams->setNamedConstant(LightViewProjParamName, depthRun->getLightViewProjMatrix());
174                                }
175                                if(setLightViewMatrix)
176                                {
177                                        if(createNewPasses)
178                                        vpParams->setNamedConstant(LightViewParamName, depthRun->getLightViewMatrix());
179                                        else
180                                        fpParams->setNamedConstant(LightViewParamName, depthRun->getLightViewMatrix());
181                                }
182                                if(setLightProjFarPlane)
183                                {
184                                        if(createNewPasses)
185                                        fpParams->setNamedConstant(LightFarPlaneParamName, depthRun->getLightFarPlane());
186                                        else
187                                        fpParams->setNamedConstant(LightFarPlaneParamName, depthRun->getLightFarPlane());
188                                }
189                }       
190                else if(createNewPasses)
191                        passes.at(i)->setActive(false);
192
193                l++;
194        }
195}
196
197
198///Technique parsers
199namespace DepthShadowReceiverParsers
200{
201        void parseMaxLights(String& params, RenderTechniqueFactory* factory)
202        {
203                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
204                f->maxlights =  StringConverter::parseInt(params);
205        }
206
207        void parseVertexProgram(String& params, RenderTechniqueFactory* factory)
208        {
209                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
210                f->shadowVertexProgram =  params;
211        }
212
213        void parseFragmentProgram(String& params, RenderTechniqueFactory* factory)
214        {
215                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
216                f->shadowFragmentProgram =  params;
217        }
218
219        void parseSetLightViewProj(String& params, RenderTechniqueFactory* factory)
220        {
221                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
222                StringVector vecparams = StringUtil::split(params, " \t");
223                f->setLightViewProjMatrix = StringConverter::parseBool(vecparams[0]);
224                if(f->setLightViewProjMatrix && vecparams.size() > 1)
225                        f->lightViewProjParamName =  vecparams[1];
226        }
227
228        void parseSetLightView(String& params, RenderTechniqueFactory* factory)
229        {
230                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
231                StringVector vecparams = StringUtil::split(params, " \t");
232                f->setLightViewMatrix = StringConverter::parseBool(vecparams[0]);
233                if(f->setLightViewMatrix && vecparams.size() > 1)
234                        f->lightViewParamName =  vecparams[1];
235        }
236
237        void parseSetLightFarPlane(String& params, RenderTechniqueFactory* factory)
238        {
239                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
240                StringVector vecparams = StringUtil::split(params, " \t");
241                f->setLightProjFarPlane = StringConverter::parseBool(vecparams[0]);
242                if(f->setLightProjFarPlane && vecparams.size() > 1)
243                        f->lightFarPlaneParamName =  vecparams[1];
244        }
245
246        void parseLightProjParamName(String& params, RenderTechniqueFactory* factory)
247        {
248                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
249                f->lightViewProjParamName =  params;
250        }
251
252        void parseLightViewParamName(String& params, RenderTechniqueFactory* factory)
253        {
254                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
255                f->lightViewParamName =  params;
256        }
257
258        void parseWorldViewProjParamName(String& params, RenderTechniqueFactory* factory)
259        {
260                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
261                f->WorldViewProjParamName =  params;
262        }
263
264        void parseWorldParamName(String& params, RenderTechniqueFactory* factory)
265        {
266                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
267                f->WorldParamName =  params;
268        }
269
270        void parseLightFarPlaneParamName(String& params, RenderTechniqueFactory* factory)
271        {
272                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
273                f->lightFarPlaneParamName =  params;
274        }
275
276        SceneBlendFactor convertBlendFactor(const String& param)
277    {
278        if (param == "one")
279            return SBF_ONE;
280        else if (param == "zero")
281            return SBF_ZERO;
282        else if (param == "dest_colour")
283            return SBF_DEST_COLOUR;
284        else if (param == "src_colour")
285            return SBF_SOURCE_COLOUR;
286        else if (param == "one_minus_dest_colour")
287            return SBF_ONE_MINUS_DEST_COLOUR;
288        else if (param == "one_minus_src_colour")
289            return SBF_ONE_MINUS_SOURCE_COLOUR;
290        else if (param == "dest_alpha")
291            return SBF_DEST_ALPHA;
292        else if (param == "src_alpha")
293            return SBF_SOURCE_ALPHA;
294        else if (param == "one_minus_dest_alpha")
295            return SBF_ONE_MINUS_DEST_ALPHA;
296        else if (param == "one_minus_src_alpha")
297            return SBF_ONE_MINUS_SOURCE_ALPHA;       
298    }
299
300        void parsePassBlending(String& params, RenderTechniqueFactory* factory)
301        {
302                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
303                StringVector vecparams = StringUtil::split(params, " \t");
304                if(vecparams.size() == 1)
305                {
306                        if (vecparams[0] == "none")
307                        {
308                f->passBlendingSRC =  SBF_ONE;
309                                f->passBlendingDEST = SBF_ZERO;
310                        }
311                        if (vecparams[0] == "add")
312                        {
313                f->passBlendingSRC =  SBF_ONE;
314                                f->passBlendingDEST = SBF_ONE;
315                        }
316            else if (vecparams[0] == "modulate")
317            {
318                                f->passBlendingSRC =  SBF_DEST_COLOUR;
319                                f->passBlendingDEST = SBF_ZERO;
320                        }
321                        else if (vecparams[0] == "colour_blend")
322                        {
323                                f->passBlendingSRC =  SBF_SOURCE_COLOUR;
324                                f->passBlendingDEST = SBF_ONE_MINUS_SOURCE_COLOUR;
325                        }
326            else if (vecparams[0] == "alpha_blend")
327            {
328                f->passBlendingSRC =  SBF_SOURCE_ALPHA;
329                                f->passBlendingDEST = SBF_ONE_MINUS_SOURCE_ALPHA;
330                        }           
331                }
332                else if (vecparams.size() == 2)
333                {
334                  f->passBlendingSRC =  convertBlendFactor(vecparams[0]);
335                  f->passBlendingDEST = convertBlendFactor(vecparams[1]) ;
336                }               
337        }
338
339        void parseCreateNewPasses(String& params, RenderTechniqueFactory* factory)
340        {
341                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
342                f->createNewPasses =  StringConverter::parseBool(params);
343        }
344       
345        void parseStartTexID(String& params, RenderTechniqueFactory* factory)
346        {
347                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
348                f->startTextureUnitID =  StringConverter::parseInt(params);
349        }
350        void parseNearestFromCamera(String& params, RenderTechniqueFactory* factory)
351        {
352                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
353                f->nearestLightsFromCamera = StringConverter::parseBool(params);
354        }
355}
356
357OgreDepthShadowReceiverRenderTechniqueFactory::OgreDepthShadowReceiverRenderTechniqueFactory()
358{
359        typeName = "DepthShadowReceiver";
360
361        using namespace DepthShadowReceiverParsers;
362        //register parsers
363        this->attributeParsers.insert(AttribParserList::value_type("max_light_count", (ILLUM_ATTRIBUTE_PARSER) parseMaxLights));
364        this->attributeParsers.insert(AttribParserList::value_type("vertex_program_name", (ILLUM_ATTRIBUTE_PARSER) parseVertexProgram));
365        this->attributeParsers.insert(AttribParserList::value_type("fragment_program_name", (ILLUM_ATTRIBUTE_PARSER) parseFragmentProgram));
366        this->attributeParsers.insert(AttribParserList::value_type("set_light_viewproj", (ILLUM_ATTRIBUTE_PARSER) parseSetLightViewProj));
367        this->attributeParsers.insert(AttribParserList::value_type("set_light_view", (ILLUM_ATTRIBUTE_PARSER) parseSetLightView));
368        this->attributeParsers.insert(AttribParserList::value_type("set_light_farplane", (ILLUM_ATTRIBUTE_PARSER) parseSetLightFarPlane));
369        this->attributeParsers.insert(AttribParserList::value_type("light_viewproj_param_name", (ILLUM_ATTRIBUTE_PARSER) parseLightProjParamName));
370        this->attributeParsers.insert(AttribParserList::value_type("light_view_param_name", (ILLUM_ATTRIBUTE_PARSER) parseLightViewParamName));
371        this->attributeParsers.insert(AttribParserList::value_type("world_view_proj_param_name", (ILLUM_ATTRIBUTE_PARSER) parseWorldViewProjParamName));
372        this->attributeParsers.insert(AttribParserList::value_type("world_param_name", (ILLUM_ATTRIBUTE_PARSER) parseWorldParamName));
373        this->attributeParsers.insert(AttribParserList::value_type("light_farplane_param_name", (ILLUM_ATTRIBUTE_PARSER) parseLightFarPlaneParamName));
374        this->attributeParsers.insert(AttribParserList::value_type("pass_blending", (ILLUM_ATTRIBUTE_PARSER) parsePassBlending));
375        this->attributeParsers.insert(AttribParserList::value_type("new_passes", (ILLUM_ATTRIBUTE_PARSER) parseCreateNewPasses));
376        this->attributeParsers.insert(AttribParserList::value_type("start_tex_id", (ILLUM_ATTRIBUTE_PARSER) parseStartTexID)); 
377        this->attributeParsers.insert(AttribParserList::value_type("nearest_from_camera", (ILLUM_ATTRIBUTE_PARSER) parseNearestFromCamera));   
378}
379
380OgreRenderTechnique* OgreDepthShadowReceiverRenderTechniqueFactory::createInstance(
381                                                                                IllumTechniqueParams* params,
382                                                                                Pass* pass,
383                                                                                OgreRenderable* parentRenderable,
384                                                                                OgreTechniqueGroup* parentTechniqueGroup)
385{       
386        //reset parameters
387        maxlights = 1;
388        shadowVertexProgram = "GTP/Basic/LightCPos_VS";
389        shadowFragmentProgram = "GTP/Basic/SM/Dist_PS";
390        setLightViewMatrix = true;
391        setLightViewProjMatrix = true;
392        setLightProjFarPlane = false;
393        lightViewProjParamName = "LightViewProj";
394        lightViewParamName = "LightView";
395        lightFarPlaneParamName = "lightFarPlane";
396        WorldViewProjParamName = "WorldViewProj";
397        WorldParamName = "World";
398        passBlendingSRC = SBF_DEST_COLOUR;
399        passBlendingDEST = SBF_ZERO;
400        createNewPasses = true;
401        startTextureUnitID = 0;
402        nearestLightsFromCamera = true;
403       
404        parseParams(params);
405
406        OgreDepthShadowReceiverRenderTechnique* result = new OgreDepthShadowReceiverRenderTechnique(
407                                                                                                maxlights,
408                                                                                                shadowVertexProgram,
409                                                                                                shadowFragmentProgram,
410                                                                                                WorldViewProjParamName,
411                                                                                                WorldParamName,
412                                                                                                setLightViewMatrix ,
413                                                                                                setLightViewProjMatrix,
414                                                                                                setLightProjFarPlane,
415                                                                                                lightViewProjParamName,
416                                                                                                lightViewParamName,
417                                                                                                lightFarPlaneParamName,
418                                                                                                passBlendingSRC,
419                                                                                                passBlendingDEST,
420                                                                                                createNewPasses,
421                                                                                                startTextureUnitID,
422                                                                                                nearestLightsFromCamera,
423                                                                                                pass,
424                                                                                                parentRenderable,
425                                                                                                parentTechniqueGroup); 
426
427        return result;
428}
429
430bool OgreDepthShadowReceiverRenderTechniqueFactory::needMaterialCopy(IllumTechniqueParams* params)
431{
432        nearestLightsFromCamera = true;
433        parseParams(params);
434        if(nearestLightsFromCamera)
435                return false;
436        else
437                 return true;
438}
439
Note: See TracBrowser for help on using the repository browser.