source: GTP/trunk/Lib/Illum/IBRBillboardCloudTrees/OGRE/src/LBBCBillboardCloudIndirectTextureViewMode.cpp @ 821

Revision 821, 16.7 KB checked in by igarcia, 18 years ago (diff)
Line 
1
2#include "LBBCBillboardCloudIndirectTextureViewMode.h"
3#include "LBBCLeaves.h"
4#include "LBBCManager.h"
5
6namespace LBBC {
7
8BillboardCloudIndirectTextureViewMode::BillboardCloudIndirectTextureViewMode(Ogre::RenderWindow* win, unsigned int ogreFrameListenerModeHandle, bool useBufferedInputKeys, bool useBufferedInputMouse)
9:OBA::OgreFrameListenerMode(win, ogreFrameListenerModeHandle, useBufferedInputKeys, useBufferedInputMouse)
10{       
11        mFrame = 0;
12        mCurrentBillboardGroup = 0;
13        mCurrentBillboard = 0;
14        showDebugOverlay(false);
15        mDebugBillboardGeneration = false;
16        mDebugTextureAtlasGeneration = false;
17}
18
19BillboardCloudIndirectTextureViewMode::~BillboardCloudIndirectTextureViewMode()
20{
21
22}
23
24
25void BillboardCloudIndirectTextureViewMode::setBillboardCloudGroupedTextureAtlasDebug(bool debugTextureAtlasGeneration)
26{
27        mDebugTextureAtlasGeneration = debugTextureAtlasGeneration;
28}
29
30void BillboardCloudIndirectTextureViewMode::configureBillboardOrthogonalAlignedCamera(unsigned int iBillboard)
31{
32        BBC::BillboardPtr billboardPtr = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves()->getBillboardCloud()->getBillboard(iBillboard);
33        Ogre::Vector3 vTopLeft = billboardPtr->getBillboardClusterData()->getQuadTopLeftCorner();
34        Ogre::Vector3 vTopRight = billboardPtr->getBillboardClusterData()->getQuadTopRightCorner();
35        Ogre::Vector3 vBottomLeft = billboardPtr->getBillboardClusterData()->getQuadBottomLeftCorner();
36        Ogre::Vector3 vBottomRight = billboardPtr->getBillboardClusterData()->getQuadBottomRightCorner();
37
38        Ogre::Vector3 vMidPoint = vTopLeft.midPoint(vBottomRight);
39        Ogre::Vector3 vWidth(vTopRight - vTopLeft);
40        Ogre::Vector3 vHeight(vBottomLeft - vTopLeft);
41
42        Ogre::Real w = vWidth.length();
43        Ogre::Real h = vHeight.length();
44        Ogre::Real aspect = w / h;
45        Ogre::Radian fovy = Ogre::Radian(Ogre::Degree(90.0));
46        Ogre::Real nearPlane =  h / Ogre::Math::Tan(fovy/2.0,false);
47        Ogre::Real farPlane = 100000;
48
49        Ogre::Vector3 vUp = vTopLeft - vBottomLeft;
50        vUp.normalise();
51
52        Ogre::Vector3 vI(vTopRight-vTopLeft);
53        vI.normalise();
54
55        Ogre::Vector3 vJ(vBottomLeft-vTopLeft);
56        vJ.normalise();
57
58        Ogre::Vector3 vDir = -vI.crossProduct(vJ);
59        vDir.normalise();
60
61        Ogre::Vector3 vRight = vDir.crossProduct(vUp);
62        vRight.normalise();     
63
64        Ogre::Quaternion qOrientation(vRight, vUp, -vDir);
65       
66        mCamera->setNearClipDistance(nearPlane);
67        mCamera->setOrientation(qOrientation);
68        mCamera->setPosition(vMidPoint - (vDir * (nearPlane*nearPlane)));
69
70        if (Ogre::Root::getSingleton().getRenderSystem()->getName() != "Direct3D9 Rendering SubSystem")
71        {
72                Ogre::Radian thetaY (fovy / 2.0f);
73                Ogre::Real tanThetaY = Ogre::Math::Tan(thetaY);
74
75                Ogre::Real tanThetaX = tanThetaY * aspect;
76
77                Ogre::Real half_w,half_h;
78                half_w = w / 2.0;
79                half_h = h / 2.0;
80
81                Ogre::Real iw = 1.0 / half_w;
82                Ogre::Real ih = 1.0 / half_h;
83                Ogre::Real q;
84                if (farPlane == 0)
85                {
86                        q = 0;
87                }
88                else
89                {
90                        q = 2.0 / (farPlane - nearPlane);
91                }
92                mCustomProjMatrix = Ogre::Matrix4::ZERO;
93                mCustomProjMatrix[0][0] = iw;
94                mCustomProjMatrix[1][1] = ih;
95                mCustomProjMatrix[2][2] = -q;
96                mCustomProjMatrix[2][3] = - (farPlane + nearPlane)/(farPlane - nearPlane);
97                mCustomProjMatrix[3][3] = 1;   
98        }
99        else
100        {
101                Ogre::Radian thetaY (fovy / 2.0f);
102                Ogre::Real tanThetaY = Ogre::Math::Tan(thetaY);
103
104                //Real thetaX = thetaY * aspect;
105                Ogre::Real tanThetaX = tanThetaY * aspect; //Math::Tan(thetaX);
106                Ogre::Real half_w = w / 2;
107                Ogre::Real half_h = h / 2;
108                Ogre::Real iw = 1.0 / half_w;
109                Ogre::Real ih = 1.0 / half_h;
110                Ogre::Real q;
111                if (farPlane == 0)
112                {
113                        q = 0;
114                }
115                else
116                {
117                        q = 1.0 / (farPlane - nearPlane);
118                }
119
120                mCustomProjMatrix = Ogre::Matrix4::ZERO;
121                mCustomProjMatrix[0][0] = iw;
122                mCustomProjMatrix[1][1] = ih;
123                mCustomProjMatrix[2][2] = q;
124                mCustomProjMatrix[2][3] = -nearPlane / (farPlane - nearPlane);
125                mCustomProjMatrix[3][3] = 1;
126
127                mCustomProjMatrix[2][2] = -mCustomProjMatrix[2][2];
128        }       
129}
130
131void BillboardCloudIndirectTextureViewMode::saveTextureAtlas()
132{
133        if (mBitRange == 32)
134        {
135                mDestPixelFormat = Ogre::PF_FLOAT32_RGBA;
136        }
137        else if (mBitRange == 16)
138        {
139                mDestPixelFormat = Ogre::PF_FLOAT16_RGBA;
140        }
141        else  // mBitRange == 8
142        {
143                mDestPixelFormat = Ogre::PF_BYTE_RGBA;
144        }
145
146        Ogre::String textureAtlasFileName = BBC::Util::getBaseName(mTextureAtlasName) + Ogre::StringConverter::toString(mCurrentBillboardGroup) + "." + BBC::Util::getExtensionName(mTextureAtlasName);
147        mTextureAtlas->save(mTextureAtlasFolder, textureAtlasFileName, mDestPixelFormat);
148}
149
150void BillboardCloudIndirectTextureViewMode::configureTexture()
151{
152        mTextureAtlas->getRectangle2D()->setVisible(false);
153
154        //mClusterTexture->getRectangle2D()->setVisible(true);
155        //mClusterTexture->getMaterial()->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("customNormalMap128x128.png");
156        //mClusterTexture->setCorners(-1.0, 1.0, 1.0, -1.0);
157
158        mBillboardCloudPointClusters->getSubEntity((mCurrentTexture-1) % mBillboardCloudPointClusters->getNumSubEntities())->setVisible(false);
159        mBillboardCloudPointClusters->getSubEntity(mCurrentTexture % mBillboardCloudPointClusters->getNumSubEntities())->setVisible(true);
160
161        configureBillboardOrthogonalAlignedCamera(mCurrentTexture % mBillboardCloudSplitted->getNumSubEntities());
162        mCamera->setCustomProjectionMatrix(true,mCustomProjMatrix);
163
164        Ogre::GpuProgramParametersSharedPtr fragParams;
165       
166        fragParams = mBillboardCloudPointClusters->getSubEntity(mCurrentTexture % mBillboardCloudPointClusters->getNumSubEntities())->getMaterial()->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
167        fragParams->setNamedConstant("textureSize", (Ogre::Real)mTextureSize);
168        mBillboardCloudPointClusters->getSubEntity(mCurrentTexture % mBillboardCloudPointClusters->getNumSubEntities())->getMaterial()->reload();
169       
170        if (mDebugTextureAtlasGeneration)
171        {
172                mClusterTexture->getMaterial()->getTechnique(0)->getPass(0)->setAmbient(Ogre::Math::RangeRandom(0.0,1.0), Ogre::Math::RangeRandom(0.0,1.0), Ogre::Math::RangeRandom(0.0,1.0));
173                mClusterTexture->getMaterial()->getTechnique(0)->getPass(0)->setDiffuse(Ogre::Math::RangeRandom(0.0,1.0), Ogre::Math::RangeRandom(0.0,1.0), Ogre::Math::RangeRandom(0.0,1.0), 1.0);
174        }
175}
176
177void BillboardCloudIndirectTextureViewMode::generateTexture()
178{
179        configureTexture();
180       
181        mClusterTexture->update();     
182        //mClusterTexture->debug();
183}
184
185void BillboardCloudIndirectTextureViewMode::setEntityClustersGroupedName(Ogre::String entityClustersGroupedName)
186{
187        mEntityClustersGroupedName = entityClustersGroupedName;
188}
189
190void BillboardCloudIndirectTextureViewMode::initializeEntityClustersGrouped()
191{
192        if (mFrame == 1)
193        {
194                for (unsigned int iSubEntity = 0; iSubEntity < mBillboardCloudPointClusters->getNumSubEntities(); iSubEntity++)
195                {
196                        mEntityClustersGrouped->getSubEntity(iSubEntity)->setVisible(false);
197                }
198        }
199}
200
201void BillboardCloudIndirectTextureViewMode::initializeBillboardCloudPointClusters()
202{
203        if (mFrame == 1)
204        {
205                for (unsigned int iSubEntity = 0; iSubEntity < mBillboardCloudPointClusters->getNumSubEntities(); iSubEntity++)
206                {
207                        mBillboardCloudPointClusters->getSubEntity(iSubEntity)->setVisible(false);
208                }
209        }
210}
211
212void BillboardCloudIndirectTextureViewMode::initializeBillboardCloudSplitted()
213{
214        if (mFrame == 1)
215        {
216                for (unsigned int iSubEntity = 0; iSubEntity < mBillboardCloudSplitted->getNumSubEntities(); iSubEntity++)
217                {
218                        mBillboardCloudSplitted->getSubEntity(iSubEntity)->setVisible(false);
219                }
220        }
221}
222
223bool BillboardCloudIndirectTextureViewMode::processUnbufferedKeyInput(const Ogre::FrameEvent& evt)
224{
225        if (mInputDevice->isKeyDown(Ogre::KC_SPACE))
226    {
227        mCurrentTexture++;
228    }
229
230        return OgreFrameListenerMode::processUnbufferedKeyInput(evt);
231}
232
233void BillboardCloudIndirectTextureViewMode::configureTextureAtlas()
234{
235        mBillboardCloudPointClusters->getSubEntity(mCurrentTexture % mBillboardCloudPointClusters->getNumSubEntities())->setVisible(false);
236
237        mTextureAtlas->getRectangle2D()->setVisible(true);
238
239        Ogre::Vector2 uvMapMax = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves()->getBillboardCloud()->getBillboard(mCurrentTexture % mBillboardCloudPointClusters->getNumSubEntities())->getBillboardClusterData()->getBillboardUVMapMax(0);
240        Ogre::Vector2 uvMapMin = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves()->getBillboardCloud()->getBillboard(mCurrentTexture % mBillboardCloudPointClusters->getNumSubEntities())->getBillboardClusterData()->getBillboardUVMapMin(0);
241
242        mClusterTexture->setCorners(uvMapMin[0], uvMapMax[1], uvMapMax[0], uvMapMin[1]);
243        mClusterTexture->getRectangle2D()->setVisible(true);
244        //mClusterTexture->getMaterial()->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(mClusterTexture->getTextureName());
245}
246
247void BillboardCloudIndirectTextureViewMode::generateTextureAtlas()
248{       
249        configureTextureAtlas();
250
251        mTextureAtlas->update();               
252        //mTextureAtlas->debug();
253       
254        mClusterTexture->getRectangle2D()->setVisible(false);
255}
256
257bool BillboardCloudIndirectTextureViewMode::frameStarted(const Ogre::FrameEvent& evt, Ogre::InputReader *inputReader)
258{
259        showDebugOverlay(false);
260        initializeEntityClustersGrouped();
261    initializeBillboardCloudSplitted();
262        initializeBillboardCloudPointClusters();
263
264        if (mFrame > 1)
265        {               
266                if (!mDebugBillboardGeneration)
267                {
268                        mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(1.0, 1.0, 1.0, 1.0));
269
270                        if (mCurrentTexture < mNumTextures)
271                        {
272                                generateTexture();
273
274                                generateTextureAtlas();
275
276                                mCurrentTexture++;
277                                mCurrentBillboard++;
278
279                                unsigned int numBillboardsCurrentGroups = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves()->getBillboardCloud()->getBillboardGroup(mCurrentBillboardGroup)->getNumBillboards();
280
281                                if (mCurrentBillboard == numBillboardsCurrentGroups)
282                                {
283                                        saveTextureAtlas();
284                                       
285                                        unsigned int numBillboardGroups = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves()->getBillboardCloud()->getNumBillboardGroups();
286
287                                        if (mCurrentBillboardGroup < numBillboardGroups)
288                                        {
289                                                mCurrentBillboard = 0;
290                                                mCurrentBillboardGroup++;                                               
291
292                                                mTextureAtlas->getRectangle2D()->setVisible(false);
293                                                mTextureAtlas->update();
294                                                //mTextureAtlas->debug();
295                                        }
296                                }
297                        }
298
299                        if (mCurrentTexture == mNumTextures)
300                        {                               
301                                mDebugBillboardGeneration = true;
302
303                                mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 0.0, 1.0));
304
305                                mTextureAtlas->getRectangle2D()->setVisible(false);
306
307                                mCurrentTexture = 0;
308                        }
309                }
310                else
311                {
312                        mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(0.0, 0.0, 0.0, 1.0));
313
314                        configureBillboard();
315
316                        configureTexture();
317
318                        mCurrentTexture = mCurrentTexture % mNumTextures;
319                }
320        }
321
322        mFrame++;
323
324        return OgreFrameListenerMode::frameStarted(evt, inputReader);   
325}
326
327void BillboardCloudIndirectTextureViewMode::configureBillboard()
328{
329        mEntityClustersGrouped->getSubEntity((mCurrentTexture-1) % mEntityClustersGrouped->getNumSubEntities())->setVisible(false);
330        mEntityClustersGrouped->getSubEntity(mCurrentTexture % mEntityClustersGrouped->getNumSubEntities())->setVisible(true);
331        mBillboardCloudSplitted->getSubEntity((mCurrentTexture-1) % mBillboardCloudPointClusters->getNumSubEntities())->setVisible(false);
332        mBillboardCloudSplitted->getSubEntity(mCurrentTexture % mBillboardCloudPointClusters->getNumSubEntities())->setVisible(true);
333}
334
335void BillboardCloudIndirectTextureViewMode::setTextureAtlasSize(unsigned int size)
336{
337        mTextureAtlasSize = size;
338}
339
340void BillboardCloudIndirectTextureViewMode::setBillboardCloudPointClustersName(Ogre::String billboardCloudPointClustersName)
341{
342        mBillboardCloudPointClustersName = billboardCloudPointClustersName;
343}
344
345void BillboardCloudIndirectTextureViewMode::setBillboardCloudSplittedName(Ogre::String billboardCloudSplittedName)
346{
347        mBillboardCloudSplittedName = billboardCloudSplittedName;
348}
349
350void BillboardCloudIndirectTextureViewMode::setTextureAtlasBitRange(unsigned int bitRange)
351{
352        mBitRange = bitRange;
353}
354
355void BillboardCloudIndirectTextureViewMode::setTextureSize(unsigned int size)
356{
357        mTextureSize = size;
358}
359
360void BillboardCloudIndirectTextureViewMode::setTextureAtlasFolder(Ogre::String textureAtlasFolder)
361{
362        mTextureAtlasFolder = textureAtlasFolder;
363}
364
365void BillboardCloudIndirectTextureViewMode::setTextureAtlasName(Ogre::String textureAtlasName)
366{
367        mTextureAtlasName = textureAtlasName;
368}
369
370void BillboardCloudIndirectTextureViewMode::createScene()
371{
372        if (mBitRange == 32)
373        {
374                mSrcPixelFormat = Ogre::PF_FLOAT32_RGBA;
375        }
376        else if (mBitRange == 16)
377        {
378                mSrcPixelFormat = Ogre::PF_FLOAT16_RGBA;
379        }
380        else  // mBitRange == 8
381        {
382                mSrcPixelFormat = Ogre::PF_A8R8G8B8;
383        }
384
385        LBBC::Leaves *mLeaves = ((LBBC::LBBCManager*)LBBC::LBBCManager::getSingletonPtr())->getLeaves();
386        Ogre::Vector2 uvMapMax = mLeaves->getBillboardCloud()->getBillboard(0)->getBillboardClusterData()->getBillboardUVMapMax(0);
387        Ogre::Vector2 uvMapMin = mLeaves->getBillboardCloud()->getBillboard(0)->getBillboardClusterData()->getBillboardUVMapMin(0);
388
389        mWindow->getViewport(0)->setBackgroundColour(Ogre::ColourValue(1.0, 1.0, 1.0, 1.0));
390
391        mBillboardCloudPointClustersSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
392        mBillboardCloudSplittedSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
393
394        mBillboardCloudPointClusters = mSceneMgr->createEntity(mBillboardCloudPointClustersName, mBillboardCloudPointClustersName);
395    mBillboardCloudPointClustersSceneNode->attachObject(mBillboardCloudPointClusters);
396
397        mBillboardCloudSplitted = mSceneMgr->createEntity(mBillboardCloudSplittedName, mBillboardCloudSplittedName);
398    mBillboardCloudSplittedSceneNode->attachObject(mBillboardCloudSplitted);
399
400        mEntityClustersGroupedSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
401        mEntityClustersGrouped = mSceneMgr->createEntity(mEntityClustersGroupedName, mEntityClustersGroupedName);
402    mEntityClustersGroupedSceneNode->attachObject(mEntityClustersGrouped);
403
404        mTextureAtlas = IMG::TextureAtlasPtr( new IMG::TextureAtlas() );
405        mTextureAtlas->create("IndirectTextureAtlas", mTextureAtlasSize, mTextureAtlasSize, mSrcPixelFormat, mCamera, Ogre::ColourValue(0.0, 0.0, 0.0));
406        mTextureAtlas->setTextureAtlasSceneNode(mBillboardCloudPointClustersSceneNode);
407        Ogre::MaterialPtr materialPtr1 = Ogre::MaterialManager::getSingleton().create("IndirectTextureAtlasMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);         
408        materialPtr1->getTechnique(0)->getPass(0)->setAlphaRejectSettings(Ogre::CMPF_GREATER_EQUAL, 10);
409        materialPtr1->getTechnique(0)->getPass(0)->createTextureUnitState("transparent.png");
410        materialPtr1->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureFiltering(Ogre::FO_NONE, Ogre::FO_NONE, Ogre::FO_NONE);                   
411        materialPtr1->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
412        materialPtr1->getTechnique(0)->getPass(0)->setLightingEnabled(false);
413        mTextureAtlas->setMaterial(materialPtr1.getPointer());
414        mTextureAtlas->setCorners(-1.0, 1.0, 1.0, -1.0);       
415
416        mClusterTexture = IMG::TexturePtr( new IMG::Texture() );
417        mClusterTexture->create("ClusterIndirectTexture", mTextureSize, mTextureSize, mSrcPixelFormat, mCamera, Ogre::ColourValue(0.0, 0.0, 0.0));
418        Ogre::MaterialPtr materialPtr = Ogre::MaterialManager::getSingleton().create("IndirectTextureMaterial", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);                       
419        if (!mDebugTextureAtlasGeneration)
420        {
421                materialPtr->getTechnique(0)->getPass(0)->createTextureUnitState("customNormalMap128x128.png", 0);
422                materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureFiltering(Ogre::FO_NONE, Ogre::FO_NONE, Ogre::FO_NONE);                     
423                materialPtr->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);         
424
425                materialPtr->getTechnique(0)->createPass();
426                materialPtr->getTechnique(0)->getPass(1)->setSceneBlending(Ogre::SBT_ADD);
427                materialPtr->getTechnique(0)->getPass(1)->setDepthWriteEnabled(false);
428
429                materialPtr->getTechnique(0)->getPass(1)->setAlphaRejectSettings(Ogre::CMPF_GREATER_EQUAL, 10);
430                materialPtr->getTechnique(0)->getPass(1)->createTextureUnitState("ClusterIndirectTexture", 0);
431                materialPtr->getTechnique(0)->getPass(1)->getTextureUnitState(0)->setTextureFiltering(Ogre::FO_NONE, Ogre::FO_NONE, Ogre::FO_NONE);                     
432                materialPtr->getTechnique(0)->getPass(1)->getTextureUnitState(0)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);         
433
434                materialPtr->getTechnique(0)->getPass(0)->setLightingEnabled(false);
435        }
436
437        mClusterTexture->setMaterial(materialPtr.getPointer());
438
439        mTextureAtlas->addTexture(mClusterTexture);
440
441        mNumTextures = mBillboardCloudPointClusters->getNumSubEntities();
442        mCurrentTexture = 0;
443}
444
445void BillboardCloudIndirectTextureViewMode::destroyScene()
446{
447       
448}
449
450}
Note: See TracBrowser for help on using the repository browser.