source: GTP/trunk/Lib/Illum/IllumModule/OgreIllumModule/src/RenderTechniques/OgrePathMapRenderTechnique.cpp @ 2406

Revision 2406, 9.7 KB checked in by szirmay, 17 years ago (diff)
RevLine 
[2185]1#include "OgrePathMapRenderTechnique.h"
2#include "OgreTechniqueGroup.h"
3#include "OgreIlluminationManager.h"
[2189]4#include "OgrePMWeightComputeRenderingRun.h"
[2185]5
6
[2189]7
[2185]8OgrePathMapRenderTechnique::OgrePathMapRenderTechnique(                                                                                 
[2299]9                                                                                                SceneBlendFactor passBlendingSRC,
10                                                                                                SceneBlendFactor passBlendingDEST,
[2366]11                                                                                                bool createNewPasses,
12                                                                                                int startTextureUnitID,
[2185]13                                                                                                Pass* pass,
14                                                                                                OgreRenderable* parentRenderable,
15                                                                                                OgreTechniqueGroup* parentTechniqueGroup)
16                                                        :RenderTechnique( parentRenderable, parentTechniqueGroup),
17                                                        OgreRenderTechnique(pass, parentRenderable, parentTechniqueGroup)
[2189]18{       
[2299]19        this->passBlendingSRC = passBlendingSRC;
20        this->passBlendingDEST = passBlendingDEST;
[2366]21        this->createNewPasses = createNewPasses;
22        this->startTextureUnitID = startTextureUnitID;
[2299]23
[2185]24        this->clusters = OgreIlluminationManager::getSingleton().getPathMapClusters(parentRenderable->getName());
[2366]25        Pass* passToSet = pass;
26
[2185]27        //insert new pass
[2366]28        if(createNewPasses)
[2185]29        {
[2366]30                Ogre::Technique* techn = pass->getParent();
31                Technique::PassIterator it = techn->getPassIterator();
32               
33                int index = 0;
34                while(it.hasMoreElements())
35                {
36                        if( it.getNext() == pass)
37                                break;
38                        index++;
39                        it.moveNext();
40                }
41               
42                Pass* newpass = pathMapPass = passToSet = techn->createPass();
43               
44                newpass->setVertexProgram("GTP/PathMap_VS");
45                newpass->setFragmentProgram("GTP/PathMap_PS");
46
47                GpuProgramParameters* Vparams = passToSet->getVertexProgramParameters().getPointer();
48                Vparams->setNamedAutoConstant("WorldViewProj", GpuProgramParameters::ACT_WORLDVIEWPROJ_MATRIX);
[2185]49        }
[2366]50
51        //bind fragment program parameters
52        GpuProgramParameters* Fparams = passToSet->getFragmentProgramParameters().getPointer();
[2185]53       
[2406]54        int prmxres = this->clusters->pathMapResolution * this->clusters->count;
55        int prmyres = this->clusters->pathMapResolution;
[2185]56        while(prmxres > 4096)
57        {
58                prmxres /= 2;
59                prmyres *= 2;           
60        }
[2406]61        int prmnt[2] = {prmxres / this->clusters->pathMapResolution, prmyres / this->clusters->pathMapResolution};
[2185]62
63        float halfPixel[2] = {0.5 / prmxres, 0.5 / prmyres};
[2189]64        Vector4 pathMapParameters(prmnt[0],prmnt[1],halfPixel[0],halfPixel[1]);
65        Fparams->setNamedConstant("prmAtlasTilesHalfPixel",pathMapParameters);
[2366]66       
[2218]67        unsigned int clustercount = OgreIlluminationManager::getSingleton().getPathMapClusterLengthsSize();
[2200]68        Fparams->setNamedConstant("allClusterCount", (float) clustercount);
69        PathMapClusters* clusters = OgreIlluminationManager::getSingleton().getPathMapClusters(parentOgreRenderable->getName());
70        Fparams->setNamedConstant("clusterCount", (float) clusters->count);
71       
[2366]72        TextureUnitState* st1;//path map texture
73        TextureUnitState* st2;//weight index texture
74        TextureUnitState* st3;//weight texture
75                       
[2200]76        createWeightIndexTexture();
[2189]77       
[2366]78        if(createNewPasses)
79        {
80                st1 = passToSet->createTextureUnitState();             
81                st1->setTextureFiltering(TFO_BILINEAR);
[2406]82                st1->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
[2366]83                st1->setTextureBorderColour(ColourValue::Green);
[2200]84
[2366]85                st2 = passToSet->createTextureUnitState();             
86                st2->setTextureFiltering(TFO_NONE);
87                st2->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
88                st2->setTextureBorderColour(ColourValue::Red);
[2249]89
[2366]90                st3 = passToSet->createTextureUnitState();             
91                st3->setTextureFiltering(TFO_NONE);
92                st3->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
93                st3->setTextureBorderColour(ColourValue::Blue);
94
95                TextureUnitState* st4 = passToSet->createTextureUnitState();           
96                st4->setTextureFiltering(TFO_BILINEAR);
97                st4->setTextureAddressingMode(TextureUnitState::TAM_WRAP);
98                st4->setTextureBorderColour(ColourValue::Blue);
99                st4->setTextureName(pass->getTextureUnitState(0)->getTextureName());
100
101                passToSet->setSceneBlending(passBlendingSRC, passBlendingDEST);
102                passToSet->setDepthBias(1);
103        }
104        else
105        {
106                st1 = pass->getTextureUnitState(startTextureUnitID);
107                st2 = pass->getTextureUnitState(startTextureUnitID + 1);
108                st3 = pass->getTextureUnitState(startTextureUnitID + 2);
109        }
110        st1->setTextureName(clusters->pathMapTextureFilename);         
111        st2->setTextureName(weightIndexTexture->getName());                             
[2185]112}
113
114OgrePathMapRenderTechnique::~OgrePathMapRenderTechnique()
115{
116
117}
118
[2200]119void OgrePathMapRenderTechnique::createWeightIndexTexture()
120{
121        PathMapClusters* clusters = OgreIlluminationManager::getSingleton().getPathMapClusters(parentOgreRenderable->getName());
[2218]122        int width = clusters->count;
[2200]123        TexturePtr texPtr = Ogre::TextureManager::getSingleton().createManual(this->parentOgreRenderable->getName() + "_PMWeightIndexTexture",
124                                                                                                                                                "default",
[2218]125                                                                                                                                                TEX_TYPE_2D,
[2200]126                                                                                                                                                width,
127                                                                                                                                                1,
128                                                                                                                                                0,
129                                                                                                                                                0,
[2218]130                                                                                                                                                PF_FLOAT32_R,
[2200]131                                                                                                                                                TU_DYNAMIC_WRITE_ONLY);
132        weightIndexTexture = texPtr.getPointer();
133
[2218]134        float *weightIndices = new float[width];
135        PixelBox lockBox(width, 1, 1, PF_FLOAT32_R, weightIndices);
[2200]136        for(int j = 0; j< clusters->count; j++)
137                        weightIndices[j] = clusters->clusters[j];
138        weightIndexTexture->getBuffer()->blitFromMemory(lockBox);
139        delete[] weightIndices;
140}
141
[2185]142void OgrePathMapRenderTechnique::update(unsigned long frameNum)
143{       
[2189]144        LightList lights;
145        SceneManager* sm = Root::getSingleton()._getCurrentSceneManager();
[2333]146        sm->_populateLightList(OgreIlluminationManager::getSingleton().getMainCamera()->getPosition(), 1000, lights);
147
148        for(int i = 0 ; i < 5 && i < lights.size(); i++)
[2189]149        {
[2333]150                String lightName = lights.at(i)->getName();
[2189]151                OgreIlluminationManager::getSingleton().createPerLightRun(lightName, ILLUMRUN_PM_WEIGHTMAP);
[2333]152                OgreIlluminationManager::getSingleton().updatePerLightRun(lightName, ILLUMRUN_PM_WEIGHTMAP, frameNum);         
[2189]153        }
[2333]154        OgrePMWeightComputeRenderingRun::sumWeights(frameNum);
[2366]155
156        Pass* passToSet = pass;
157        int textureUnitID = startTextureUnitID + 2;
158        if(createNewPasses)
159        {
160                passToSet = pathMapPass;
161                textureUnitID = 2;
162        }
163        TextureUnitState* st = passToSet->getTextureUnitState(textureUnitID);
[2333]164        st->setTextureName(OgrePMWeightComputeRenderingRun::getPMWeightTextureName());
[2185]165}
166
[2333]167
168
[2299]169namespace PathMapParsers
170{
171        SceneBlendFactor convertBlendFactor(const String& param)
172    {
173        if (param == "one")
174            return SBF_ONE;
175        else if (param == "zero")
176            return SBF_ZERO;
177        else if (param == "dest_colour")
178            return SBF_DEST_COLOUR;
179        else if (param == "src_colour")
180            return SBF_SOURCE_COLOUR;
181        else if (param == "one_minus_dest_colour")
182            return SBF_ONE_MINUS_DEST_COLOUR;
183        else if (param == "one_minus_src_colour")
184            return SBF_ONE_MINUS_SOURCE_COLOUR;
185        else if (param == "dest_alpha")
186            return SBF_DEST_ALPHA;
187        else if (param == "src_alpha")
188            return SBF_SOURCE_ALPHA;
189        else if (param == "one_minus_dest_alpha")
190            return SBF_ONE_MINUS_DEST_ALPHA;
191        else if (param == "one_minus_src_alpha")
192            return SBF_ONE_MINUS_SOURCE_ALPHA;       
193    }
194
195        void parsePassBlending(String& params, RenderTechniqueFactory* factory)
196        {
197                OgrePathMapRenderTechniqueFactory* f = (OgrePathMapRenderTechniqueFactory*) factory;
198                StringVector vecparams = StringUtil::split(params, " \t");
199                if(vecparams.size() == 1)
200                {
201                        if (vecparams[0] == "none")
202                        {
203                f->passBlendingSRC =  SBF_ONE;
204                                f->passBlendingDEST = SBF_ZERO;
205                        }
206                        if (vecparams[0] == "add")
207                        {
208                f->passBlendingSRC =  SBF_ONE;
209                                f->passBlendingDEST = SBF_ONE;
210                        }
211            else if (vecparams[0] == "modulate")
212            {
213                                f->passBlendingSRC =  SBF_DEST_COLOUR;
214                                f->passBlendingDEST = SBF_ZERO;
215                        }
216                        else if (vecparams[0] == "colour_blend")
217                        {
218                                f->passBlendingSRC =  SBF_SOURCE_COLOUR;
219                                f->passBlendingDEST = SBF_ONE_MINUS_SOURCE_COLOUR;
220                        }
221            else if (vecparams[0] == "alpha_blend")
222            {
223                f->passBlendingSRC =  SBF_SOURCE_ALPHA;
224                                f->passBlendingDEST = SBF_ONE_MINUS_SOURCE_ALPHA;
225                        }           
226                }
227                else if (vecparams.size() == 2)
228                {
229                  f->passBlendingSRC =  convertBlendFactor(vecparams[0]);
230                  f->passBlendingDEST = convertBlendFactor(vecparams[1]) ;
231                }               
[2366]232        }
233
234        void parseCreateNewPasses(String& params, RenderTechniqueFactory* factory)
235        {
236                OgrePathMapRenderTechniqueFactory* f = (OgrePathMapRenderTechniqueFactory*) factory;
237                f->createNewPasses =  StringConverter::parseBool(params);
238        }
239       
240        void parseStartTexID(String& params, RenderTechniqueFactory* factory)
241        {
242                OgrePathMapRenderTechniqueFactory* f = (OgrePathMapRenderTechniqueFactory*) factory;
243                f->startTextureUnitID =  StringConverter::parseInt(params);
244        }
[2299]245}
246
[2185]247OgrePathMapRenderTechniqueFactory::OgrePathMapRenderTechniqueFactory()
248{
249        typeName = "PathMap";
[2299]250        using namespace PathMapParsers;
251        this->attributeParsers.insert(AttribParserList::value_type("pass_blending", (ILLUM_ATTRIBUTE_PARSER) parsePassBlending));
[2366]252        this->attributeParsers.insert(AttribParserList::value_type("new_passes", (ILLUM_ATTRIBUTE_PARSER) parseCreateNewPasses));
253        this->attributeParsers.insert(AttribParserList::value_type("start_tex_id", (ILLUM_ATTRIBUTE_PARSER) parseStartTexID)); 
[2185]254}
255
256OgreRenderTechnique* OgrePathMapRenderTechniqueFactory::createInstance(
257                                                                                IllumTechniqueParams* params,
258                                                                                Pass* pass,
259                                                                                OgreRenderable* parentRenderable,
260                                                                                OgreTechniqueGroup* parentTechniqueGroup)
261{       
[2299]262        passBlendingSRC = SBF_ONE;
263        passBlendingDEST = SBF_ONE;
[2366]264        createNewPasses = true;
265        startTextureUnitID = 0;
[2299]266
[2185]267        parseParams(params);
268
269        OgrePathMapRenderTechnique* result = new OgrePathMapRenderTechnique(
[2299]270                                                                                                passBlendingSRC,
271                                                                                                passBlendingDEST,
[2366]272                                                                                                createNewPasses,
273                                                                                                startTextureUnitID,
[2185]274                                                                                                pass,
275                                                                                                parentRenderable,
276                                                                                                parentTechniqueGroup); 
277
278        return result;
279}
280
Note: See TracBrowser for help on using the repository browser.