source: trunk/VUT/OcclusionCullingSceneManager/TestCulling/TestCullingApplication.cpp @ 44

Revision 44, 14.5 KB checked in by mattausch, 19 years ago (diff)

implementation for terrain + octree scenemanager

Line 
1/**
2    \file
3        TestCullingApplication.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 "TestCullingApplication.h"
17#include "OgreOcclusionCullingSceneTraverser.h"
18
19#define WIN32_LEAN_AND_MEAN
20#include "windows.h"
21
22//RaySceneQuery* mRaySceneQuery = 0;
23
24/***********************************************/
25/* TestCullingApplication implementation       */
26/***********************************************/
27/*TestCullingApplication::~TestCullingApplication()
28{
29        delete mRaySceneQuery;
30}*/
31//-----------------------------------------------------------------------
32void TestCullingApplication::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 TestCullingApplication::createScene(void)
47{
48        Plane waterPlane;
49        // Set ambient light
50        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
51       
52        // Create a light
53        Light* l = mSceneMgr->createLight("MainLight");
54        // Accept default settings: point light, white diffuse, just set position
55        // NB I could attach the light to a SceneNode if I wanted it to move automatically with
56        //  other objects, but I don't
57        l->setPosition(20,80,50);
58
59        // --Fog
60        // NB it's VERY important to set this before calling setWorldGeometry
61        // because the vertex program picked will be different
62        ColourValue fadeColour(0.93, 0.86, 0.76);
63        //mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
64    //mSceneMgr->setFog( FOG_EXP, fadeColour, 0.005 );
65
66        mWindow->getViewport(0)->setBackgroundColour(fadeColour);
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        std::string terrain_cfg("terrain.cfg");
73#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
74        terrain_cfg = mResourcePath + terrain_cfg;
75#endif
76        mSceneMgr -> setWorldGeometry( terrain_cfg );
77        // Infinite far plane?
78        if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
79        {
80                mCamera->setFarClipDistance(0);
81        }
82
83/*      // Define the required skyplane
84        Plane plane;
85        // 5000 world units from the camera
86        plane.d = 5000;
87        // Above the camera, facing down
88        plane.normal = -Vector3::UNIT_Y;
89        // Create the plane 10000 units wide, tile the texture 3 times
90    mSceneMgr->setSkyPlane(true, plane, "Examples/SpaceSkyPlane",10000,3);*/
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        //mRaySceneQuery = mSceneMgr->createRayQuery(
97        //      Ray(mCamera->getPosition(), Vector3::NEGATIVE_UNIT_Y));
98
99        /*Entity *robotEnt = mSceneMgr->createEntity( "Robot", "robot.mesh" );
100        SceneNode *robotNode = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode", Vector3( 750, 25, 600 ));
101        robotNode->attachObject( robotEnt );
102        robotNode->scale( .3, .3, .3 );
103        robotNode->yaw( Degree( 160 ) );
104
105        Entity *ogreEnt = mSceneMgr->createEntity( "Ogre", "ogrehead.mesh" );
106    SceneNode *ogreNode = mSceneMgr->getRootSceneNode()->createChildSceneNode( "Ogre", Vector3( 800, 50, 830 ) );
107    ogreNode->attachObject( ogreEnt );
108        ogreNode->scale(.2,.2,.2);
109        ogreNode->yaw( Degree( 20 ) );
110
111        Entity *ogreEnt2 = mSceneMgr->createEntity( "Ogre2", "ogrehead.mesh" );
112    SceneNode *ogreNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "Ogre2", Vector3( 700, 50, 730 ) );
113    ogreNode2->attachObject( ogreEnt2 );
114        ogreNode2->scale(.05,.05,.05);
115        ogreNode->yaw( Degree( 40 ) );*/
116
117        // CEGUI setup
118        setupGui();
119}
120//-----------------------------------------------------------------------
121void TestCullingApplication::setupGui( void )
122{
123         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, ST_EXTERIOR_CLOSE);
124     mGUISystem = new CEGUI::System(mGUIRenderer);
125
126         // Mouse
127     CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
128     CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
129         mGUISystem->setDefaultMouseCursor(
130                (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
131
132         CEGUI::MouseCursor::getSingleton().show( );
133}
134//-----------------------------------------------------------------------
135void TestCullingApplication::createFrameListener(void)
136{
137        mFrameListener= new MouseQueryListener(mWindow, mCamera, mSceneMgr, mGUIRenderer);
138        mFrameListener->showDebugOverlay(true);
139        mRoot->addFrameListener(mFrameListener);
140}
141//-----------------------------------------------------------------------
142void TestCullingApplication::chooseSceneManager(void)
143{
144    //mSceneMgr = mRoot->getSceneManager(ST_GENERIC);
145        mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
146}
147
148/***********************************************/
149/* MouseQueryListener implementation           */
150/***********************************************/
151//-----------------------------------------------------------------------
152MouseQueryListener::MouseQueryListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager, CEGUI::Renderer *renderer)
153        : ExampleFrameListener(win, cam, false, true), mGUIRenderer(renderer),
154                mShutdownRequested(false)
155{
156
157        // Setup default variables
158        mCurrentObject = NULL;
159        mLMouseDown = false;
160        mRMouseDown = false;
161        mSceneMgr = sceneManager;
162
163    // Reduce move speed
164        mMoveSpeed = 50;
165        mRotateSpeed *= 2;
166
167        mCurrentAlgorithm = OcclusionCullingSceneTraverser::RENDER_COHERENT;
168        mThreshold = 0;
169   
170        // Register this so that we get mouse events.
171        mEventProcessor->addMouseListener(this);
172        mEventProcessor->addMouseMotionListener(this);
173        mEventProcessor->addKeyListener(this);
174
175        mRaySceneQuery = mSceneMgr->createRayQuery( Ray() );
176
177        // show overlay
178        Overlay* pOver = OverlayManager::getSingleton().getByName("Example/OcclusionCullingDemoOverlay");
179
180        mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/AlgorithmInfo");
181        mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/ThresholdInfo");
182        mFrustumCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/FrustumCulledNodesInfo");
183        mQueryCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/QueryCulledNodesInfo");
184    mTraversedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/TraversedNodesInfo");
185        mSceneNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/SceneNodesInfo");
186        mHierarchyNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/HierarchyNodesInfo");
187
188        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
189        mThresholdInfo->setCaption(": 0");
190        mFrustumCulledNodesInfo->setCaption(": 0");
191        mQueryCulledNodesInfo->setCaption(": 0");
192        mTraversedNodesInfo->setCaption(": 0");
193        mSceneNodesInfo->setCaption(": 0");
194        mHierarchyNodesInfo->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//-----------------------------------------------------------------------
368void MouseQueryListener::keyPressed(KeyEvent* e)
369{
370        if(e->getKey() == KC_ESCAPE)
371    {
372                mShutdownRequested = true;
373                e->consume();
374                return;
375        }
376
377        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
378        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
379        e->consume();
380}
381//-----------------------------------------------------------------------
382void MouseQueryListener::keyReleased(KeyEvent* e)
383{
384        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
385        e->consume();
386}
387//-----------------------------------------------------------------------
388void MouseQueryListener::keyClicked(KeyEvent* e)
389{
390        // Do nothing
391        e->consume();
392}
393//-----------------------------------------------------------------------
394INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
395{
396    // Create application object
397    TestCullingApplication app;
398
399        try
400        {
401        app.go();
402    }
403        catch( Ogre::Exception& e )
404        {
405        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
406    }   
407
408    return 0;
409}
Note: See TracBrowser for help on using the repository browser.