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

Revision 1104, 9.8 KB checked in by gumbau, 18 years ago (diff)

Improved LODStrips and LODTree demos

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