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

Revision 52, 14.7 KB checked in by mattausch, 20 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        mRenderedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/RenderedNodesInfo");
186
187        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
188        mThresholdInfo->setCaption(": 0");
189        mFrustumCulledNodesInfo->setCaption(": 0");
190        mQueryCulledNodesInfo->setCaption(": 0");
191        mTraversedNodesInfo->setCaption(": 0");
192        mSceneNodesInfo->setCaption(": 0");
193        mHierarchyNodesInfo->setCaption(": 0");
194        mRenderedNodesInfo->setCaption(": 0");
195               
196    pOver->show();
197}
198//-----------------------------------------------------------------------
199MouseQueryListener::~MouseQueryListener( )
200{
201        delete mRaySceneQuery;
202}
203//-----------------------------------------------------------------------
204void MouseQueryListener::mouseMoved (MouseEvent *e)
205{
206        // Update CEGUI with the mouse motion
207    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() * mGUIRenderer->getWidth(), e->getRelY() * mGUIRenderer->getHeight());
208}
209//-----------------------------------------------------------------------
210void MouseQueryListener::mousePressed(MouseEvent* e)
211{
212     // Left mouse button down
213     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
214     {
215                 CEGUI::MouseCursor::getSingleton().hide( );
216
217                 // Setup the ray scene query
218         Ray mouseRay = mCamera->getCameraToViewportRay( e->getX(), e->getY() );
219         mRaySceneQuery->setRay( mouseRay );
220
221         // Execute query
222         RaySceneQueryResult &result = mRaySceneQuery->execute();
223         RaySceneQueryResult::iterator itr = result.begin( );
224
225         // Get results, create a node/entity on the position
226         if ( itr != result.end() && itr->worldFragment )
227         {
228                         char name[16];
229             sprintf( name, "Robot%d", mCount++ );
230
231             Entity *ent = mSceneMgr->createEntity( name, "robot.mesh" );
232             mCurrentObject = mSceneMgr->getRootSceneNode( )->createChildSceneNode( String(name) + "Node", itr->worldFragment->singleIntersection );
233             mCurrentObject->attachObject( ent );
234             mCurrentObject->setScale( 0.1f, 0.1f, 0.1f );
235         }
236
237         mLMouseDown = true;
238     }
239     // Right mouse button down
240     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
241     {
242         CEGUI::MouseCursor::getSingleton().hide( );
243         mRMouseDown = true;
244     } // else if
245} // mousePressed
246
247 //-----------------------------------------------------------------------
248void MouseQueryListener::mouseReleased(MouseEvent* e)
249{
250    // Left mouse button up
251    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
252    {
253                CEGUI::MouseCursor::getSingleton().show( );
254        mLMouseDown = false;
255    }
256    // Right mouse button up
257    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
258    {
259        CEGUI::MouseCursor::getSingleton().show( );
260        mRMouseDown = false;
261    }
262}
263//-----------------------------------------------------------------------
264void MouseQueryListener::mouseDragged (MouseEvent *e)
265 {
266         // If we are dragging the left mouse button.           
267         if ( mLMouseDown )
268     {
269                 Ray mouseRay = mCamera->getCameraToViewportRay( e->getX(), e->getY() );
270                 mRaySceneQuery->setRay( mouseRay );
271
272                 RaySceneQueryResult &result = mRaySceneQuery->execute();
273                 RaySceneQueryResult::iterator itr = result.begin( );
274
275                 if ( itr != result.end() && itr->worldFragment )
276                 {
277                         mCurrentObject->setPosition( itr->worldFragment->singleIntersection );
278                 }
279     }
280         // If we are dragging the right mouse button.
281         if ( mRMouseDown )
282         {
283                 mCamera->yaw( -e->getRelX() * mRotateSpeed );
284                 mCamera->pitch( -e->getRelY() * mRotateSpeed );
285         }
286}
287//-----------------------------------------------------------------------
288bool MouseQueryListener::frameStarted(const FrameEvent &evt)
289{
290        // clamp to terrain
291        Vector3 camPos = mCamera->getPosition( );
292    Ray cameraRay( Vector3(camPos.x, 5000.0f, camPos.z), Vector3::NEGATIVE_UNIT_Y );
293    mRaySceneQuery->setRay( cameraRay );
294
295    // Perform the scene query
296    RaySceneQueryResult &queryResult = mRaySceneQuery->execute();
297    RaySceneQueryResult::iterator it = queryResult.begin( );
298
299        if (it != queryResult.end() && it->worldFragment)
300        {
301                SceneQuery::WorldFragment* wf = it->worldFragment;
302
303                mCamera->setPosition(mCamera->getPosition().x, wf->singleIntersection.y + 10,
304                        mCamera->getPosition().z);
305        }
306         
307        return ExampleFrameListener::frameStarted(evt);
308}
309//-----------------------------------------------------------------------
310bool MouseQueryListener::frameEnded(const FrameEvent& evt)
311{
312        if (mShutdownRequested)
313                return false;
314
315    if (timeDelay >= 0)
316        timeDelay -= evt.timeSinceLastFrame;
317
318    KEY_PRESSED(KC_SPACE, 0.3, changeAlgorithm());
319
320        KEY_PRESSED(KC_SUBTRACT, 0, changeThreshold(-10));
321        KEY_PRESSED(KC_ADD, 0, changeThreshold(10));
322        //KEY_PRESSED(KC_T, 1, change);
323     
324        changeStats();
325
326    return ExampleFrameListener::frameStarted(evt) && ExampleFrameListener::frameEnded(evt);       
327}
328//-----------------------------------------------------------------------
329void MouseQueryListener::changeThreshold(int incr)
330{
331        mThreshold += incr; if(mThreshold < 0) mThreshold = 0;
332       
333        char str[100]; sprintf(str,": %d", mThreshold);
334
335        mSceneMgr->setOption("Threshold", &mThreshold);
336        mThresholdInfo->setCaption(str);
337}
338//-----------------------------------------------------------------------
339void MouseQueryListener::changeAlgorithm()
340{
341    mCurrentAlgorithm = ++mCurrentAlgorithm % OcclusionCullingSceneTraverser::NUM_RENDERMODES;
342
343        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
344        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
345}
346//-----------------------------------------------------------------------
347void MouseQueryListener::changeStats()
348{
349        unsigned int opt = 0;
350        char str[100];
351       
352        mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
353        mFrustumCulledNodesInfo->setCaption(str);
354       
355        mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
356        mQueryCulledNodesInfo->setCaption(str);
357       
358        mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt);
359        mTraversedNodesInfo->setCaption(str);
360
361        mSceneMgr->getOption("NumSceneNodes", &opt); sprintf(str,": %d", opt);
362        mSceneNodesInfo->setCaption(str);
363
364        mSceneMgr->getOption("NumOctreeNodes", &opt); sprintf(str,": %d", opt);
365        mHierarchyNodesInfo->setCaption(str);
366
367        mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt);
368        mRenderedNodesInfo->setCaption(str);
369}
370//-----------------------------------------------------------------------
371void MouseQueryListener::keyPressed(KeyEvent* e)
372{
373        if(e->getKey() == KC_ESCAPE)
374    {
375                mShutdownRequested = true;
376                e->consume();
377                return;
378        }
379
380        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
381        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
382        e->consume();
383}
384//-----------------------------------------------------------------------
385void MouseQueryListener::keyReleased(KeyEvent* e)
386{
387        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
388        e->consume();
389}
390//-----------------------------------------------------------------------
391void MouseQueryListener::keyClicked(KeyEvent* e)
392{
393        // Do nothing
394        e->consume();
395}
396//-----------------------------------------------------------------------
397INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
398{
399    // Create application object
400    TestCullingTerrainApplication app;
401
402        try
403        {
404        app.go();
405    }
406        catch( Ogre::Exception& e )
407        {
408        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
409    }   
410
411    return 0;
412}
Note: See TracBrowser for help on using the repository browser.