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)
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,
[2285]23                                                                                                Pass* pass,
24                                                                                                OgreRenderable* parentRenderable,
25                                                                                                OgreTechniqueGroup* parentTechniqueGroup)
26                                                        :RenderTechnique( parentRenderable, parentTechniqueGroup),
27                                                        OgreRenderTechnique(pass, parentRenderable, parentTechniqueGroup),
28                                                        DepthShadowReceiverRenderTechnique(parentRenderable, parentTechniqueGroup)
29{
[2299]30        this->passBlendingSRC = passBlendingSRC;
31        this->passBlendingDEST = passBlendingDEST;
[2285]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;
[2366]43        this->createNewPasses = createNewPasses;
44        this->startTextureUnitID = startTextureUnitID;
[2397]45
46        this->nearestLightsFromCamera = nearestLightsFromCamera;
[2366]47                                                       
48        if(createNewPasses)
49        {
50                //insert new passes
51                Ogre::Technique* techn = pass->getParent();
52                Technique::PassIterator it = techn->getPassIterator();
[2285]53               
[2366]54                int index = 0;
55                while(it.hasMoreElements())
56                {
57                        if( it.getNext() == pass)
58                                break;
59                        index++;
60                        it.moveNext();
61                }
62               
[2285]63                index++;
[2366]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);
[2285]74
[2366]75                        newpass->setSceneBlending(passBlendingSRC, passBlendingDEST);
76                       
77                        newpass->setDepthBias(1);
78                        techn->movePass(lastpass, index);                       
79                }
80        }       
[2285]81}
82
83OgreDepthShadowReceiverRenderTechnique::~OgreDepthShadowReceiverRenderTechnique()
84{
85
86}
87
88void OgreDepthShadowReceiverRenderTechnique::update(unsigned long frameNum)
89{
90        LightList lights;
[2397]91        Vector3 center = OgreIlluminationManager::getSingleton().getMainCamera()->getWorldPosition();
92        if(!nearestLightsFromCamera)
93                center = ((OgreSharedRuns*) sharedRuns)->getRootPosition();
[2285]94        Root::getSingleton()._getCurrentSceneManager()->_populateLightList(
[2397]95                                                        center,
[2285]96                                                        100000.0,
97                                                        lights);
98
99        //fill passes
100        unsigned int l = 0;
[2366]101        for(unsigned int i = 0; i < maxlights; i++)
[2285]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();
[2366]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(
[2285]133                                        depthRun->getDepthMapTextureName());
134                       
[2366]135                                if(createNewPasses)
136                                {
137                                        //TODO: ask programs from illummanager
138                                        passes.at(i)->setVertexProgram(shadowVertexProgram);
139                                        passes.at(i)->setFragmentProgram(shadowFragmentProgram);
140                                }
[2355]141               
[2366]142                                GpuProgramParametersSharedPtr fpParams = passToSet->getFragmentProgramParameters();
143                                GpuProgramParametersSharedPtr vpParams = passToSet->getVertexProgramParameters();
[2333]144
[2366]145                                String LightViewProjParamName = lightViewProjParamName;
146                                String LightViewParamName = lightViewParamName;
147                                String LightFarPlaneParamName = lightFarPlaneParamName;
148                                if(!createNewPasses)
149                                {
[2372]150                                        LightViewProjParamName += StringConverter::toString(i+1);
151                                        LightViewParamName += StringConverter::toString(i+1);
152                                        LightFarPlaneParamName += StringConverter::toString(i+1);
[2366]153                                }
154                                else
155                                {
156                                        vpParams->setNamedAutoConstant(WorldViewProjParamName,
157                                                                                GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);       
158                                        vpParams->setNamedAutoConstant(WorldParamName,
159                                                                                GpuProgramParameters::ACT_WORLD_MATRIX);
160                                }
[2355]161               
[2285]162                                if(setLightViewProjMatrix)
[2366]163                                {
164                                        if(createNewPasses)
165                                        vpParams->setNamedConstant(LightViewProjParamName, depthRun->getLightViewProjMatrix());
166                                        else
167                                        fpParams->setNamedConstant(LightViewProjParamName, depthRun->getLightViewProjMatrix());
168                                }
[2285]169                                if(setLightViewMatrix)
[2366]170                                {
171                                        if(createNewPasses)
172                                        vpParams->setNamedConstant(LightViewParamName, depthRun->getLightViewMatrix());
173                                        else
174                                        fpParams->setNamedConstant(LightViewParamName, depthRun->getLightViewMatrix());
175                                }
[2285]176                                if(setLightProjFarPlane)
[2366]177                                {
178                                        if(createNewPasses)
179                                        fpParams->setNamedConstant(LightFarPlaneParamName, depthRun->getLightFarPlane());
180                                        else
181                                        fpParams->setNamedConstant(LightFarPlaneParamName, depthRun->getLightFarPlane());
182                                }
[2285]183                }       
[2366]184                else if(createNewPasses)
[2285]185                        passes.at(i)->setActive(false);
186
[2372]187                l++;
[2285]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        }
[2299]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                }               
[2366]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        }
[2397]344        void parseNearestFromCamera(String& params, RenderTechniqueFactory* factory)
345        {
346                OgreDepthShadowReceiverRenderTechniqueFactory* f = (OgreDepthShadowReceiverRenderTechniqueFactory*) factory;
347                f->nearestLightsFromCamera = StringConverter::parseBool(params);
348        }
[2285]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));
[2299]368        this->attributeParsers.insert(AttribParserList::value_type("pass_blending", (ILLUM_ATTRIBUTE_PARSER) parsePassBlending));
[2366]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)); 
[2397]371        this->attributeParsers.insert(AttribParserList::value_type("nearest_from_camera", (ILLUM_ATTRIBUTE_PARSER) parseNearestFromCamera));   
[2285]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";
[2297]384        setLightViewMatrix = true;
[2285]385        setLightViewProjMatrix = true;
386        setLightProjFarPlane = false;
387        lightViewProjParamName = "LightViewProj";
388        lightViewParamName = "LightView";
389        lightFarPlaneParamName = "lightFarPlane";
390        WorldViewProjParamName = "WorldViewProj";
391        WorldParamName = "World";
[2299]392        passBlendingSRC = SBF_DEST_COLOUR;
393        passBlendingDEST = SBF_ZERO;
[2366]394        createNewPasses = true;
395        startTextureUnitID = 0;
[2397]396        nearestLightsFromCamera = true;
[2366]397       
[2285]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,
[2299]412                                                                                                passBlendingSRC,
413                                                                                                passBlendingDEST,
[2366]414                                                                                                createNewPasses,
415                                                                                                startTextureUnitID,
[2397]416                                                                                                nearestLightsFromCamera,
[2285]417                                                                                                pass,
418                                                                                                parentRenderable,
419                                                                                                parentTechniqueGroup); 
420
421        return result;
422}
423
[2397]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.