source: trunk/VUT/OcclusionCullingSceneManager/TestCullingTerrain/TestCullingTerrainApplication.cpp @ 51

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