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

Revision 1306, 14.3 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 "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 = mRenderOp.indexData->indexBuffer;
124                mRenderOp.indexData->indexStart = 0;
125                mRenderOp.indexData->indexCount = indices_to_render;
126
127                unsigned long* pIdx = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
128
129                for (int k=0; k<indices_to_render; k++)
130                        pIdx[k] = lodStripsLib->dataRetrievalInterface->GetIndex(k+offset);
131
132                ibuf->unlock();
133        }
134}
135
136class FresnelFrameListener : public ExampleFrameListener
137{
138        int manage;
139
140public:
141
142    FresnelFrameListener(RenderWindow* win, Camera* cam)
143        : ExampleFrameListener(win, cam, false, false)
144    {
145                manage=1;
146        }
147
148        bool frameStarted(const FrameEvent& evt)
149    {
150                Vector3 dist;
151                int distance=0,inc2=0,d;
152                unsigned int nlod,diflods;
153
154                // Move upto 80 units/second
155                Real MoveFactor = 180.0 * evt.timeSinceLastFrame;
156
157                // Copy the current state of the input devices
158                mInputDevice->capture();
159
160                // If this is the first frame, pick a speed
161                if (evt.timeSinceLastFrame == 0)
162                {
163                        mMoveScale = 1;
164                        mRotScale = 0.1;
165                }
166                // Otherwise scale movement units by time passed since last frame
167                else
168                {
169                        // Move about 100 units per second,
170                        mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
171                        // Take about 10 seconds for full rotation
172                        mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
173                }
174
175                mRotX = 0;
176        mRotY = 0;
177            mTranslateVector = Vector3::ZERO;
178
179                //LOD selection
180                int difdist = dist_max - dist_min;
181       
182                int i=0;
183
184                dist = node->getPosition() - mCamera->getPosition();
185                distance =dist.length();
186
187                float lodfactor = (float)(distance - dist_min) / (float)(dist_max - dist_min);
188                lodfactor = 1.0f - lodfactor;
189
190                if (lodfactor<0.0f)
191                        lodfactor=0.0f;
192                if (lodfactor>1.0f)
193                        lodfactor=1.0f;
194
195                static float lodfactorBefore = -1.0f;
196                if (fabsf(lodfactorBefore-lodfactor)>0.05f ||
197                        (lodfactorBefore>0.0f && lodfactor==0.0f) ||
198                        (lodfactorBefore<1.0f && lodfactor==1.0f))
199                {
200                        myStrips->GoToLod(lodfactor);
201                        DumpDataToOgreBuffers(ogreMesh,myStrips);
202                        lodfactorBefore=lodfactor;
203                }
204
205                // Move the node
206                if(mInputDevice->isKeyDown(Ogre::KC_UP))
207                  mTranslateVector.z = -mMoveScale;
208
209
210                if(mInputDevice->isKeyDown(Ogre::KC_DOWN))
211                  mTranslateVector.z = mMoveScale;
212
213                // Instead of moving the ship left and right, rotate it using yaw()
214                if(mInputDevice->isKeyDown(Ogre::KC_LEFT))
215                  mCamera->yaw(mRotScale);
216
217                if(mInputDevice->isKeyDown(Ogre::KC_RIGHT))
218                  mCamera->yaw(-mRotScale);
219
220                // Move the node
221                if(mInputDevice->isKeyDown(Ogre::KC_W))
222                  node->translate(0,mMoveScale,0);
223
224                if(mInputDevice->isKeyDown(Ogre::KC_S))
225                  node->translate(0,-mMoveScale,0);
226
227                if(mInputDevice->isKeyDown(Ogre::KC_Z))
228                  node->scale(1.01,1.01,1.01);
229
230                if(mInputDevice->isKeyDown(Ogre::KC_X))
231                  node->scale(0.99,0.99,0.99);
232
233                // Rotate
234                if(mInputDevice->isKeyDown(Ogre::KC_A))
235                  node->yaw(mRotScale);
236
237                if(mInputDevice->isKeyDown(Ogre::KC_D))
238                  node->yaw(-mRotScale);
239
240                if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE))
241                {
242                        delete myStrips;
243
244                        delete [] mat;
245
246                    return false;
247                }
248
249        if( mInputDevice->getMouseButton( 1 ) )
250        {
251            mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
252            mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
253        }
254        else
255        {
256            mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
257            mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
258        }
259
260
261                char cadena[256];
262
263                               
264                sprintf(cadena,"Distance: %d",distance);
265               
266                mInfo->setCaption(cadena);
267
268                sprintf(cadena,"LOD factor: %f",lodfactor);
269
270                mInfo2->setCaption(cadena);
271
272                mCamera->yaw(mRotX);
273        mCamera->pitch(mRotY);
274        mCamera->moveRelative(mTranslateVector);
275
276                return true;
277    }
278};
279
280class FresnelApplication : public ExampleApplication
281{
282protected:
283    RefractionTextureListener mRefractionListener;
284    ReflectionTextureListener mReflectionListener;
285public:
286    FresnelApplication() {
287   
288   
289    }
290
291    ~FresnelApplication()
292    {
293    }
294protected:
295   
296
297
298    // Just override the mandatory create scene method
299    void createScene(void)
300    {
301                Entity* pEnt;
302
303                mat = new MaterialPtr[1];
304               
305            // Check prerequisites first
306                const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities();
307        if (!caps->hasCapability(RSC_VERTEX_PROGRAM) || !(caps->hasCapability(RSC_FRAGMENT_PROGRAM)))
308        {
309            OGRE_EXCEPT(1, "Your card does not support vertex and fragment programs, so cannot "
310                "run this demo. Sorry!",
311                "Fresnel::createScene");
312        }
313        else
314        {
315            if (!GpuProgramManager::getSingleton().isSyntaxSupported("arbfp1") &&
316                !GpuProgramManager::getSingleton().isSyntaxSupported("ps_2_0") &&
317                                !GpuProgramManager::getSingleton().isSyntaxSupported("ps_1_4")
318                                )
319            {
320                OGRE_EXCEPT(1, "Your card does not support advanced fragment programs, "
321                    "so cannot run this demo. Sorry!",
322                "Fresnel::createScene");
323            }
324        }
325
326        theCam = mCamera;
327        theCam->setPosition(0,20,dist_min-600.0f);
328        // Set ambient light
329        mSceneMgr->setAmbientLight(ColourValue(0.3, 0.3, 0.3));
330
331        // Create a point light
332        Light* l = mSceneMgr->createLight("MainLight");
333        l->setType(Light::LT_DIRECTIONAL);
334        l->setDirection(0.0,0.0,-1.0);
335
336       
337        RenderTexture* rttTex = mRoot->getRenderSystem()->createRenderTexture( "Refraction", 512, 512 );
338               
339        {
340            Viewport *v = rttTex->addViewport( mCamera );
341            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
342            mat->getTechnique(0)->getPass(0)->getTextureUnitState(2)->setTextureName("Refraction");
343            v->setOverlaysEnabled(false);
344            rttTex->addListener(&mRefractionListener);
345        }
346       
347               
348        rttTex = mRoot->getRenderSystem()->createRenderTexture( "Reflection", 512, 512 );
349        {
350            Viewport *v = rttTex->addViewport( mCamera );
351            MaterialPtr mat = MaterialManager::getSingleton().getByName("Examples/FresnelReflectionRefraction");
352            mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName("Reflection");
353            v->setOverlaysEnabled(false);
354            rttTex->addListener(&mReflectionListener);
355        }
356       
357       
358        // Define a floor plane mesh
359        reflectionPlane.normal = Vector3::UNIT_Y;
360        reflectionPlane.d = 0;
361        MeshManager::getSingleton().createPlane("ReflectPlane",
362            ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
363            reflectionPlane,
364            9000,9000,10,10,true,1,5,5,Vector3::UNIT_Z);
365        pPlaneEnt = mSceneMgr->createEntity( "plane", "ReflectPlane" );
366        pPlaneEnt->setMaterialName("Examples/FresnelReflectionRefraction");
367        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(pPlaneEnt);
368
369       
370        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
371
372        // My node to which all objects will be attached
373        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
374
375
376        // Now the below water ents
377        pEnt = mSceneMgr->createEntity( "PoolFloor", "PoolFloor.mesh" );
378        myRootNode->attachObject(pEnt);
379        belowWaterEnts.push_back(pEnt);
380                myRootNode->scale(6.0,6.0,6.0);
381
382                std::string model_file=model_name;
383                model_file.append(".mesh");
384
385                //Models
386        entity = mSceneMgr->createEntity(model_name, "../../../OgreStuff/media/GT/ogrolod.mesh");
387
388                ogreMesh = entity->getMesh().getPointer();
389
390                // load LOD info from the object
391                meshloader=new Geometry::GeoMeshLoader;
392                Geometry::Mesh *themesh = meshloader->load("../../../OgreStuff/media/GT/ogrolod.mesh");
393
394        node = mSceneMgr->getRootSceneNode()->createChildSceneNode();
395        node->attachObject( entity );
396
397                std::string lod_file="../../media/GT/";
398                lod_file.append(model_name);
399                lod_file.append(".lod");
400
401                if (!meshloader->GetLodStripsData())
402            OGRE_EXCEPT(1, "The loaded mesh does not contain any LOD info","LOD Demo");
403
404                myStrips = new Geometry::LodStripsLibrary(meshloader->GetLodStripsData(),themesh);
405               
406                for (unsigned int i=0; i<ogreMesh->getNumSubMeshes(); i++)
407                {
408                        Ogre::RenderOperation mRenderOp;
409                        ogreMesh->getSubMesh(i)->_getRenderOperation(mRenderOp,0);
410                        int indices_to_render = myStrips->GetValidIndexCount(i);
411
412                        mRenderOp.indexData->indexBuffer =
413                                        Ogre::HardwareBufferManager::getSingleton().createIndexBuffer(
414                                                Ogre::HardwareIndexBuffer::IT_32BIT, // type of index
415                                                indices_to_render, // number of indexes
416                                                Ogre::HardwareBuffer::HBU_DISCARDABLE , // usage
417                                                false);
418                }
419
420                entity->setNormaliseNormals(true);
421                aboveWaterEnts.push_back(entity);
422                entity->setMaterialName("LODStripsDemo/Ogro");
423
424                for (int i=-3; i<7; i++)
425                        for (int j=0; j<4; j++)
426                        {
427                                char newObjName[16]="";
428                                sprintf(newObjName,"arbol_%d_%d",i,j);
429                                Ogre::SceneNode * auxnode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
430                                Ogre::Entity *auxen = entity->clone(newObjName);
431                                auxnode->attachObject(auxen);
432                                auxnode->rotate(Ogre::Vector3(0,1,0),Ogre::Degree(180.0f),Ogre::Node::TS_WORLD);
433                                auxnode->scale(30.0f,30.0f,30.0f);
434                                float randomsepx = (float)((rand()%18)-9);
435                                float randomsepy = (float)((rand()%12)-6);
436                                auxnode->translate(i*70.0f+randomsepx,-1.0f,-j*70.0f-randomsepx);
437                                auxen->setNormaliseNormals(true);
438                        }
439
440                node->translate(0,0,-500.0f);
441
442        // show overlay
443        Overlay* pOver = OverlayManager::getSingleton().getByName("Demo_LodStrips/Overlay");   
444        mInfo = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_1");
445                mInfo2 = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_2");
446            pOver->show();
447
448    }
449
450    void createFrameListener(void)
451    {
452        mFrameListener= new FresnelFrameListener(mWindow, mCamera);
453        mFrameListener->showDebugOverlay(true);
454        mRoot->addFrameListener(mFrameListener);
455    }
456
457};
458
459
460
461#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
462#define WIN32_LEAN_AND_MEAN
463#include "windows.h"
464#endif
465
466#ifdef __cplusplus
467extern "C" {
468#endif
469
470#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
471INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
472#else
473int main(int argc, char **argv)
474#endif
475{
476    // Create application object
477    FresnelApplication app;
478
479    try {
480        app.go();
481    } catch( Exception& e ) {
482#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
483        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
484#else
485        std::cerr << "An exception has occured: " << e.getFullDescription();
486#endif
487    }
488
489
490    return 0;
491}
492
493#ifdef __cplusplus
494}
495#endif
Note: See TracBrowser for help on using the repository browser.