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

Revision 1561, 11.0 KB checked in by gumbau, 18 years ago (diff)

Added F1 key functionality

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