source: trunk/VUT/work/TestCullingTerrain/TestCullingTerrainApplication.cpp @ 87

Revision 87, 15.0 KB checked in by mattausch, 20 years ago (diff)
RevLine 
[61]1/**
2    \file
3        TestCullingTerrainApplication.cpp
4    \brief
[74]5        Tests the visibility culling algorithm
[61]6*/
7
8#include <OgreNoMemoryMacros.h>
9#include <CEGUI/CEGUI.h>
10#include <../CEGUIRenderer/include/OgreCEGUIRenderer.h>
11#include <../CEGUIRenderer/include/OgreCEGUIResourceProvider.h>
12#include <../CEGUIRenderer/include/OgreCEGUITexture.h>
13#include <OgreMemoryMacros.h>
14
15#include "Ogre.h"
16#include "TestCullingTerrainApplication.h"
17
18#define WIN32_LEAN_AND_MEAN
19#include "windows.h"
20
21
[80]22/*******************************************************/
23/*     TestCullingTerrainApplication implementation    */
24/*******************************************************/
[61]25TestCullingTerrainApplication::~TestCullingTerrainApplication()
26{
[82]27        delete mTerrainContentGenerator;
[61]28}
29//-----------------------------------------------------------------------
30void TestCullingTerrainApplication::createCamera( void )
31{
32        // Create the camera
33        mCamera = mSceneMgr->createCamera("PlayerCam");
34
35        // Position it at 500 in Z direction
36        mCamera->setPosition(Vector3(128,25,128));
37
38        // Look back along -Z
39    mCamera->lookAt(Vector3(0,0,-300));
40    mCamera->setNearClipDistance(1);
41    mCamera->setFarClipDistance(1000);
42}
43//-----------------------------------------------------------------------
[75]44void TestCullingTerrainApplication::createScene()
[61]45{
46        // Set ambient light
47        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
48       
49        // Create a light
50        Light* l = mSceneMgr->createLight("MainLight");
51        // Accept default settings: point light, white diffuse, just set position
52        // NB I could attach the light to a SceneNode if I wanted it to move automatically with
53        //  other objects, but I don't
54        l->setPosition(20,80,50);
55
56        // --Fog
57        // NB it's VERY important to set this before calling setWorldGeometry
58        // because the vertex program picked will be different
59        ColourValue fadeColour(0.93, 0.86, 0.76);
60        mWindow->getViewport(0)->setBackgroundColour(fadeColour);
61        //mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
62
63        // Create a skybox
64    //mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 500, false);
65        //mSceneMgr->setSkyDome( true, "Examples/CloudySky", 5, 8, 500, false );
66
67        /*      // Define the required skyplane
68        Plane plane;
69        // 5000 world units from the camera
70        plane.d = 5000;
71        // Above the camera, facing down
72        plane.normal = -Vector3::UNIT_Y;
73        // Create the plane 10000 units wide, tile the texture 3 times
74    mSceneMgr->setSkyPlane(true, plane, "Examples/SpaceSkyPlane",10000,3);*/
75
76        std::string terrain_cfg("terrain.cfg");
77#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
78        terrain_cfg = mResourcePath + terrain_cfg;
79#endif
[74]80        mSceneMgr->setWorldGeometry(terrain_cfg);
[61]81        // Infinite far plane?
82        if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
83        {
84                mCamera->setFarClipDistance(0);
85        }
86
87        // Set a nice viewpoint
[85]88        mCamera->setPosition(707, 2500, 528);
[61]89        mCamera->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
[75]90       
[61]91        // CEGUI setup
92        setupGui();
[80]93        // HACK: necessary to call once before the content creation for
94        // terrain initialisation
95        mSceneMgr->_renderScene(mCamera, mWindow->getViewport(0), true);
[74]96
[82]97        mTerrainContentGenerator = new TerrainContentGenerator(mSceneMgr);
[87]98//      mTerrainContentGenerator->GenerateScene(500, "ninja.mesh");
99        mTerrainContentGenerator->GenerateScene(1000, "robot.mesh");
[86]100
[84]101        // no limitations needed anymore: the user can set
102        // objects also on peaks of terrain
[82]103        mTerrainContentGenerator->SetMaxHeight(5000);
[61]104}
105//-----------------------------------------------------------------------
[80]106void TestCullingTerrainApplication::setupGui()
[61]107{
[75]108         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY,
109                 false, 3000, ST_EXTERIOR_CLOSE);
[61]110     mGUISystem = new CEGUI::System(mGUIRenderer);
111
112         // Mouse
113     CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
114     CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
115         mGUISystem->setDefaultMouseCursor(
116                (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
117
[75]118         CEGUI::MouseCursor::getSingleton().show();
[61]119}
120//-----------------------------------------------------------------------
[80]121void TestCullingTerrainApplication::createFrameListener()
[61]122{
[80]123        mFrameListener= new MouseQueryListener(mWindow, mCamera, mSceneMgr,
[82]124                mGUIRenderer, mTerrainContentGenerator);
[61]125        mFrameListener->showDebugOverlay(true);
126        mRoot->addFrameListener(mFrameListener);
127}
128//-----------------------------------------------------------------------
[80]129void TestCullingTerrainApplication::chooseSceneManager()
[61]130{
131        mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
132}
133/***********************************************/
[80]134/*      MouseQueryListener implementation      */
[61]135/***********************************************/
136//-----------------------------------------------------------------------
[75]137MouseQueryListener::MouseQueryListener(RenderWindow* win, Camera* cam,
138                                                                           SceneManager *sceneManager,
[80]139                                                                           CEGUI::Renderer *renderer,
140                                                                           TerrainContentGenerator *sceneGenerator):
[86]141ExampleFrameListener(win, cam, false, true),
142mGUIRenderer(renderer),
143mShutdownRequested(false),
144mUseOptimization(false),
145mLMouseDown(false),
146mRMouseDown(false),
147mSceneMgr(sceneManager),
148mCurrentObject(NULL),
149mTerrainContentGenerator(sceneGenerator),
150mVisibilityThreshold(0),
[87]151mCurrentAlgorithm(GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING),
152mShowOctree(true),
153mUseCulling(false)
[61]154{
[86]155        // Reduce move speed
[61]156        mMoveSpeed = 50;
157        mRotateSpeed *= 2;
158   
159        // Register this so that we get mouse events.
160        mEventProcessor->addMouseListener(this);
161        mEventProcessor->addMouseMotionListener(this);
162        mEventProcessor->addKeyListener(this);
163
[74]164        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
[75]165       
[61]166        // show overlay
167        Overlay* pOver = OverlayManager::getSingleton().getByName("Example/VisibilityDemoOverlay");
168
[74]169        mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/AlgorithmInfo");
170        mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ThresholdInfo");
[84]171       
[74]172        mFrustumCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/FrustumCulledNodesInfo");
173        mQueryCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/QueryCulledNodesInfo");
174    mTraversedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/TraversedNodesInfo");
175        mHierarchyNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/HierarchyNodesInfo");
176        mRenderedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/RenderedNodesInfo");
[87]177        mObjectsInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/ObjectsInfo");
[86]178        mUseOptimizationInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/UseOptimizationInfo");
[87]179        mQueriesIssuedInfo = OverlayManager::getSingleton().getOverlayElement("Example/Visibility/QueriesIssuedInfo");
180       
[61]181        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
182        mThresholdInfo->setCaption(": 0");
183        mFrustumCulledNodesInfo->setCaption(": 0");
184        mQueryCulledNodesInfo->setCaption(": 0");
185        mTraversedNodesInfo->setCaption(": 0");
186        mHierarchyNodesInfo->setCaption(": 0");
187        mRenderedNodesInfo->setCaption(": 0");
[87]188        mObjectsInfo->setCaption(": 0");
[86]189        mUseOptimizationInfo->setCaption(": true");
[87]190        mQueriesIssuedInfo->setCaption(": 0");
[84]191
[85]192        setAlgorithm(mCurrentAlgorithm);
[86]193        toggleUseOptimization();
194        toggleShowOctree();
[87]195        toggleUseCulling();
[85]196
[61]197    pOver->show();
198}
199//-----------------------------------------------------------------------
200MouseQueryListener::~MouseQueryListener( )
201{
[74]202        delete mRayQueryExecutor;
[61]203}
204//-----------------------------------------------------------------------
205void MouseQueryListener::mouseMoved (MouseEvent *e)
206{
207        // Update CEGUI with the mouse motion
[75]208    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() * mGUIRenderer->getWidth(),
209                e->getRelY() * mGUIRenderer->getHeight());
[61]210}
211//-----------------------------------------------------------------------
212void MouseQueryListener::mousePressed(MouseEvent* e)
213{
214     // Left mouse button down
215     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
216     {
[76]217                 CEGUI::MouseCursor::getSingleton().hide();
[61]218
219                 // Setup the ray scene query
[80]220         Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
[74]221   
222                 Vector3 queryResult;
[80]223                 
224                 // Get results, create a node/entity on the position
[82]225                 mCurrentObject = mTerrainContentGenerator->GenerateSceneObject(
[80]226                         mouseRay.getOrigin(), mouseRay.getDirection(), "robot.mesh");
227               
[61]228         mLMouseDown = true;
229     }
230     // Right mouse button down
231     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
232     {
[75]233         CEGUI::MouseCursor::getSingleton().hide();
[61]234         mRMouseDown = true;
235     } // else if
236} // mousePressed
237
238 //-----------------------------------------------------------------------
239void MouseQueryListener::mouseReleased(MouseEvent* e)
240{
241    // Left mouse button up
242    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
243    {
[75]244                CEGUI::MouseCursor::getSingleton().show();
[61]245        mLMouseDown = false;
246    }
247    // Right mouse button up
248    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
249    {
[75]250        CEGUI::MouseCursor::getSingleton().show();
[61]251        mRMouseDown = false;
252    }
253}
254//-----------------------------------------------------------------------
[75]255void MouseQueryListener::mouseDragged(MouseEvent *e)
[61]256 {
257         // If we are dragging the left mouse button.           
[75]258         if (mLMouseDown)
[61]259     {
[74]260                 Vector3 queryResult;
261                 Ray mouseRay = mCamera->getCameraToViewportRay(e->getX(), e->getY());
[61]262
[74]263                 if(mRayQueryExecutor->executeRayQuery(&queryResult, mouseRay))
[61]264                 {
[80]265                         if(mCurrentObject)
266                                 mCurrentObject->setPosition(queryResult);
[74]267                 }
[61]268     }
269         // If we are dragging the right mouse button.
[75]270         if (mRMouseDown)
[61]271         {
272                 mCamera->yaw( -e->getRelX() * mRotateSpeed );
273                 mCamera->pitch( -e->getRelY() * mRotateSpeed );
274         }
275}
276//-----------------------------------------------------------------------
277bool MouseQueryListener::frameStarted(const FrameEvent &evt)
278{
279        // clamp to terrain
[74]280        Vector3 camPos = mCamera->getPosition();
281        Vector3 queryResult;
[61]282
[74]283    if(mRayQueryExecutor->executeRayQuery(&queryResult,
284                Vector3(camPos.x, 5000.0f, camPos.z), Vector3::NEGATIVE_UNIT_Y))
[61]285        {
[74]286                mCamera->setPosition(mCamera->getPosition().x, queryResult.y + 10,
[61]287                        mCamera->getPosition().z);
288        }
[75]289       
[61]290        return ExampleFrameListener::frameStarted(evt);
291}
292//-----------------------------------------------------------------------
293bool MouseQueryListener::frameEnded(const FrameEvent& evt)
294{
295        if (mShutdownRequested)
296                return false;
297
298    if (timeDelay >= 0)
299        timeDelay -= evt.timeSinceLastFrame;
300
[85]301    KEY_PRESSED(KC_SPACE, 0.3, nextAlgorithm());
[61]302
303        KEY_PRESSED(KC_SUBTRACT, 0, changeThreshold(-10));
304        KEY_PRESSED(KC_ADD, 0, changeThreshold(10));
[86]305        KEY_PRESSED(KC_O, 0.3, toggleUseOptimization());
306        KEY_PRESSED(KC_S, 0.3, toggleShowOctree());
[87]307        KEY_PRESSED(KC_C, 0.3, toggleUseCulling());
308             
309        updateStats();
[61]310
311    return ExampleFrameListener::frameStarted(evt) && ExampleFrameListener::frameEnded(evt);       
312}
313//-----------------------------------------------------------------------
314void MouseQueryListener::changeThreshold(int incr)
315{
[85]316        mVisibilityThreshold += incr;
317        if(mVisibilityThreshold < 0) mVisibilityThreshold = 0;
[61]318       
[85]319        char str[100]; sprintf(str,": %d", mVisibilityThreshold);
[61]320
[85]321        mSceneMgr->setOption("Threshold", &mVisibilityThreshold);
[61]322        mThresholdInfo->setCaption(str);
323}
324//-----------------------------------------------------------------------
[85]325void MouseQueryListener::nextAlgorithm()
[61]326{
[74]327        mCurrentAlgorithm = ++mCurrentAlgorithm %
328                GtpVisibility::VisibilityEnvironment::NUM_CULLING_MANAGERS,
[61]329
[85]330        setAlgorithm(mCurrentAlgorithm);
331}
332//-----------------------------------------------------------------------
333void MouseQueryListener::setAlgorithm(int algorithm)
334{
[61]335        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
336        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
337}
338//-----------------------------------------------------------------------
[87]339void MouseQueryListener::updateStats()
[61]340{
341        unsigned int opt = 0;
342        char str[100];
343       
344        mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
345        mFrustumCulledNodesInfo->setCaption(str);
346       
[87]347        mSceneMgr->getOption("NumQueriesIssued", &opt); sprintf(str,": %d", opt);
348        mQueriesIssuedInfo->setCaption(str);
349       
[61]350        mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
351        mQueryCulledNodesInfo->setCaption(str);
352       
353        mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt);
354        mTraversedNodesInfo->setCaption(str);
355
[74]356        mSceneMgr->getOption("NumHierarchyNodes", &opt); sprintf(str,": %d", opt);
[61]357        mHierarchyNodesInfo->setCaption(str);
358
359        mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt);
360        mRenderedNodesInfo->setCaption(str);
[84]361
362        sprintf(str,": %d", mTerrainContentGenerator->GetObjectCount());
[87]363        mObjectsInfo->setCaption(str);
[61]364}
365//-----------------------------------------------------------------------
[86]366void MouseQueryListener::toggleUseOptimization()
367{
368        mUseOptimization = !mUseOptimization;
369
370        mSceneMgr->setOption("UseOptimization", &mUseOptimization);
371
372        if(mUseOptimization)
373                mUseOptimizationInfo->setCaption(": true");
374        else
375                mUseOptimizationInfo->setCaption(": false");
376}
377//-----------------------------------------------------------------------
378void MouseQueryListener::toggleShowOctree()
379{
380        mShowOctree = !mShowOctree;
381
382        mSceneMgr->setOption("ShowOctree", &mShowOctree);
383}
384//-----------------------------------------------------------------------
[87]385void MouseQueryListener::toggleUseCulling()
386{
387        mUseCulling = !mUseCulling;
388
389        mSceneMgr->setOption("UseCulling", &mUseCulling);
390}
391//-----------------------------------------------------------------------
[61]392void MouseQueryListener::keyPressed(KeyEvent* e)
393{
394        if(e->getKey() == KC_ESCAPE)
395    {
396                mShutdownRequested = true;
397                e->consume();
398                return;
399        }
400
401        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
402        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
403        e->consume();
404}
405//-----------------------------------------------------------------------
406void MouseQueryListener::keyReleased(KeyEvent* e)
407{
408        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
409        e->consume();
410}
411//-----------------------------------------------------------------------
412void MouseQueryListener::keyClicked(KeyEvent* e)
413{
414        // Do nothing
415        e->consume();
416}
417//-----------------------------------------------------------------------
418INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
419{
420    // Create application object
421    TestCullingTerrainApplication app;
422
423        try
424        {
425        app.go();
426    }
427        catch( Ogre::Exception& e )
428        {
[75]429        MessageBox( NULL, e.getFullDescription().c_str(),
430                        "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
[61]431    }   
432
433    return 0;
434}
Note: See TracBrowser for help on using the repository browser.