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

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