source: GTP/trunk/App/Demos/Geom/Demo_LodStrips/main.cpp @ 2165

Revision 2165, 13.3 KB checked in by gumbau, 18 years ago (diff)

Solved bug in the LodStrips? demo that prevented the LOD to be changed

Line 
1/*      ==========================================================================
2 *      (C) 2006 Universitat Jaume I
3 *      ==========================================================================
4 *      PROYECT:        GAME TOOLS
5 *      ==========================================================================*/
6/**     CONTENT:       
7        *
8        *
9        *       @file   main.cpp
10/** COMMENTS:
11        * Model must be in "media/models" folder.
12        * Lod file must be in "media/GT" folder.
13/*===========================================================================*/
14#include "ExampleApplication.h"
15#include "GeoLodStripsLibrary.h"
16#include "GeoMeshLoader.h"
17
18
19// Distance values
20#define dist_min 1100
21#define dist_max 2500
22
23// Model name
24#define model_name "dwarf2"
25
26
27//Global variables
28
29Entity* entity;
30Geometry::LodStripsLibrary* myStrips;
31Ogre::Mesh *ogreMesh=NULL;
32Geometry::GeoMeshLoader *meshloader=NULL;
33SceneNode* node;
34
35MaterialPtr *mat;
36
37ColourValue color=ColourValue::Red;
38
39Camera* theCam;
40Entity* pPlaneEnt;
41
42OverlayElement* mInfo;
43OverlayElement* mInfo2;
44OverlayElement* mHelp;
45OverlayElement* mLOD;
46OverlayElement* mShad;
47SceneManager* SceneMgrAux;
48
49char LODStringAuto[]="(F3) LOD Mode: AUTOMATIC";
50char LODStringManu[]="(F3) LOD Mode: MANUAL";
51char ShadON[]       ="(F2) Shadows ON";
52char ShadOFF[]      ="(F2) Shadows OFF";
53
54char HelpString[]="(F1) Quit Help\n"
55                        "This demo shows an example of the LODStrips model in action. The models in the scene\n"
56                        "are associated to a LodStrips object that manage their level of detail.\n"
57                        "The level of detail of the objects depend on the distance to the camera. When the\n"
58                        "camera goes away from them, the level of detail decreases, and when the camera gets\n"
59                        "closer to them the level of detail increases to restore the original geometry of the\n"
60                        "model.\n"
61                        "The current level of detail can be seen in real-time in the bottom-left corner of the screen.\n"
62                        "The level of detail begins to decrease at a certain distance of the crowd, and stops\n"
63                        "decreasing when the objects reach the their minimum LOD. This 'lodding' distance is\n"
64                        "customizable from the source code of the demo.\n\n"
65                        "(F3) LOD Mode   ( AUTOMATIC  vs  MANUAL )\n"
66                        "           MANUAL MODE:  Use (+) and (-) keys to change de LOD\n";
67
68char NoHelpString[]="\n\n\n\n\n\n\n\n\n\n\n\n\n(F1) Help\n";
69
70int num_ogres = 90;
71
72
73class CustomIndexData : public Geometry::IndexData
74{
75private:
76        Ogre::Mesh *targetMesh;
77        Ogre::HardwareIndexBufferSharedPtr ibuf;
78        Ogre::RenderOperation mRenderOp;
79        unsigned long* pIdx;
80public:
81        CustomIndexData(Ogre::Mesh *ogremesh):Geometry::IndexData(){
82                targetMesh=ogremesh;
83                pIdx=NULL;
84        }
85        virtual ~CustomIndexData(void){}
86
87        virtual void Begin(unsigned int submeshid, unsigned int indexcount){
88                targetMesh->getSubMesh(submeshid)->_getRenderOperation(mRenderOp,0);
89                ibuf = mRenderOp.indexData->indexBuffer;
90                mRenderOp.indexData->indexCount = indexcount;
91                pIdx = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
92        }
93        virtual void SetIndex(unsigned int i, unsigned int index){
94                pIdx[i] = index; //lodStripsLib->dataRetrievalInterface->GetIndex(k+offset);
95        }
96        virtual void End(){
97                ibuf->unlock();
98        }
99        virtual void BorrowIndexData(const Geometry::IndexData *){}
100};
101
102class FresnelFrameListener : public ExampleFrameListener
103{
104        float miButtonTimer;
105
106public:
107
108    FresnelFrameListener(RenderWindow* win, Camera* cam)
109        : ExampleFrameListener(win, cam, false, false)
110    {
111                miButtonTimer=0;
112        }
113
114        bool frameStarted(const FrameEvent& evt)
115    {
116                Vector3 dist;
117                int distance=0,inc2=0;
118            static int modo=0;
119                static int shadows=1;
120
121                float tiempo = evt.timeSinceLastFrame;
122                miButtonTimer -= tiempo;
123
124                if (shadows == 0)
125                {
126                        SceneMgrAux->setShadowTechnique(SHADOWTYPE_NONE);
127                }
128                else
129                {
130                        SceneMgrAux->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
131                }
132
133
134                // Move upto 80 units/second
135                Real MoveFactor = 180.0 * evt.timeSinceLastFrame;
136
137                // Copy the current state of the input devices
138                mInputDevice->capture();
139
140                // If this is the first frame, pick a speed
141                if (evt.timeSinceLastFrame == 0)
142                {
143                        mMoveScale = 1;
144                        mRotScale = 0.1;
145                }
146                // Otherwise scale movement units by time passed since last frame
147                else
148                {
149                        // Move about 100 units per second,
150                        mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
151                        // Take about 10 seconds for full rotation
152                        mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
153                }
154
155                mRotX = 0;
156        mRotY = 0;
157            mTranslateVector = Vector3::ZERO;
158
159                //LOD selection
160                static float lodfactor=0;
161                static float lodfactorBefore = -1.0f;
162               
163                dist = node->getPosition() - mCamera->getPosition();
164                distance =dist.length();
165
166                if ( modo == 0 )      //Automatic LOD
167                {
168                        int difdist = dist_max - dist_min;
169       
170                        int i=0;
171
172                        lodfactor = (float)(distance - dist_min) / (float)(dist_max - dist_min);
173                        lodfactor = 1.0f - lodfactor;
174                }
175                else
176                {
177          //  lodfactor = lodfactorBefore;
178                }
179
180                       
181        if (( mInputDevice->isKeyDown(Ogre::KC_ADD) ) && (modo == 1))
182                                lodfactor += 0.001f;
183            if (( mInputDevice->isKeyDown(Ogre::KC_SUBTRACT) ) && (modo == 1))
184                                lodfactor -= 0.001f;
185
186                if (lodfactor<0.0f)
187                        lodfactor=0.0f;
188                if (lodfactor>1.0f)
189                        lodfactor=1.0f;
190
191                if (fabsf(lodfactorBefore-lodfactor)>0.03f ||
192                        (lodfactorBefore>0.0f && lodfactor==0.0f) ||
193                        (lodfactorBefore<1.0f && lodfactor==1.0f))
194                {
195                        myStrips->GoToLod(lodfactor);
196                        lodfactorBefore=lodfactor;
197                }
198
199                if ( mInputDevice->isKeyDown(Ogre::KC_F3) && ( miButtonTimer <= 0 ) )
200                {
201                            miButtonTimer = 0.5;
202                               
203                                if (modo == 0)
204                                {
205                                        modo=1;
206                                        mLOD->setCaption(LODStringManu);
207                                }
208                                else
209                                {
210                                        modo=0;
211                                        mLOD->setCaption(LODStringAuto);
212                                }
213                }
214
215                if ( mInputDevice->isKeyDown(Ogre::KC_F2) && ( miButtonTimer <= 0 ) )
216                {
217                            miButtonTimer = 0.5;
218                               
219                                if (shadows == 0)
220                                {
221                                        shadows = 1;
222                                        mShad->setCaption(ShadON);
223                                }
224                                else
225                                {
226                                        shadows = 0;
227                                        mShad->setCaption(ShadOFF);
228                                }
229                }
230
231                // Move the node
232                if(mInputDevice->isKeyDown(Ogre::KC_UP) ||
233                   mInputDevice->isKeyDown(Ogre::KC_W) ||
234                   mInputDevice->isKeyDown(Ogre::KC_NUMPAD5))
235                  mTranslateVector.z = -mMoveScale;
236
237                if(mInputDevice->isKeyDown(Ogre::KC_DOWN) ||
238                   mInputDevice->isKeyDown(Ogre::KC_S) ||
239                   mInputDevice->isKeyDown(Ogre::KC_NUMPAD2))
240                  mTranslateVector.z = mMoveScale;
241
242                if (mInputDevice->isKeyDown(Ogre::KC_A) ||
243                        mInputDevice->isKeyDown(Ogre::KC_NUMPAD1))
244                        mTranslateVector.x = -mMoveScale;
245
246                if (mInputDevice->isKeyDown(Ogre::KC_D) ||
247                        mInputDevice->isKeyDown(Ogre::KC_NUMPAD3))
248                        mTranslateVector.x = mMoveScale;
249
250/*              if (mInputDevice->isKeyDown(Ogre::KC_K))
251                        mCamera->setDetailLevel(SDL_WIREFRAME);*/
252
253                static bool newpush = true;
254                if (!mInputDevice->isKeyDown(Ogre::KC_F1))
255                        newpush = true;
256
257                static bool showing_help = false;
258                if (mInputDevice->isKeyDown(Ogre::KC_F1) && newpush)
259                {
260                        newpush = false;
261                        if (showing_help = !showing_help)
262                mHelp->setCaption(HelpString);
263                        else
264                mHelp->setCaption(NoHelpString);
265                }
266
267                if(mInputDevice->isKeyDown(Ogre::KC_LEFT))
268                  mCamera->yaw(mRotScale);
269
270                if(mInputDevice->isKeyDown(Ogre::KC_RIGHT))
271                  mCamera->yaw(-mRotScale);
272
273                if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE))
274                {
275                        delete myStrips;
276                        delete [] mat;
277                    return false;
278                }
279
280        if( mInputDevice->getMouseButton( 1 ) )
281        {
282            mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
283            mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
284        }
285        else
286        {
287            mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
288            mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
289        }
290
291                SceneMgrAux->setShadowFarDistance(distance + 200);
292
293                char cadena[256];
294        const RenderTarget::FrameStats& stats = mWindow->getStatistics();
295                               
296                sprintf(cadena,"\nDistance: %d\nLOD factor: %f\nTriangle Count: %d\n"
297                                     ,    distance,      lodfactor,stats.triangleCount);
298                mInfo->setCaption(cadena);
299                sprintf(cadena,"Current FPS: %f\n",stats.lastFPS);
300                mInfo2->setCaption(cadena);
301
302                mCamera->yaw(mRotX);
303        mCamera->pitch(mRotY);
304        mCamera->moveRelative(mTranslateVector);
305
306                return true;
307    }
308
309};
310
311class LodStripsApplication : public ExampleApplication
312{
313protected:
314public:
315    LodStripsApplication() {}
316    ~LodStripsApplication() {}
317
318protected:
319
320    // Just override the mandatory create scene method
321    void createScene(void)
322    {
323                SceneMgrAux = mSceneMgr;
324        mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));
325                mSceneMgr->setShadowTechnique(SHADOWTYPE_TEXTURE_MODULATIVE);
326                mSceneMgr->setShadowTextureSettings(2048,1);
327                mSceneMgr->setShadowFarDistance(1024);
328                mSceneMgr->setShadowColour(ColourValue(0.5, 0.5, 0.5));
329
330                mat = new MaterialPtr[1];
331
332                theCam = mCamera;
333        theCam->setPosition(-35,50,dist_min-600.0f);
334        // Set ambient light
335
336        // Create a directional light
337        Light* l = mSceneMgr->createLight("MainLight");
338        l->setType(Light::LT_DIRECTIONAL);
339        l->setDirection(-0.5,-1.0,-1.0);
340                l->setCastShadows(true);
341
342        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
343
344        // My node to which all objects will be attached
345        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
346
347        // Define a floor plane mesh
348                Plane plane( Vector3::UNIT_Y, 0 );
349
350                MeshManager::getSingleton().createPlane("ground",
351                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
352                        20000,10000,6,6,true,1,250,250,Vector3::UNIT_Z);
353
354                Entity* groundEntity = mSceneMgr->createEntity( "GroundEntity", "ground" );
355                mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(groundEntity);
356               
357                groundEntity->setMaterialName("SnowTerrain");
358                groundEntity->setCastShadows(false);
359
360                std::string model_file=model_name;
361                model_file.append(".mesh");
362
363                //Models
364        entity = mSceneMgr->createEntity(model_name, "../../../OgreStuff/media/GT/ogrolod.mesh");
365                ogreMesh = entity->getMesh().getPointer();
366
367                // load LOD info from the object
368                meshloader=new Geometry::GeoMeshLoader;
369                Geometry::Mesh *themesh = meshloader->load("../../../OgreStuff/media/GT/ogrolod.mesh");
370
371        node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
372        node->attachObject( entity );
373                node->setVisible(false);               
374
375                std::string lod_file="../../media/GT/";
376                lod_file.append(model_name);
377                lod_file.append(".lod");
378
379                if (!meshloader->GetLodStripsData())
380            OGRE_EXCEPT(1, "The loaded mesh does not contain any LOD info","LOD Demo");
381
382                myStrips = new Geometry::LodStripsLibrary(      meshloader->GetLodStripsData(),
383                                                                                                        themesh,
384                                                                                                        new CustomIndexData(ogreMesh)   );
385               
386                entity->setNormaliseNormals(true);
387                entity->setMaterialName("LODStripsDemo/Ogro");
388
389
390                num_ogres=0;
391
392                for (int i=-4; i<4; i++) // 7
393                        for (int j=0; j<8; j++) // 4
394                        {
395                                char newObjName[16]="";
396                                sprintf(newObjName,"arbol_%d_%d",i,j);
397                                Ogre::SceneNode * auxnode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
398                                Ogre::Entity *auxen = entity->clone(newObjName);
399                                auxnode->attachObject(auxen);
400                                auxnode->rotate(Ogre::Vector3(0,1,0),Ogre::Degree(180.0f),Ogre::Node::TS_WORLD);
401                                auxnode->scale(30.0f,30.0f,30.0f);
402                                float randomsepx = (float)((rand()%18)-9);
403                                float randomsepy = (float)((rand()%12)-6);
404                                auxnode->translate(i*70.0f+randomsepx,-0.3f,-j*70.0f-randomsepx);
405                                auxen->setNormaliseNormals(true);
406                                auxen->setCastShadows(true);
407
408                                num_ogres++;
409                        }
410
411                node->translate(0,0,-500.0f);
412
413        // show overlay
414        Overlay* pOver = OverlayManager::getSingleton().getByName("Demo_LodStrips/Overlay");   
415        mInfo = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_1");
416                mInfo2 = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_2");
417                mHelp = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Help");
418                mLOD = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/ModoLOD");
419                mShad = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Shadows");
420                mHelp->setCaption(NoHelpString);
421                mLOD->setCaption(LODStringAuto);
422                mShad->setCaption(ShadON);
423                pOver->show();
424                //mWindow->getStatistics();
425
426    }
427
428    void createFrameListener(void)
429    {
430        mFrameListener= new FresnelFrameListener(mWindow, mCamera);
431        mFrameListener->showDebugOverlay(false);
432        mRoot->addFrameListener(mFrameListener);
433    }
434
435};
436
437
438
439#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
440#define WIN32_LEAN_AND_MEAN
441#include "windows.h"
442#endif
443
444#ifdef __cplusplus
445extern "C" {
446#endif
447
448#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
449INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
450#else
451int main(int argc, char **argv)
452#endif
453{
454    // Create application object
455    LodStripsApplication app;
456
457    try {
458        app.go();
459    } catch( Exception& e ) {
460#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
461        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
462#else
463        std::cerr << "An exception has occured: " << e.getFullDescription();
464#endif
465    }
466
467
468    return 0;
469}
470
471#ifdef __cplusplus
472}
473#endif
Note: See TracBrowser for help on using the repository browser.