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

Revision 1029, 12.8 KB checked in by gumbau, 18 years ago (diff)

LodStrips? Ogre demo initial import

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