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

Revision 1092, 14.7 KB checked in by gumbau, 18 years ago (diff)

LodStrips? and LODTrees 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 "OgreLodStripsLibrary.h"
16#include "GeoLodStripsLibrary.h"
17#include "GeoMeshLoader.h"
18
19
20// Distance values
21#define dist_min 300
22#define dist_max 700
23
24// Model name
25#define model_name "dwarf2"
26
27
28//Global variables
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;
41std::vector<Entity*> belowWaterEnts;
42std::vector<Entity*> aboveWaterEnts;
43
44Plane reflectionPlane;
45
46OverlayElement* mInfo;
47OverlayElement* mInfo2;
48
49class RefractionTextureListener : public RenderTargetListener
50{
51public:
52    void preRenderTargetUpdate(const RenderTargetEvent& evt)
53    {
54        // Hide plane and objects above the water
55        pPlaneEnt->setVisible(false);
56        std::vector<Entity*>::iterator i, iend;
57        iend = aboveWaterEnts.end();
58        for (i = aboveWaterEnts.begin(); i != iend; ++i)
59        {
60            (*i)->setVisible(false);
61        }
62
63    }
64    void postRenderTargetUpdate(const RenderTargetEvent& evt)
65    {
66        // Show plane and objects above the water
67        pPlaneEnt->setVisible(true);
68        std::vector<Entity*>::iterator i, iend;
69        iend = aboveWaterEnts.end();
70        for (i = aboveWaterEnts.begin(); i != iend; ++i)
71        {
72            (*i)->setVisible(true);
73        }
74    }
75
76};
77class ReflectionTextureListener : public RenderTargetListener
78{
79public:
80    void preRenderTargetUpdate(const RenderTargetEvent& evt)
81    {
82        // Hide plane and objects below the water
83        pPlaneEnt->setVisible(false);
84        std::vector<Entity*>::iterator i, iend;
85        iend = belowWaterEnts.end();
86        for (i = belowWaterEnts.begin(); i != iend; ++i)
87        {
88            (*i)->setVisible(false);
89        }
90        theCam->enableReflection(reflectionPlane);
91
92    }
93    void postRenderTargetUpdate(const RenderTargetEvent& evt)
94    {
95        // Show plane and objects below the water
96        pPlaneEnt->setVisible(true);
97        std::vector<Entity*>::iterator i, iend;
98        iend = belowWaterEnts.end();
99        for (i = belowWaterEnts.begin(); i != iend; ++i)
100        {
101            (*i)->setVisible(true);
102        }
103        theCam->disableReflection();
104    }
105
106};
107
108void DumpDataToOgreBuffers(Ogre::Mesh *original_mesh, Geometry::LodStripsLibrary *lodStripsLib)
109{
110        // Copy to Ogre buffers including the degenerated triangles
111
112        Ogre::HardwareIndexBufferSharedPtr      ibuf;
113        Ogre::IndexData *indexes;
114        Ogre::RenderOperation mRenderOp;
115
116        for (int submesh=0; submesh < original_mesh->getNumSubMeshes(); submesh++)
117        {
118                int indices_to_render = lodStripsLib->GetValidIndexCount(submesh);
119                int offset = lodStripsLib->GetValidOffset(submesh);
120
121                original_mesh->getSubMesh(submesh)->_getRenderOperation(mRenderOp,0);
122
123                ibuf = Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
124                        Ogre::HardwareIndexBuffer::IT_32BIT, // type of index
125                        indices_to_render, // number of indexes
126                        Ogre::HardwareBuffer::HBU_DISCARDABLE , // usage
127                        false); // no shadow buffer
128                                       
129                mRenderOp.indexData->indexBuffer = ibuf;
130                mRenderOp.indexData->indexStart = 0;//offset;
131                mRenderOp.indexData->indexCount = indices_to_render;
132
133                unsigned long* pIdx = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
134
135                for (int k=0; k<indices_to_render; k++)
136                        pIdx[k] = lodStripsLib->dataRetrievalInterface->GetIndex(k+offset);
137                       
138                ibuf->unlock();
139
140        }
141}
142
143class FresnelFrameListener : public ExampleFrameListener
144{
145        int manage;
146
147public:
148
149    FresnelFrameListener(RenderWindow* win, Camera* cam)
150        : ExampleFrameListener(win, cam, false, false)
151    {
152                manage=1;
153        }
154
155        bool frameStarted(const FrameEvent& evt)
156    {
157                Vector3 dist;
158                int distance=0,inc2=0,d;
159                unsigned int nlod,diflods;
160
161                // Move upto 80 units/second
162                Real MoveFactor = 180.0 * evt.timeSinceLastFrame;
163
164                // Copy the current state of the input devices
165                mInputDevice->capture();
166
167                // If this is the first frame, pick a speed
168                if (evt.timeSinceLastFrame == 0)
169                {
170                        mMoveScale = 1;
171                        mRotScale = 0.1;
172                }
173                // Otherwise scale movement units by time passed since last frame
174                else
175                {
176                        // Move about 100 units per second,
177                        mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
178                        // Take about 10 seconds for full rotation
179                        mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
180                }
181
182                mRotX = 0;
183        mRotY = 0;
184            mTranslateVector = Vector3::ZERO;
185
186                //LOD selection
187                int difdist = dist_max - dist_min;
188       
189                int i=0;
190
191                dist = node->getPosition() - mCamera->getPosition();
192                distance =dist.length();
193
194                DumpDataToOgreBuffers(ogreMesh,myStrips);
195
196                float lodfactor = (float)(distance - dist_min) / (float)(dist_max - dist_min);
197                lodfactor = 1.0f - lodfactor;
198
199                if (lodfactor >= 0.0f && lodfactor <= 1.0f)                     
200                {
201                        myStrips->GoToLod(lodfactor);
202
203/*                      diflods = 10.0f;//myStrips->MaxLod()-myStrips->MinLod();
204                        inc2=diflods/difdist;
205                        inc2++;
206
207                        d = distance - dist_min;
208
209                        nlod = d*inc2;*/
210
211//                      if ((nlod!=myStrips->mCurrentLod)&&(nlod>=myStrips->MinLod())&&(nlod<=myStrips->MaxLod()))
212//                      {
213                                if (lodfactor < 0.333f)
214                                {
215                                        color.r=0.0;
216                                        color.g=(lodfactor)*3.0f;//nlod*1.0/(diflods/3);
217                                        color.b=(1.0-lodfactor)*3.0f;//(nlod*1.0/(diflods/3));
218                                }
219                                else
220                                {
221                                        if (lodfactor<0.666f)
222                                        {
223                                                color.r=(lodfactor-0.333f)*3.0f;//(nlod-diflods/3)*1.0/(diflods/3);
224                                                color.g=1.0;
225                                                color.b=0.0;
226                                        }
227                                        else
228                                        {
229                                                color.r=1.0;
230                                                color.g=(1.0-lodfactor)*3.0f;//(nlod-(2*diflods/3))*1.0/(diflods/3);
231                                                color.b=0.0;
232                                        }
233                                }
234                                mat[0]->setDiffuse(color);
235                //      }
236                }
237                else
238                {
239                        if ((distance > dist_max))
240                        {
241                        //      myStrips->GoToLod(1.0f);
242
243                                color.r=0.0;
244                                color.g=0.0;
245                                color.b=1.0;
246                                mat[0]->setDiffuse(color);
247
248                        }
249                        else
250                        {
251                                if ((distance < dist_min))
252                                {
253                                //      myStrips->GoToLod(0.0f);
254
255                                        color.r=1.0;
256                                        color.g=0.0;
257                                        color.b=0.0;
258                                        mat[0]->setDiffuse(color);
259                                }
260                        }
261                }
262
263                // Move the node
264                if(mInputDevice->isKeyDown(Ogre::KC_UP))
265                  mTranslateVector.z = -mMoveScale;
266
267
268                if(mInputDevice->isKeyDown(Ogre::KC_DOWN))
269                  mTranslateVector.z = mMoveScale;
270
271                // Instead of moving the ship left and right, rotate it using yaw()
272                if(mInputDevice->isKeyDown(Ogre::KC_LEFT))
273                  mCamera->yaw(mRotScale);
274
275                if(mInputDevice->isKeyDown(Ogre::KC_RIGHT))
276                  mCamera->yaw(-mRotScale);
277
278                // Move the node
279                if(mInputDevice->isKeyDown(Ogre::KC_W))
280                  node->translate(0,mMoveScale,0);
281
282                if(mInputDevice->isKeyDown(Ogre::KC_S))
283                  node->translate(0,-mMoveScale,0);
284
285                if(mInputDevice->isKeyDown(Ogre::KC_Z))
286                  node->scale(1.01,1.01,1.01);
287
288                if(mInputDevice->isKeyDown(Ogre::KC_X))
289                  node->scale(0.99,0.99,0.99);
290
291                // Rotate
292                if(mInputDevice->isKeyDown(Ogre::KC_A))
293                  node->yaw(mRotScale);
294
295                if(mInputDevice->isKeyDown(Ogre::KC_D))
296                  node->yaw(-mRotScale);
297
298                if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE))
299                {
300                        delete myStrips;
301
302                        delete [] mat;
303
304                    return false;
305                }
306
307        if( mInputDevice->getMouseButton( 1 ) )
308        {
309            mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
310            mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
311        }
312        else
313        {
314            mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
315            mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
316        }
317
318
319                char cadena[256];
320
321                               
322                sprintf(cadena,"Distance: %d",distance);
323               
324                mInfo->setCaption(cadena);
325
326                if (lodfactor<0.0f)
327                        lodfactor=0.0f;
328                if (lodfactor>1.0f)
329                        lodfactor=1.0f;
330                sprintf(cadena,"LOD factor: %f",lodfactor);
331
332                mInfo2->setCaption(cadena);
333
334                mCamera->yaw(mRotX);
335        mCamera->pitch(mRotY);
336        mCamera->moveRelative(mTranslateVector);
337
338                return true;
339    }
340};
341
342class FresnelApplication : public ExampleApplication
343{
344protected:
345    RefractionTextureListener mRefractionListener;
346    ReflectionTextureListener mReflectionListener;
347public:
348    FresnelApplication() {
349   
350   
351    }
352
353    ~FresnelApplication()
354    {
355    }
356protected:
357   
358
359
360    // Just override the mandatory create scene method
361    void createScene(void)
362    {
363                Entity* pEnt;
364
365                mat = new MaterialPtr[1];
366               
367            // Check prerequisites first
368                const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
369        if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM)))
370        {
371            OGRE_EXCEPT(1, "Your card does not support vertex and fragment programs, so cannot "
372                "run this demo. Sorry!",
373                "Fresnel::createScene");
374        }
375        else
376        {
377            if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") &&
378                !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") &&
379                                !GpuProgramManager::getSingleton().isSyntaxSupported("ps_1_4")
380                                )
381            {
382                OGRE_EXCEPT(1, "Your card does not support advanced fragment programs, "
383                    "so cannot run this demo. Sorry!",
384                "Fresnel::createScene");
385            }
386        }
387
388        theCam = mCamera;
389        theCam->setPosition(0,20,dist_max+50);
390        // Set ambient light
391        mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3));
392
393        // Create a point light
394        Light* l = mSceneMgr->createLight("MainLight");
395        l->setType(Light::LT_DIRECTIONAL);
396        l->setDirection(0.0,0.0,-1.0);
397
398       
399        RenderTexture* rttTex = mRoot->getRenderSystem()->createRenderTexture( "Refraction", 512, 512 );
400               
401        {
402            Viewport *v = rttTex->addViewport( mCamera );
403            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
404            mat->getTechnique(0)->getPass(0)->getTextureUnitState(2)->setTextureName("Refraction");
405            v->setOverlaysEnabled(false);
406            rttTex->addListener(&mRefractionListener);
407        }
408       
409               
410        rttTex = mRoot->getRenderSystem()->createRenderTexture( "Reflection", 512, 512 );
411        {
412            Viewport *v = rttTex->addViewport( mCamera );
413            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
414            mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName("Reflection");
415            v->setOverlaysEnabled(false);
416            rttTex->addListener(&mReflectionListener);
417        }
418       
419       
420        // Define a floor plane mesh
421        reflectionPlane.normal = Vector3::UNIT_Y;
422        reflectionPlane.d = 0;
423        MeshManager::getSingleton().createPlane("ReflectPlane",
424            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
425            reflectionPlane,
426            9000,9000,10,10,true,1,5,5,Vector3::UNIT_Z);
427        pPlaneEnt = mSceneMgr->createEntity( "plane", "ReflectPlane" );
428        pPlaneEnt->setMaterialName("Examples/FresnelReflectionRefraction");
429        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);
430
431       
432        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
433
434        // My node to which all objects will be attached
435        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
436
437
438        // Now the below water ents
439        pEnt = mSceneMgr->createEntity( "PoolFloor", "PoolFloor.mesh" );
440        myRootNode->attachObject(pEnt);
441        belowWaterEnts.push_back(pEnt);
442                myRootNode->scale(6.0,6.0,6.0);
443
444                std::string model_file=model_name;
445                model_file.append(".mesh");
446
447                //Models
448        entity = mSceneMgr->createEntity(model_name, "../../../OgreStuff/media/GT/dwarflod.mesh");
449
450                ogreMesh = entity->getMesh().getPointer();
451
452                // load LOD info from the object
453                meshloader=new Geometry::GeoMeshLoader;
454                Geometry::Mesh *themesh = meshloader->load("../../../OgreStuff/media/GT/dwarflod.mesh");
455
456        node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
457        node->attachObject( entity );
458
459                std::string lod_file="../../media/GT/";
460                lod_file.append(model_name);
461                lod_file.append(".lod");
462
463//              myStrips = new LodStripsLibrary(lod_file,entity->getMesh().getPointer());
464
465                if (!meshloader->GetLodStripsData())
466                        exit(1);
467
468                myStrips = new Geometry::LodStripsLibrary(meshloader->GetLodStripsData(),themesh);
469
470                entity->setNormaliseNormals(true);
471
472                aboveWaterEnts.push_back(entity);
473
474                // Colour-coded material
475                mat[0] = MaterialManager::getSingleton().create("test_mat",
476                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
477                mat[0]->setCullingMode(CULL_ANTICLOCKWISE);
478                mat[0]->setAmbient(ColourValue::Black);
479                mat[0]->setDiffuse(color);
480                mat[0]->setLightingEnabled(true);
481                entity->setMaterialName("test_mat");
482
483        // show overlay
484        Overlay* pOver = OverlayManager::getSingleton().getByName("Demo_LodStrips/Overlay");   
485        mInfo = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_1");
486                mInfo2 = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_2");
487            pOver->show();
488
489    }
490
491    void createFrameListener(void)
492    {
493        mFrameListener= new FresnelFrameListener(mWindow, mCamera);
494        mFrameListener->showDebugOverlay(true);
495        mRoot->addFrameListener(mFrameListener);
496    }
497
498};
499
500
501
502#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
503#define WIN32_LEAN_AND_MEAN
504#include "windows.h"
505#endif
506
507#ifdef __cplusplus
508extern "C" {
509#endif
510
511#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
512INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
513#else
514int main(int argc, char **argv)
515#endif
516{
517    // Create application object
518    FresnelApplication app;
519
520    try {
521        app.go();
522    } catch( Exception& e ) {
523#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
524        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
525#else
526        std::cerr << "An exception has occured: " << e.getFullDescription();
527#endif
528    }
529
530
531    return 0;
532}
533
534#ifdef __cplusplus
535}
536#endif
Note: See TracBrowser for help on using the repository browser.