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

Revision 2397, 9.7 KB checked in by szirmay, 17 years ago (diff)
Line 
1#include "OgrePathMapRenderTechnique.h"
2#include "OgreTechniqueGroup.h"
3#include "OgreIlluminationManager.h"
4#include "OgrePMWeightComputeRenderingRun.h"
5
6
7
8OgrePathMapRenderTechnique::OgrePathMapRenderTechnique(                                                                                 
9                                                                                                SceneBlendFactor passBlendingSRC,
10                                                                                                SceneBlendFactor passBlendingDEST,
11                                                                                                bool createNewPasses,
12                                                                                                int startTextureUnitID,
13                                                                                                Pass* pass,
14                                                                                                OgreRenderable* parentRenderable,
15                                                                                                OgreTechniqueGroup* parentTechniqueGroup)
16                                                        :RenderTechnique( parentRenderable, parentTechniqueGroup),
17                                                        OgreRenderTechnique(pass, parentRenderable, parentTechniqueGroup)
18{       
19        this->passBlendingSRC = passBlendingSRC;
20        this->passBlendingDEST = passBlendingDEST;
21        this->createNewPasses = createNewPasses;
22        this->startTextureUnitID = startTextureUnitID;
23
24        this->clusters = OgreIlluminationManager::getSingleton().getPathMapClusters(parentRenderable->getName());
25        Pass* passToSet = pass;
26
27        //insert new pass
28        if(createNewPasses)
29        {
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);
49        }
50
51        //bind fragment program parameters
52        GpuProgramParameters* Fparams = passToSet->getFragmentProgramParameters().getPointer();
53       
54        int prmxres = clusters->pathMapResolution * clusters->count;
55        int prmyres = clusters->pathMapResolution;
56        while(prmxres > 4096)
57        {
58                prmxres /= 2;
59                prmyres *= 2;           
60        }
61        int prmnt[2] = {prmxres / clusters->pathMapResolution, prmyres / clusters->pathMapResolution};
62
63        float halfPixel[2] = {0.5 / prmxres, 0.5 / prmyres};
64        Vector4 pathMapParameters(prmnt[0],prmnt[1],halfPixel[0],halfPixel[1]);
65        Fparams->setNamedConstant("prmAtlasTilesHalfPixel",pathMapParameters);
66       
67        unsigned int clustercount = OgreIlluminationManager::getSingleton().getPathMapClusterLengthsSize();
68        Fparams->setNamedConstant("allClusterCount", (float) clustercount);
69        PathMapClusters* clusters = OgreIlluminationManager::getSingleton().getPathMapClusters(parentOgreRenderable->getName());
70        Fparams->setNamedConstant("clusterCount", (float) clusters->count);
71       
72        TextureUnitState* st1;//path map texture
73        TextureUnitState* st2;//weight index texture
74        TextureUnitState* st3;//weight texture
75                       
76        createWeightIndexTexture();
77       
78        if(createNewPasses)
79        {
80                st1 = passToSet->createTextureUnitState();             
81                st1->setTextureFiltering(TFO_BILINEAR);
82                st1->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
83                st1->setTextureBorderColour(ColourValue::Green);
84
85                st2 = passToSet->createTextureUnitState();             
86                st2->setTextureFiltering(TFO_NONE);
87                st2->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
88                st2->setTextureBorderColour(ColourValue::Red);
89
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());                             
112}
113
114OgrePathMapRenderTechnique::~OgrePathMapRenderTechnique()
115{
116
117}
118
119void OgrePathMapRenderTechnique::createWeightIndexTexture()
120{
121        PathMapClusters* clusters = OgreIlluminationManager::getSingleton().getPathMapClusters(parentOgreRenderable->getName());
122        int width = clusters->count;
123        TexturePtr texPtr = Ogre::TextureManager::getSingleton().createManual(this->parentOgreRenderable->getName() + "_PMWeightIndexTexture",
124                                                                                                                                                "default",
125                                                                                                                                                TEX_TYPE_2D,
126                                                                                                                                                width,
127                                                                                                                                                1,
128                                                                                                                                                0,
129                                                                                                                                                0,
130                                                                                                                                                PF_FLOAT32_R,
131                                                                                                                                                TU_DYNAMIC_WRITE_ONLY);
132        weightIndexTexture = texPtr.getPointer();
133
134        float *weightIndices = new float[width];
135        PixelBox lockBox(width, 1, 1, PF_FLOAT32_R, weightIndices);
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
142void OgrePathMapRenderTechnique::update(unsigned long frameNum)
143{       
144        LightList lights;
145        SceneManager* sm = Root::getSingleton()._getCurrentSceneManager();
146        sm->_populateLightList(OgreIlluminationManager::getSingleton().getMainCamera()->getPosition(), 1000, lights);
147
148        for(int i = 0 ; i < 5 && i < lights.size(); i++)
149        {
150                String lightName = lights.at(i)->getName();
151                OgreIlluminationManager::getSingleton().createPerLightRun(lightName, ILLUMRUN_PM_WEIGHTMAP);
152                OgreIlluminationManager::getSingleton().updatePerLightRun(lightName, ILLUMRUN_PM_WEIGHTMAP, frameNum);         
153        }
154        OgrePMWeightComputeRenderingRun::sumWeights(frameNum);
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);
164        st->setTextureName(OgrePMWeightComputeRenderingRun::getPMWeightTextureName());
165}
166
167
168
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                }               
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        }
245}
246
247OgrePathMapRenderTechniqueFactory::OgrePathMapRenderTechniqueFactory()
248{
249        typeName = "PathMap";
250        using namespace PathMapParsers;
251        this->attributeParsers.insert(AttribParserList::value_type("pass_blending", (ILLUM_ATTRIBUTE_PARSER) parsePassBlending));
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)); 
254}
255
256OgreRenderTechnique* OgrePathMapRenderTechniqueFactory::createInstance(
257                                                                                IllumTechniqueParams* params,
258                                                                                Pass* pass,
259                                                                                OgreRenderable* parentRenderable,
260                                                                                OgreTechniqueGroup* parentTechniqueGroup)
261{       
262        passBlendingSRC = SBF_ONE;
263        passBlendingDEST = SBF_ONE;
264        createNewPasses = true;
265        startTextureUnitID = 0;
266
267        parseParams(params);
268
269        OgrePathMapRenderTechnique* result = new OgrePathMapRenderTechnique(
270                                                                                                passBlendingSRC,
271                                                                                                passBlendingDEST,
272                                                                                                createNewPasses,
273                                                                                                startTextureUnitID,
274                                                                                                pass,
275                                                                                                parentRenderable,
276                                                                                                parentTechniqueGroup); 
277
278        return result;
279}
280
Note: See TracBrowser for help on using the repository browser.