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

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