source: GTP/trunk/App/Demos/Geom/Demo_LodTrees/main.cpp @ 1306

Revision 1306, 10.5 KB checked in by gumbau, 18 years ago (diff)

Demo efficiency improved (indexbuffers)

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 "GeoLodTreeLibrary.h"
16#include "GeoMeshLoader.h"
17
18
19// Distance values
20#define dist_min 300
21#define dist_max 700
22
23// Model name
24#define model_name "arbol"
25
26
27//Global variables
28Entity* entity;
29Geometry::LodTreeLibrary* myTrees;
30Ogre::Mesh *ogreMesh=NULL;
31Geometry::GeoMeshLoader *meshloader=NULL;
32bool force_maxLODfactor = false;
33
34Ogre::Vector3 forest_center;
35
36ColourValue color=ColourValue::Red;
37
38Camera* theCam;
39Entity* pPlaneEnt;
40
41OverlayElement* mInfo;
42OverlayElement* mInfo2;
43
44
45void DumpDataToOgreBuffers(Ogre::Mesh *original_mesh, Geometry::LodTreeLibrary *lodTreesLib)
46{
47        // Copy to Ogre buffers including the degenerated triangles
48
49        Ogre::HardwareIndexBufferSharedPtr      ibuf;
50        Ogre::IndexData *indexes;
51        Ogre::RenderOperation mRenderOp;
52
53        for (int submesh=0; submesh < original_mesh->getNumSubMeshes(); submesh++)
54        {
55                bool istrunk = lodTreesLib->GetLeavesSubMesh()!=submesh;
56                original_mesh->getSubMesh(submesh)->_getRenderOperation(mRenderOp,0);
57
58                // we will suppose this submesh is the foliage
59                int indices_to_render = lodTreesLib->CurrentLOD_Foliage_IndexCount();           
60                int offset = 0;
61
62                if (istrunk)
63                {
64                        // this submesh is the trunk
65                        offset = lodTreesLib->GetValidTrunkOffset(submesh);
66                        indices_to_render = lodTreesLib->GetValidTrunkIndexCount(submesh);
67                }
68
69                ibuf = mRenderOp.indexData->indexBuffer;
70                mRenderOp.indexData->indexStart = 0;
71                mRenderOp.indexData->indexCount = indices_to_render;           
72
73                unsigned long* pIdx = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
74
75                for (int k=0; k<indices_to_render; k++)
76                        if (istrunk)
77                                pIdx[k] = lodTreesLib->CurrentLOD_Trunk_Indices()->GetIndex(k+offset);
78                        else
79                                pIdx[k] = lodTreesLib->CurrentLOD_Foliage_Indices()->GetIndex(k);
80
81                       
82                ibuf->unlock();
83        }
84}
85
86class FresnelFrameListener : public ExampleFrameListener
87{
88        int manage;
89
90public:
91
92    FresnelFrameListener(RenderWindow* win, Camera* cam)
93        : ExampleFrameListener(win, cam, false, false)
94    {
95                manage=1;
96        }
97
98        bool frameStarted(const FrameEvent& evt)
99    {
100                Vector3 dist;
101                int distance=0,inc2=0,d;
102                unsigned int nlod,diflods;
103
104                // Move upto 80 units/second
105                Real MoveFactor = 180.0 * evt.timeSinceLastFrame;
106
107                // Copy the current state of the input devices
108                mInputDevice->capture();
109
110                // If this is the first frame, pick a speed
111                if (evt.timeSinceLastFrame == 0)
112                {
113                        mMoveScale = 1;
114                        mRotScale = 0.1;
115                }
116                // Otherwise scale movement units by time passed since last frame
117                else
118                {
119                        // Move about 100 units per second,
120                        mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
121                        // Take about 10 seconds for full rotation
122                        mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
123                }
124
125                mRotX = 0;
126        mRotY = 0;
127            mTranslateVector = Vector3::ZERO;
128
129                //LOD selection
130                int difdist = dist_max - dist_min;
131       
132                int i=0;
133
134                dist = forest_center - mCamera->getPosition();
135                distance =dist.length();
136
137                float lodfactor = (float)(distance - dist_min) / (float)(dist_max - dist_min);
138                lodfactor = 1.0f - lodfactor;
139
140                if (lodfactor<0.0f)
141                        lodfactor=0.0f;
142                if (lodfactor>1.0f)
143                        lodfactor=1.0f;
144
145                if (force_maxLODfactor)
146                        lodfactor=1.0f;
147
148                static float lodfactorBefore = -1.0f;
149                if (fabsf(lodfactorBefore-lodfactor)>0.05f)
150                {
151                        myTrees->GoToLod(lodfactor);
152                        DumpDataToOgreBuffers(ogreMesh,myTrees);
153                        lodfactorBefore=lodfactor;
154                }
155
156                // Move the node
157                if(mInputDevice->isKeyDown(Ogre::KC_UP))
158                  mTranslateVector.z = -mMoveScale;
159
160
161                if(mInputDevice->isKeyDown(Ogre::KC_DOWN))
162                  mTranslateVector.z = mMoveScale;
163
164                // Instead of moving the ship left and right, rotate it using yaw()
165                if(mInputDevice->isKeyDown(Ogre::KC_LEFT))
166                  mCamera->yaw(mRotScale);
167
168                force_maxLODfactor=mInputDevice->isKeyDown(Ogre::KC_F2);                 
169
170                if(mInputDevice->isKeyDown(Ogre::KC_RIGHT))
171                  mCamera->yaw(-mRotScale);
172
173                if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE))
174                {
175                        //delete myTrees;
176                    return false;
177                }
178
179        if( mInputDevice->getMouseButton( 1 ) )
180        {
181            mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
182            mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
183        }
184        else
185        {
186            mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
187            mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
188        }
189
190
191                char cadena[256];
192
193                               
194                sprintf(cadena,"Distance: %d",distance);
195               
196                mInfo->setCaption(cadena);
197
198                sprintf(cadena,"LOD factor: %f",lodfactor);
199
200                mInfo2->setCaption(cadena);
201
202                mCamera->yaw(mRotX);
203        mCamera->pitch(mRotY);
204        mCamera->moveRelative(mTranslateVector);
205
206                return true;
207    }
208};
209
210class FresnelApplication : public ExampleApplication
211{
212protected:
213public:
214    FresnelApplication()
215        {
216        }
217
218    ~FresnelApplication()
219    {
220    }
221protected:
222   
223
224
225    // Just override the mandatory create scene method
226    void createScene(void)
227    {
228//              mat = new MaterialPtr[1];
229               
230        theCam = mCamera;
231                theCam->setPosition(0,20,dist_min-40);
232        // Set ambient light
233        mSceneMgr->setAmbientLight(ColourValue(0.4, 0.4, 0.4));
234
235        // Create a directional light
236                Light* l = mSceneMgr->createLight("MainLight");
237                l->setType(Light::LT_DIRECTIONAL);
238        l->setDirection(0.0,-1.0,0.0);
239       
240        // Define a floor plane mesh
241                Plane plane( Vector3::UNIT_Y, 0 );
242
243                MeshManager::getSingleton().createPlane("ground",
244                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
245                        1500,1500,20,20,true,1,5,5,Vector3::UNIT_Z);
246
247                Entity* suelo = mSceneMgr->createEntity( "GroundEntity", "ground" );
248                mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(suelo);
249               
250
251                suelo->setMaterialName("Examples/GrassFloor");
252                suelo->setCastShadows(false);       
253
254       
255        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
256
257        // My node to which all objects will be attached
258        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
259
260                std::string model_file=model_name;
261                model_file.append(".mesh");
262
263                //Models
264        entity = mSceneMgr->createEntity(model_name, "../../../OgreStuff/media/GT/ML12m.mesh");
265
266                ogreMesh = entity->getMesh().getPointer();
267
268                // load LOD info from the object
269                meshloader=new Geometry::GeoMeshLoader;
270                Geometry::Mesh *themesh = meshloader->load("../../../OgreStuff/media/GT/ML12m.mesh");
271
272                if (!meshloader->GetLodStripsData())
273            OGRE_EXCEPT(1, "The loaded mesh does not contain LOD info for the trunk","LOD Demo");
274                if (!meshloader->GetTreeSimpSeq())
275            OGRE_EXCEPT(1, "The loaded mesh does not contain LOD info for the foliage","LOD Demo");
276
277                myTrees = new Geometry::LodTreeLibrary(meshloader->GetLodStripsData(),meshloader->GetTreeSimpSeq(),themesh);
278
279                entity->setNormaliseNormals(true);
280
281                for (int submesh=0; submesh < ogreMesh->getNumSubMeshes(); submesh++)
282                {
283                        bool istrunk = myTrees->GetLeavesSubMesh()!=submesh;
284                        int indices_to_render = 0;
285                        if (istrunk)
286                        {
287                                entity->getSubEntity(submesh)->setMaterialName("Examples/Populifolia/trunk");
288                                indices_to_render = myTrees->GetValidTrunkIndexCount(submesh);
289                        }
290                        else
291                        {
292                                entity->getSubEntity(submesh)->setMaterialName("Examples/Populifolia/leaf");
293                                indices_to_render = myTrees->CurrentLOD_Foliage_IndexCount();
294                        }
295
296                        Ogre::RenderOperation mRenderOp;
297                        ogreMesh->getSubMesh(submesh)->_getRenderOperation(mRenderOp,0);
298
299                        mRenderOp.indexData->indexBuffer = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
300                                Ogre::HardwareIndexBuffer::IT_32BIT, // type of index
301                                indices_to_render, // number of indexes
302                                Ogre::HardwareBuffer::HBU_DISCARDABLE , // usage
303                                false); // no shadow buffer
304                }
305
306                forest_center=Ogre::Vector3(150.0f,0.0f,0.0f);
307                for (int i=1; i<8; i++) // 20
308                        for (int j=1; j<8; j++) // 20
309                        {
310                                char newTreeName[16]="";
311                                sprintf(newTreeName,"arbol_%d_%d",i,j);
312                                Ogre::SceneNode * auxnode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
313                                Ogre::Entity *auxent = entity->clone(newTreeName);
314                                auxnode->attachObject( auxent );
315                                auxnode->scale(4.0f,4.0f,4.0f);
316                                auxnode->rotate(Ogre::Vector3(0,0,1),Ogre::Degree(rand()%360));
317                                auxnode->rotate(Ogre::Vector3(1,0,0),Ogre::Radian(-3.14159f*0.5f),Ogre::Node::TS_WORLD);
318                                float randomsepx = (float)((rand()%18)-9);
319                                float randomsepy = (float)((rand()%12)-6);
320                                auxnode->translate(i*30.0f+randomsepx,0.0f,-j*30.0f-randomsepx);
321                                auxent->setNormaliseNormals(true);
322                        }
323
324                if (!meshloader->GetLodStripsData() || !meshloader->GetTreeSimpSeq())
325            OGRE_EXCEPT(1, "The loaded mesh does not contain any LOD info","LOD Demo");
326
327
328        // show overlay
329        Overlay* pOver = OverlayManager::getSingleton().getByName("Demo_LodStrips/Overlay");   
330        mInfo = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_1");
331                mInfo2 = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_2");
332            pOver->show();
333
334    }
335
336    void createFrameListener(void)
337    {
338        mFrameListener= new FresnelFrameListener(mWindow, mCamera);
339        mFrameListener->showDebugOverlay(true);
340        mRoot->addFrameListener(mFrameListener);
341    }
342
343};
344
345
346
347#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
348#define WIN32_LEAN_AND_MEAN
349#include "windows.h"
350#endif
351
352#ifdef __cplusplus
353extern "C" {
354#endif
355
356#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
357INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
358#else
359int main(int argc, char **argv)
360#endif
361{
362    // Create application object
363    FresnelApplication app;
364
365    try {
366        app.go();
367    } catch( Exception& e ) {
368#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
369        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
370#else
371        std::cerr << "An exception has occured: " << e.getFullDescription();
372#endif
373    }
374
375
376    return 0;
377}
378
379#ifdef __cplusplus
380}
381#endif
Note: See TracBrowser for help on using the repository browser.