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

Revision 2475, 17.3 KB checked in by szirmay, 17 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                                                                                                bool bindToVertexShader,
24                                                                                                Pass* pass,
25                                                                                                OgreRenderable* parentRenderable,
26                                                                                                OgreTechniqueGroup* parentTechniqueGroup)
27                                                        :RenderTechnique( parentRenderable, parentTechniqueGroup),
28                                                        OgreRenderTechnique(pass, parentRenderable, parentTechniqueGroup),
29                                                        DepthShadowReceiverRenderTechnique(parentRenderable, parentTechniqueGroup)
30{
31        this->bindToVertexShader = bindToVertexShader;
32        this->passBlendingSRC = passBlendingSRC;
33        this->passBlendingDEST = passBlendingDEST;
34        this->maxlights = maxlights;
35        this->shadowVertexProgram = shadowVertexProgram ;
36        this->shadowFragmentProgram = shadowFragmentProgram;
37        this->setLightViewMatrix = setLightViewMatrix;
38        this->setLightViewProjMatrix = setLightViewProjMatrix;
39        this->setLightProjFarPlane = setLightProjFarPlane;
40        this->lightViewProjParamName = lightViewProjParamName;
41        this->lightViewParamName = lightViewParamName;
42        this->lightFarPlaneParamName = lightFarPlaneParamName;
43        this->WorldParamName = WorldParamName;
44        this->WorldViewProjParamName = WorldViewProjParamName;
45        this->createNewPasses = createNewPasses;
46        this->startTextureUnitID = startTextureUnitID;
47
48        this->nearestLightsFromCamera = nearestLightsFromCamera;
49                                                       
50        if(createNewPasses)
51        {
52                //insert new passes
53                Ogre::Technique* techn = pass->getParent();
54                Technique::PassIterator it = techn->getPassIterator();
55               
56                int index = 0;
57                while(it.hasMoreElements())
58                {
59                        if( it.getNext() == pass)
60                                break;
61                        index++;
62                        it.moveNext();
63                }
64               
65                index++;
66                for(int i = 0; i < maxlights; i++)
67                {
68                        int lastpass = techn->getNumPasses();
69                        Pass* newpass = techn->createPass();
70                        passes.push_back(newpass);
71                       
72                        TextureUnitState* st = newpass->createTextureUnitState();               
73                        st->setTextureFiltering(TFO_NONE);
74                        st->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
75                        st->setTextureBorderColour(ColourValue::White);
76
77                        newpass->setSceneBlending(passBlendingSRC, passBlendingDEST);
78                       
79                        newpass->setDepthBias(1);
80                        newpass->setVertexProgram(shadowVertexProgram);
81                        newpass->setFragmentProgram(shadowFragmentProgram);
82                       
83                        GpuProgramParametersSharedPtr vpParams = newpass->getVertexProgramParameters();
84                        vpParams->setNamedAutoConstant(WorldViewProjParamName,
85                                                                                GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);       
86                        vpParams->setNamedAutoConstant(WorldParamName,
87                                                                                GpuProgramParameters::ACT_WORLD_MATRIX);
88                        techn->movePass(lastpass, index);                       
89                }
90        }       
91}
92
93OgreDepthShadowReceiverRenderTechnique::~OgreDepthShadowReceiverRenderTechnique()
94{
95
96}
97
98void OgreDepthShadowReceiverRenderTechnique::update(unsigned long frameNum)
99{
100        LightList lights;
101        Vector3 center = OgreIlluminationManager::getSingleton().getMainCamera()->getWorldPosition();
102        if(!nearestLightsFromCamera)
103                center = ((OgreSharedRuns*) sharedRuns)->getRootRenderable()->getParentSceneNode()->_getDerivedPosition();
104                //center = ((OgreSharedRuns*) sharedRuns)->getRootPosition();
105        Root::getSingleton()._getCurrentSceneManager()->_populateLightList(
106                                                        center,
107                                                        100000.0,
108                                                        lights);
109
110        //fill passes
111        unsigned int l = 0;
112        for(unsigned int i = 0; i < maxlights; i++)
113        {
114                int lightcount = lights.size();
115                while( lightcount > l)
116                {
117                        if(!lights.at(l)->getCastShadows() || !lights.at(l)->isAttached())
118                        l++;
119                 else
120                        break;
121                }
122
123                if(lightcount > l)
124                {
125                       
126                                //create run if not exists
127                                OgreIlluminationManager::getSingleton().createPerLightRun(lights.at(l)->getName(),
128                                                                                                                                                        ILLUMRUN_DEPTH_SHADOWMAP);
129                                //update light depth map
130                                OgreIlluminationManager::getSingleton().updatePerLightRun(lights.at(l)->getName(),
131                                                                                                                                                        ILLUMRUN_DEPTH_SHADOWMAP,
132                                                                                                                                                        frameNum);
133                               
134                                //set texture to pass
135                                OgreDepthShadowMapRenderingRun* depthRun =
136                                        (OgreDepthShadowMapRenderingRun*) OgreIlluminationManager::getSingleton()
137                                                                                                                .getPerLightRun(lights.at(l)->getName(),
138                                                                                                                ILLUMRUN_DEPTH_SHADOWMAP)->asOgreRenderingRun();
139                               
140                                Pass* passToSet = this->pass;
141                                int textureUnit = startTextureUnitID + i;
142                                if(createNewPasses)
143                                {
144                                        passToSet = passes.at(i);
145                                        passToSet->setActive(true);
146                                        textureUnit = 0;
147                                        passes.at(i)->setActive(true);
148                                }
149                                passToSet->getTextureUnitState(textureUnit)->setTextureName(
150                                        depthRun->getDepthMapTextureName());
151                                       
152                                GpuProgramParametersSharedPtr fpParams = passToSet->getFragmentProgramParameters();
153                                GpuProgramParametersSharedPtr vpParams = passToSet->getVertexProgramParameters();
154                                GpuProgramParametersSharedPtr variableSetParams = fpParams;
155                                if(bindToVertexShader)
156                                        variableSetParams = vpParams;
157
158                                String LightViewProjParamName = lightViewProjParamName;
159                                String LightViewParamName = lightViewParamName;
160                                String LightFarPlaneParamName = lightFarPlaneParamName;
161                                if(!createNewPasses)
162                                {
163                                        LightViewProjParamName += StringConverter::toString(i+1);
164                                        LightViewParamName += StringConverter::toString(i+1);
165                                        LightFarPlaneParamName += StringConverter::toString(i+1);
166                                }                               
167               
168                                if(setLightViewProjMatrix)
169                                {
170                                        if(createNewPasses)
171                                        vpParams->setNamedConstant(LightViewProjParamName, depthRun->getLightViewProjMatrix());
172                                        else
173                                        variableSetParams->setNamedConstant(LightViewProjParamName, depthRun->getLightViewProjMatrix());
174                                }
175                                if(setLightViewMatrix)
176                                {
177                                        if(createNewPasses)
178                                        vpParams->setNamedConstant(LightViewParamName, depthRun->getLightViewMatrix());
179                                        else
180                                        variableSetParams->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        void parseBindToVertexShader(String& params, RenderTechniqueFactory* factory)
356        {
357                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
358                f->bindToVertexShader = StringConverter::parseBool(params);
359        }
360}
361
362OgreDepthShadowReceiverRenderTechniqueFactory::OgreDepthShadowReceiverRenderTechniqueFactory()
363{
364        typeName = "DepthShadowReceiver";
365
366        using namespace DepthShadowReceiverParsers;
367        //register parsers
368        this->attributeParsers.insert(AttribParserList::value_type("max_light_count", (ILLUM_ATTRIBUTE_PARSER) parseMaxLights));
369        this->attributeParsers.insert(AttribParserList::value_type("vertex_program_name", (ILLUM_ATTRIBUTE_PARSER) parseVertexProgram));
370        this->attributeParsers.insert(AttribParserList::value_type("fragment_program_name", (ILLUM_ATTRIBUTE_PARSER) parseFragmentProgram));
371        this->attributeParsers.insert(AttribParserList::value_type("set_light_viewproj", (ILLUM_ATTRIBUTE_PARSER) parseSetLightViewProj));
372        this->attributeParsers.insert(AttribParserList::value_type("set_light_view", (ILLUM_ATTRIBUTE_PARSER) parseSetLightView));
373        this->attributeParsers.insert(AttribParserList::value_type("set_light_farplane", (ILLUM_ATTRIBUTE_PARSER) parseSetLightFarPlane));
374        this->attributeParsers.insert(AttribParserList::value_type("light_viewproj_param_name", (ILLUM_ATTRIBUTE_PARSER) parseLightProjParamName));
375        this->attributeParsers.insert(AttribParserList::value_type("light_view_param_name", (ILLUM_ATTRIBUTE_PARSER) parseLightViewParamName));
376        this->attributeParsers.insert(AttribParserList::value_type("world_view_proj_param_name", (ILLUM_ATTRIBUTE_PARSER) parseWorldViewProjParamName));
377        this->attributeParsers.insert(AttribParserList::value_type("world_param_name", (ILLUM_ATTRIBUTE_PARSER) parseWorldParamName));
378        this->attributeParsers.insert(AttribParserList::value_type("light_farplane_param_name", (ILLUM_ATTRIBUTE_PARSER) parseLightFarPlaneParamName));
379        this->attributeParsers.insert(AttribParserList::value_type("pass_blending", (ILLUM_ATTRIBUTE_PARSER) parsePassBlending));
380        this->attributeParsers.insert(AttribParserList::value_type("new_passes", (ILLUM_ATTRIBUTE_PARSER) parseCreateNewPasses));
381        this->attributeParsers.insert(AttribParserList::value_type("start_tex_id", (ILLUM_ATTRIBUTE_PARSER) parseStartTexID)); 
382        this->attributeParsers.insert(AttribParserList::value_type("nearest_from_camera", (ILLUM_ATTRIBUTE_PARSER) parseNearestFromCamera));   
383        this->attributeParsers.insert(AttribParserList::value_type("bind_to_vertex_shader", (ILLUM_ATTRIBUTE_PARSER) parseBindToVertexShader));
384}
385
386OgreRenderTechnique* OgreDepthShadowReceiverRenderTechniqueFactory::createInstance(
387                                                                                IllumTechniqueParams* params,
388                                                                                Pass* pass,
389                                                                                OgreRenderable* parentRenderable,
390                                                                                OgreTechniqueGroup* parentTechniqueGroup)
391{       
392        //reset parameters
393        maxlights = 1;
394        shadowVertexProgram = "GTP/Basic/LightCPos_VS";
395        shadowFragmentProgram = "GTP/Basic/SM/Dist_PS";
396        setLightViewMatrix = true;
397        setLightViewProjMatrix = true;
398        setLightProjFarPlane = false;
399        lightViewProjParamName = "LightViewProj";
400        lightViewParamName = "LightView";
401        lightFarPlaneParamName = "lightFarPlane";
402        WorldViewProjParamName = "WorldViewProj";
403        WorldParamName = "World";
404        passBlendingSRC = SBF_DEST_COLOUR;
405        passBlendingDEST = SBF_ZERO;
406        createNewPasses = true;
407        startTextureUnitID = 0;
408        nearestLightsFromCamera = false;
409        bindToVertexShader = false;
410
411        parseParams(params);
412
413        OgreDepthShadowReceiverRenderTechnique* result = new OgreDepthShadowReceiverRenderTechnique(
414                                                                                                maxlights,
415                                                                                                shadowVertexProgram,
416                                                                                                shadowFragmentProgram,
417                                                                                                WorldViewProjParamName,
418                                                                                                WorldParamName,
419                                                                                                setLightViewMatrix ,
420                                                                                                setLightViewProjMatrix,
421                                                                                                setLightProjFarPlane,
422                                                                                                lightViewProjParamName,
423                                                                                                lightViewParamName,
424                                                                                                lightFarPlaneParamName,
425                                                                                                passBlendingSRC,
426                                                                                                passBlendingDEST,
427                                                                                                createNewPasses,
428                                                                                                startTextureUnitID,
429                                                                                                nearestLightsFromCamera,
430                                                                                                bindToVertexShader,
431                                                                                                pass,
432                                                                                                parentRenderable,
433                                                                                                parentTechniqueGroup); 
434
435        return result;
436}
437
438bool OgreDepthShadowReceiverRenderTechniqueFactory::needMaterialCopy(IllumTechniqueParams* params)
439{
440        nearestLightsFromCamera = true;
441        parseParams(params);
442        if(nearestLightsFromCamera)
443                return false;
444        else
445                 return true;
446}
447
Note: See TracBrowser for help on using the repository browser.