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

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