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

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