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

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