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

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