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

Revision 1114, 15.2 KB checked in by gumbau, 18 years ago (diff)
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 1200
22#define dist_max 2000
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                float lodfactor = (float)(distance - dist_min) / (float)(dist_max - dist_min);
195                lodfactor = 1.0f - lodfactor;
196
197                if (lodfactor<0.0f)
198                        lodfactor=0.0f;
199                if (lodfactor>1.0f)
200                        lodfactor=1.0f;
201
202/*              if (lodfactor >= 0.0f && lodfactor <= 1.0f)                     
203                {*/
204                static float lodfactorBefore = -1.0f;
205                if (fabsf(lodfactorBefore-lodfactor)>0.05f ||
206                        (lodfactorBefore>0.0f && lodfactor==0.0f) ||
207                        (lodfactorBefore<1.0f && lodfactor==1.0f))
208                {
209                        myStrips->GoToLod(lodfactor);
210                        DumpDataToOgreBuffers(ogreMesh,myStrips);
211                        lodfactorBefore=lodfactor;
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=(0.3f-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=(0.3f-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/*              else
237                {
238                        if ((distance > dist_max))
239                        {
240                                color.r=0.0;
241                                color.g=0.0;
242                                color.b=1.0;
243                                mat[0]->setDiffuse(color);
244
245                        }
246                        else
247                        {
248                                if ((distance < dist_min))
249                                {
250                                        color.r=1.0;
251                                        color.g=0.0;
252                                        color.b=0.0;
253                                        mat[0]->setDiffuse(color);
254                                }
255                        }
256                }
257*/
258                // Move the node
259                if(mInputDevice->isKeyDown(Ogre::KC_UP))
260                  mTranslateVector.z = -mMoveScale;
261
262
263                if(mInputDevice->isKeyDown(Ogre::KC_DOWN))
264                  mTranslateVector.z = mMoveScale;
265
266                // Instead of moving the ship left and right, rotate it using yaw()
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                // Move the node
274                if(mInputDevice->isKeyDown(Ogre::KC_W))
275                  node->translate(0,mMoveScale,0);
276
277                if(mInputDevice->isKeyDown(Ogre::KC_S))
278                  node->translate(0,-mMoveScale,0);
279
280                if(mInputDevice->isKeyDown(Ogre::KC_Z))
281                  node->scale(1.01,1.01,1.01);
282
283                if(mInputDevice->isKeyDown(Ogre::KC_X))
284                  node->scale(0.99,0.99,0.99);
285
286                // Rotate
287                if(mInputDevice->isKeyDown(Ogre::KC_A))
288                  node->yaw(mRotScale);
289
290                if(mInputDevice->isKeyDown(Ogre::KC_D))
291                  node->yaw(-mRotScale);
292
293                if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE))
294                {
295                        delete myStrips;
296
297                        delete [] mat;
298
299                    return false;
300                }
301
302        if( mInputDevice->getMouseButton( 1 ) )
303        {
304            mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
305            mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
306        }
307        else
308        {
309            mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
310            mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
311        }
312
313
314                char cadena[256];
315
316                               
317                sprintf(cadena,"Distance: %d",distance);
318               
319                mInfo->setCaption(cadena);
320
321                sprintf(cadena,"LOD factor: %f",lodfactor);
322
323                mInfo2->setCaption(cadena);
324
325                mCamera->yaw(mRotX);
326        mCamera->pitch(mRotY);
327        mCamera->moveRelative(mTranslateVector);
328
329                return true;
330    }
331};
332
333class FresnelApplication : public ExampleApplication
334{
335protected:
336    RefractionTextureListener mRefractionListener;
337    ReflectionTextureListener mReflectionListener;
338public:
339    FresnelApplication() {
340   
341   
342    }
343
344    ~FresnelApplication()
345    {
346    }
347protected:
348   
349
350
351    // Just override the mandatory create scene method
352    void createScene(void)
353    {
354                Entity* pEnt;
355
356                mat = new MaterialPtr[1];
357               
358            // Check prerequisites first
359                const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
360        if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM)))
361        {
362            OGRE_EXCEPT(1, "Your card does not support vertex and fragment programs, so cannot "
363                "run this demo. Sorry!",
364                "Fresnel::createScene");
365        }
366        else
367        {
368            if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") &&
369                !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") &&
370                                !GpuProgramManager::getSingleton().isSyntaxSupported("ps_1_4")
371                                )
372            {
373                OGRE_EXCEPT(1, "Your card does not support advanced fragment programs, "
374                    "so cannot run this demo. Sorry!",
375                "Fresnel::createScene");
376            }
377        }
378
379        theCam = mCamera;
380        theCam->setPosition(0,20,dist_min-600.0f);
381        // Set ambient light
382        mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3));
383
384        // Create a point light
385        Light* l = mSceneMgr->createLight("MainLight");
386        l->setType(Light::LT_DIRECTIONAL);
387        l->setDirection(0.0,0.0,-1.0);
388
389       
390        RenderTexture* rttTex = mRoot->getRenderSystem()->createRenderTexture( "Refraction", 512, 512 );
391               
392        {
393            Viewport *v = rttTex->addViewport( mCamera );
394            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
395            mat->getTechnique(0)->getPass(0)->getTextureUnitState(2)->setTextureName("Refraction");
396            v->setOverlaysEnabled(false);
397            rttTex->addListener(&mRefractionListener);
398        }
399       
400               
401        rttTex = mRoot->getRenderSystem()->createRenderTexture( "Reflection", 512, 512 );
402        {
403            Viewport *v = rttTex->addViewport( mCamera );
404            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
405            mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName("Reflection");
406            v->setOverlaysEnabled(false);
407            rttTex->addListener(&mReflectionListener);
408        }
409       
410       
411        // Define a floor plane mesh
412        reflectionPlane.normal = Vector3::UNIT_Y;
413        reflectionPlane.d = 0;
414        MeshManager::getSingleton().createPlane("ReflectPlane",
415            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
416            reflectionPlane,
417            9000,9000,10,10,true,1,5,5,Vector3::UNIT_Z);
418        pPlaneEnt = mSceneMgr->createEntity( "plane", "ReflectPlane" );
419        pPlaneEnt->setMaterialName("Examples/FresnelReflectionRefraction");
420        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);
421
422       
423        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
424
425        // My node to which all objects will be attached
426        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
427
428
429        // Now the below water ents
430        pEnt = mSceneMgr->createEntity( "PoolFloor", "PoolFloor.mesh" );
431        myRootNode->attachObject(pEnt);
432        belowWaterEnts.push_back(pEnt);
433                myRootNode->scale(6.0,6.0,6.0);
434
435                std::string model_file=model_name;
436                model_file.append(".mesh");
437
438                //Models
439        entity = mSceneMgr->createEntity(model_name, "../../../OgreStuff/media/GT/bunnylod.mesh");
440
441                ogreMesh = entity->getMesh().getPointer();
442
443                // load LOD info from the object
444                meshloader=new Geometry::GeoMeshLoader;
445                Geometry::Mesh *themesh = meshloader->load("../../../OgreStuff/media/GT/bunnylod.mesh");
446
447        node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
448        node->attachObject( entity );
449
450                std::string lod_file="../../media/GT/";
451                lod_file.append(model_name);
452                lod_file.append(".lod");
453
454//              myStrips = new LodStripsLibrary(lod_file,entity->getMesh().getPointer());
455
456                if (!meshloader->GetLodStripsData())
457            OGRE_EXCEPT(1, "The loaded mesh does not contain any LOD info","LOD Demo");
458
459                myStrips = new Geometry::LodStripsLibrary(meshloader->GetLodStripsData(),themesh);
460
461                entity->setNormaliseNormals(true);
462
463                aboveWaterEnts.push_back(entity);
464
465                // Colour-coded material
466                mat[0] = MaterialManager::getSingleton().create("test_mat",
467                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
468                mat[0]->setCullingMode(CULL_ANTICLOCKWISE);
469                mat[0]->setAmbient(ColourValue(0.3f,0.3f,0.3f));
470                mat[0]->setDiffuse(color);
471                mat[0]->setLightingEnabled(true);
472                entity->setMaterialName("test_mat");
473
474
475                for (int i=-3; i<2; i++) // 20
476                        for (int j=0; j<5; j++) // 20
477                        {
478                                char newObjName[16]="";
479                                sprintf(newObjName,"arbol_%d_%d",i,j);
480                                Ogre::SceneNode * auxnode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
481                                auxnode->attachObject( entity->clone(newObjName) );
482                                auxnode->scale(0.8f,0.8f,0.8f);
483                                float randomsepx = (float)((rand()%18)-9);
484                                float randomsepy = (float)((rand()%12)-6);
485                                auxnode->translate(i*100.0f+randomsepx,40.0f,-j*100.0f-randomsepx);
486                        }
487
488                node->translate(0,0,-500.0f);
489
490        // show overlay
491        Overlay* pOver = OverlayManager::getSingleton().getByName("Demo_LodStrips/Overlay");   
492        mInfo = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_1");
493                mInfo2 = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_2");
494            pOver->show();
495
496    }
497
498    void createFrameListener(void)
499    {
500        mFrameListener= new FresnelFrameListener(mWindow, mCamera);
501        mFrameListener->showDebugOverlay(true);
502        mRoot->addFrameListener(mFrameListener);
503    }
504
505};
506
507
508
509#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
510#define WIN32_LEAN_AND_MEAN
511#include "windows.h"
512#endif
513
514#ifdef __cplusplus
515extern "C" {
516#endif
517
518#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
519INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
520#else
521int main(int argc, char **argv)
522#endif
523{
524    // Create application object
525    FresnelApplication app;
526
527    try {
528        app.go();
529    } catch( Exception& e ) {
530#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
531        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
532#else
533        std::cerr << "An exception has occured: " << e.getFullDescription();
534#endif
535    }
536
537
538    return 0;
539}
540
541#ifdef __cplusplus
542}
543#endif
Note: See TracBrowser for help on using the repository browser.