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

Revision 1529, 13.9 KB checked in by gumbau, 18 years ago (diff)

Demos upgraded to the new programming interface

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