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

Revision 2475, 9.8 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 = this->clusters->pathMapResolution * this->clusters->count;
55        int prmyres = this->clusters->pathMapResolution;
56        while(prmxres > 4096)
57        {
58                prmxres /= 2;
59                prmyres *= 2;           
60        }
61        int prmnt[2] = {prmxres / this->clusters->pathMapResolution, prmyres / this->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_BORDER);
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()->getWorldPosition(), 1000, lights);
147
148        int found = 0;
149        for(int i = 0 ; found < 2 && i < lights.size(); i++)
150        {
151                if(lights.at(i)->isAttached())
152                {
153                        found ++;
154                        String lightName = lights.at(i)->getName();
155                        OgreIlluminationManager::getSingleton().createPerLightRun(lightName, ILLUMRUN_PM_WEIGHTMAP);
156                        OgreIlluminationManager::getSingleton().updatePerLightRun(lightName, ILLUMRUN_PM_WEIGHTMAP, frameNum);         
157                }
158        }
159        OgrePMWeightComputeRenderingRun::sumWeights(frameNum);
160
161        Pass* passToSet = pass;
162        int textureUnitID = startTextureUnitID + 2;
163        if(createNewPasses)
164        {
165                passToSet = pathMapPass;
166                textureUnitID = 2;
167        }
168        TextureUnitState* st = passToSet->getTextureUnitState(textureUnitID);
169        st->setTextureName(OgrePMWeightComputeRenderingRun::getPMWeightTextureName());
170}
171
172
173
174namespace PathMapParsers
175{
176        SceneBlendFactor convertBlendFactor(const String& param)
177    {
178        if (param == "one")
179            return SBF_ONE;
180        else if (param == "zero")
181            return SBF_ZERO;
182        else if (param == "dest_colour")
183            return SBF_DEST_COLOUR;
184        else if (param == "src_colour")
185            return SBF_SOURCE_COLOUR;
186        else if (param == "one_minus_dest_colour")
187            return SBF_ONE_MINUS_DEST_COLOUR;
188        else if (param == "one_minus_src_colour")
189            return SBF_ONE_MINUS_SOURCE_COLOUR;
190        else if (param == "dest_alpha")
191            return SBF_DEST_ALPHA;
192        else if (param == "src_alpha")
193            return SBF_SOURCE_ALPHA;
194        else if (param == "one_minus_dest_alpha")
195            return SBF_ONE_MINUS_DEST_ALPHA;
196        else if (param == "one_minus_src_alpha")
197            return SBF_ONE_MINUS_SOURCE_ALPHA;       
198    }
199
200        void parsePassBlending(String& params, RenderTechniqueFactory* factory)
201        {
202                OgrePathMapRenderTechniqueFactory* f = (OgrePathMapRenderTechniqueFactory*) factory;
203                StringVector vecparams = StringUtil::split(params, " \t");
204                if(vecparams.size() == 1)
205                {
206                        if (vecparams[0] == "none")
207                        {
208                f->passBlendingSRC =  SBF_ONE;
209                                f->passBlendingDEST = SBF_ZERO;
210                        }
211                        if (vecparams[0] == "add")
212                        {
213                f->passBlendingSRC =  SBF_ONE;
214                                f->passBlendingDEST = SBF_ONE;
215                        }
216            else if (vecparams[0] == "modulate")
217            {
218                                f->passBlendingSRC =  SBF_DEST_COLOUR;
219                                f->passBlendingDEST = SBF_ZERO;
220                        }
221                        else if (vecparams[0] == "colour_blend")
222                        {
223                                f->passBlendingSRC =  SBF_SOURCE_COLOUR;
224                                f->passBlendingDEST = SBF_ONE_MINUS_SOURCE_COLOUR;
225                        }
226            else if (vecparams[0] == "alpha_blend")
227            {
228                f->passBlendingSRC =  SBF_SOURCE_ALPHA;
229                                f->passBlendingDEST = SBF_ONE_MINUS_SOURCE_ALPHA;
230                        }           
231                }
232                else if (vecparams.size() == 2)
233                {
234                  f->passBlendingSRC =  convertBlendFactor(vecparams[0]);
235                  f->passBlendingDEST = convertBlendFactor(vecparams[1]) ;
236                }               
237        }
238
239        void parseCreateNewPasses(String& params, RenderTechniqueFactory* factory)
240        {
241                OgrePathMapRenderTechniqueFactory* f = (OgrePathMapRenderTechniqueFactory*) factory;
242                f->createNewPasses =  StringConverter::parseBool(params);
243        }
244       
245        void parseStartTexID(String& params, RenderTechniqueFactory* factory)
246        {
247                OgrePathMapRenderTechniqueFactory* f = (OgrePathMapRenderTechniqueFactory*) factory;
248                f->startTextureUnitID =  StringConverter::parseInt(params);
249        }
250}
251
252OgrePathMapRenderTechniqueFactory::OgrePathMapRenderTechniqueFactory()
253{
254        typeName = "PathMap";
255        using namespace PathMapParsers;
256        this->attributeParsers.insert(AttribParserList::value_type("pass_blending", (ILLUM_ATTRIBUTE_PARSER) parsePassBlending));
257        this->attributeParsers.insert(AttribParserList::value_type("new_passes", (ILLUM_ATTRIBUTE_PARSER) parseCreateNewPasses));
258        this->attributeParsers.insert(AttribParserList::value_type("start_tex_id", (ILLUM_ATTRIBUTE_PARSER) parseStartTexID)); 
259}
260
261OgreRenderTechnique* OgrePathMapRenderTechniqueFactory::createInstance(
262                                                                                IllumTechniqueParams* params,
263                                                                                Pass* pass,
264                                                                                OgreRenderable* parentRenderable,
265                                                                                OgreTechniqueGroup* parentTechniqueGroup)
266{       
267        passBlendingSRC = SBF_ONE;
268        passBlendingDEST = SBF_ONE;
269        createNewPasses = true;
270        startTextureUnitID = 0;
271
272        parseParams(params);
273
274        OgrePathMapRenderTechnique* result = new OgrePathMapRenderTechnique(
275                                                                                                passBlendingSRC,
276                                                                                                passBlendingDEST,
277                                                                                                createNewPasses,
278                                                                                                startTextureUnitID,
279                                                                                                pass,
280                                                                                                parentRenderable,
281                                                                                                parentTechniqueGroup); 
282
283        return result;
284}
285
Note: See TracBrowser for help on using the repository browser.