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

Revision 42, 13.3 KB checked in by mattausch, 20 years ago (diff)
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
22RaySceneQuery* raySceneQuery = 0;
23
24/***********************************************/
25/* TestCullingApplication implementation       */
26/***********************************************/
27TestCullingApplication::~TestCullingApplication()
28{
29        delete raySceneQuery;
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        raySceneQuery = 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        /* CEGUI::Window* sheet =
135            CEGUI::WindowManager::getSingleton().loadWindowLayout(
136                (CEGUI::utf8*)"ogregui.layout");
137
138     mGUISystem->setGUISheet(sheet);*/
139}
140//-----------------------------------------------------------------------
141void TestCullingApplication::createFrameListener(void)
142{
143        mFrameListener= new MouseQueryListener(mWindow, mCamera, mSceneMgr, mGUIRenderer);
144        mFrameListener->showDebugOverlay(true);
145        mRoot->addFrameListener(mFrameListener);
146}
147//-----------------------------------------------------------------------
148void TestCullingApplication::chooseSceneManager(void)
149{
150    //mSceneMgr = mRoot->getSceneManager(ST_GENERIC);
151        mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
152}
153
154/***********************************************/
155/* MouseQueryListener implementation           */
156/***********************************************/
157
158//-----------------------------------------------------------------------
159MouseQueryListener::MouseQueryListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager, CEGUI::Renderer *renderer)
160        : ExampleFrameListener(win, cam, false, true), mGUIRenderer(renderer),
161                mShutdownRequested(false)
162{
163
164        // Setup default variables
165//      mCurrentObject = NULL;
166        mLMouseDown = false;
167        mRMouseDown = false;
168        mSceneMgr = sceneManager;
169
170    // Reduce move speed
171        mMoveSpeed = 50;
172        mRotateSpeed *= 2;
173
174        mCurrentAlgorithm = OcclusionCullingSceneTraverser::RENDER_COHERENT;
175        mThreshold = 0;
176   
177        // Register this so that we get mouse events.
178        mEventProcessor->addMouseListener(this);
179        mEventProcessor->addMouseMotionListener(this);
180        mEventProcessor->addKeyListener(this);
181
182        // show overlay
183        Overlay* pOver = OverlayManager::getSingleton().getByName("Example/OcclusionCullingDemoOverlay");
184
185        mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/AlgorithmInfo");
186        mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/ThresholdInfo");
187        mFrustumCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/FrustumCulledNodesInfo");
188        mQueryCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/QueryCulledNodesInfo");
189    mTraversedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/TraversedNodesInfo");
190        mSceneNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/SceneNodesInfo");
191        mHierarchyNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/HierarchyNodesInfo");
192
193        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
194        mThresholdInfo->setCaption(": 0");
195        mFrustumCulledNodesInfo->setCaption(": 0");
196        mQueryCulledNodesInfo->setCaption(": 0");
197        mTraversedNodesInfo->setCaption(": 0");
198        mSceneNodesInfo->setCaption(": 0");
199        mHierarchyNodesInfo->setCaption(": 0");
200
201    pOver->show();
202} // MouseQueryListener
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                 mLMouseDown = true;
217     } // if
218     // Right mouse button down
219     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
220     {
221         CEGUI::MouseCursor::getSingleton().hide( );
222         mRMouseDown = true;
223     } // else if
224} // mousePressed
225
226 //-----------------------------------------------------------------------
227void MouseQueryListener::mouseReleased(MouseEvent* e)
228{
229    // Left mouse button up
230    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
231    {
232                CEGUI::MouseCursor::getSingleton().show( );
233        mLMouseDown = false;
234    }
235    // Right mouse button up
236    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
237    {
238        CEGUI::MouseCursor::getSingleton().show( );
239        mRMouseDown = false;
240    }
241}
242//-----------------------------------------------------------------------
243void MouseQueryListener::mouseDragged (MouseEvent *e)
244 {
245         /*
246         // If we are dragging the left mouse button.   
247         if ( mLMouseDown )
248         {
249                mShipNode->translate(-e->getRelX() * 200, -e->getRelY() * 200, 0.0);
250     }
251         */
252         
253         // If we are dragging the right mouse button.
254         if ( mRMouseDown )
255         {
256                 mCamera->yaw( -e->getRelX() * mRotateSpeed );
257                 mCamera->pitch( -e->getRelY() * mRotateSpeed );
258         }
259}
260//-----------------------------------------------------------------------
261bool MouseQueryListener::frameStarted(const FrameEvent &evt)
262{
263        // clamp to terrain
264        static Ray updateRay;
265        updateRay.setOrigin(mCamera->getPosition());
266        updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
267        raySceneQuery->setRay(updateRay);
268        RaySceneQueryResult& qryResult = raySceneQuery->execute();
269        RaySceneQueryResult::iterator i = qryResult.begin();
270         
271        if (i != qryResult.end() && i->worldFragment)
272        {
273                SceneQuery::WorldFragment* wf = i->worldFragment;
274                mCamera->setPosition(mCamera->getPosition().x,
275                        i->worldFragment->singleIntersection.y + 10,
276                        mCamera->getPosition().z);
277        }
278         
279        return ExampleFrameListener::frameStarted(evt);
280}
281//-----------------------------------------------------------------------
282bool MouseQueryListener::frameEnded(const FrameEvent& evt)
283{
284        if (mShutdownRequested)
285                return false;
286
287    if (timeDelay >= 0)
288        timeDelay -= evt.timeSinceLastFrame;
289
290    KEY_PRESSED(KC_SPACE, 0.3, changeAlgorithm());
291
292        KEY_PRESSED(KC_SUBTRACT, 0.3, changeThreshold(-10));
293        KEY_PRESSED(KC_ADD, 0, changeThreshold(10));
294        //KEY_PRESSED(KC_T, 1, change);
295     
296        changeStats();
297
298    return ExampleFrameListener::frameStarted(evt) && ExampleFrameListener::frameEnded(evt);       
299}
300//-----------------------------------------------------------------------
301void MouseQueryListener::changeThreshold(int incr)
302{
303        mThreshold += incr; if(mThreshold < 0) mThreshold = 0;
304       
305        char str[100]; sprintf(str,": %d", mThreshold);
306
307        mSceneMgr->setOption("Threshold", &mThreshold);
308        mThresholdInfo->setCaption(str);
309}
310//-----------------------------------------------------------------------
311void MouseQueryListener::changeAlgorithm()
312{
313    mCurrentAlgorithm = ++mCurrentAlgorithm % OcclusionCullingSceneTraverser::NUM_RENDERMODES;
314
315        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
316        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
317}
318//-----------------------------------------------------------------------
319void MouseQueryListener::changeStats()
320{
321        unsigned int opt = 0;
322        char str[100];
323       
324        mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
325        mFrustumCulledNodesInfo->setCaption(str);
326       
327        mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
328        mQueryCulledNodesInfo->setCaption(str);
329       
330        mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt);
331        mTraversedNodesInfo->setCaption(str);
332
333        mSceneMgr->getOption("NumSceneNodes", &opt); sprintf(str,": %d", opt);
334        mSceneNodesInfo->setCaption(str);
335
336        mSceneMgr->getOption("NumOctreeNodes", &opt); sprintf(str,": %d", opt);
337        mHierarchyNodesInfo->setCaption(str);
338}
339//-----------------------------------------------------------------------
340void MouseQueryListener::keyPressed(KeyEvent* e)
341{
342        if(e->getKey() == KC_ESCAPE)
343    {
344                mShutdownRequested = true;
345                e->consume();
346                return;
347        }
348
349        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
350        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
351        e->consume();
352}
353//-----------------------------------------------------------------------
354void MouseQueryListener::keyReleased(KeyEvent* e)
355{
356        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
357        e->consume();
358}
359//-----------------------------------------------------------------------
360void MouseQueryListener::keyClicked(KeyEvent* e)
361{
362        // Do nothing
363        e->consume();
364}
365//-----------------------------------------------------------------------
366INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
367{
368    // Create application object
369    TestCullingApplication app;
370
371        try
372        {
373        app.go();
374    }
375        catch( Ogre::Exception& e )
376        {
377        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
378    }   
379
380    return 0;
381}
Note: See TracBrowser for help on using the repository browser.