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

Revision 41, 12.8 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        mWindow->getViewport(0)->setBackgroundColour(fadeColour);
66
67         // Create a skybox
68     //mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 500, false);
69         //mSceneMgr->setSkyDome( true, "Examples/CloudySky", 5, 8, 500, false );
70
71        std::string terrain_cfg("terrain.cfg");
72#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
73        terrain_cfg = mResourcePath + terrain_cfg;
74#endif
75        mSceneMgr -> setWorldGeometry( terrain_cfg );
76        // Infinite far plane?
77/*      if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
78        {
79                mCamera->setFarClipDistance(0);
80        }*/
81
82/*      // Define the required skyplane
83        Plane plane;
84        // 5000 world units from the camera
85        plane.d = 5000;
86        // Above the camera, facing down
87        plane.normal = -Vector3::UNIT_Y;
88        // Create the plane 10000 units wide, tile the texture 3 times
89    mSceneMgr->setSkyPlane(true, plane, "Examples/SpaceSkyPlane",10000,3);*/
90
91        // Set a nice viewpoint
92        mCamera->setPosition(707,2500,528);
93        mCamera->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
94
95        raySceneQuery = mSceneMgr->createRayQuery(
96        Ray(mCamera->getPosition(), Vector3::NEGATIVE_UNIT_Y));
97
98        Entity *robotEnt = mSceneMgr->createEntity( "Robot", "robot.mesh" );
99        SceneNode *robotNode = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode", Vector3( 750, 25, 600 ));
100        robotNode->attachObject( robotEnt );
101        robotNode->scale( .3, .3, .3 );
102        robotNode->yaw( Degree( 160 ) );
103
104        Entity *ogreEnt = mSceneMgr->createEntity( "Ogre", "ogrehead.mesh" );
105    SceneNode *ogreNode = mSceneMgr->getRootSceneNode()->createChildSceneNode( "Ogre", Vector3( 800, 50, 830 ) );
106    ogreNode->attachObject( ogreEnt );
107        ogreNode->scale(.2,.2,.2);
108        ogreNode->yaw( Degree( 20 ) );
109
110        Entity *ogreEnt2 = mSceneMgr->createEntity( "Ogre2", "ogrehead.mesh" );
111    SceneNode *ogreNode2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "Ogre2", Vector3( 700, 50, 730 ) );
112    ogreNode2->attachObject( ogreEnt2 );
113        ogreNode2->scale(.05,.05,.05);
114        ogreNode->yaw( Degree( 40 ) );
115
116        // CEGUI setup
117        setupGui();
118}
119//-----------------------------------------------------------------------
120void TestCullingApplication::setupGui( void )
121{
122         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, ST_EXTERIOR_CLOSE);
123     mGUISystem = new CEGUI::System(mGUIRenderer);
124
125         // Mouse
126     CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
127     CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
128         mGUISystem->setDefaultMouseCursor(
129                (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
130
131         CEGUI::MouseCursor::getSingleton().show( );
132     
133        /* CEGUI::Window* sheet =
134            CEGUI::WindowManager::getSingleton().loadWindowLayout(
135                (CEGUI::utf8*)"ogregui.layout");
136
137     mGUISystem->setGUISheet(sheet);*/
138}
139//-----------------------------------------------------------------------
140void TestCullingApplication::createFrameListener(void)
141{
142        mFrameListener= new MouseQueryListener(mWindow, mCamera, mSceneMgr, mGUIRenderer);
143        mFrameListener->showDebugOverlay(true);
144        mRoot->addFrameListener(mFrameListener);
145}
146//-----------------------------------------------------------------------
147void TestCullingApplication::chooseSceneManager(void)
148{
149    //mSceneMgr = mRoot->getSceneManager(ST_GENERIC);
150        mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
151}
152
153/***********************************************/
154/* MouseQueryListener implementation           */
155/***********************************************/
156
157//-----------------------------------------------------------------------
158MouseQueryListener::MouseQueryListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager, CEGUI::Renderer *renderer)
159        : ExampleFrameListener(win, cam, false, true), mGUIRenderer(renderer),
160                mShutdownRequested(false)
161{
162
163        // Setup default variables
164//      mCurrentObject = NULL;
165        mLMouseDown = false;
166        mRMouseDown = false;
167        mSceneMgr = sceneManager;
168
169    // Reduce move speed
170        mMoveSpeed = 50;
171        mRotateSpeed *= 2;
172
173        mCurrentAlgorithm = OcclusionCullingSceneTraverser::RENDER_COHERENT;
174        mThreshold = 0;
175   
176        // Register this so that we get mouse events.
177        mEventProcessor->addMouseListener(this);
178        mEventProcessor->addMouseMotionListener(this);
179        mEventProcessor->addKeyListener(this);
180
181        // show overlay
182        Overlay* pOver = OverlayManager::getSingleton().getByName("Example/OcclusionDemoOverlay");
183
184        mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/AlgorithmInfo");
185        mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/ThresholdInfo");
186        mFrustumCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/FrustumCulledNodesInfo");
187        mQueryCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/QueryCulledNodesInfo");
188    mTraversedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/TraversedNodesInfo");
189
190        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
191        mThresholdInfo->setCaption(": 0");
192        mFrustumCulledNodesInfo->setCaption(": 0");
193        mQueryCulledNodesInfo->setCaption(": 0");
194        mTraversedNodesInfo->setCaption(": 0");
195
196    pOver->show();
197} // MouseQueryListener
198//-----------------------------------------------------------------------
199void MouseQueryListener::mouseMoved (MouseEvent *e)
200{
201        // Update CEGUI with the mouse motion
202    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() * mGUIRenderer->getWidth(), e->getRelY() * mGUIRenderer->getHeight());
203}
204//-----------------------------------------------------------------------
205void MouseQueryListener::mousePressed(MouseEvent* e)
206{
207     // Left mouse button down
208     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
209     {
210                 CEGUI::MouseCursor::getSingleton().hide( );
211                 mLMouseDown = true;
212     } // if
213     // Right mouse button down
214     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
215     {
216         CEGUI::MouseCursor::getSingleton().hide( );
217         mRMouseDown = true;
218     } // else if
219} // mousePressed
220
221 //-----------------------------------------------------------------------
222void MouseQueryListener::mouseReleased(MouseEvent* e)
223{
224    // Left mouse button up
225    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
226    {
227                CEGUI::MouseCursor::getSingleton().show( );
228        mLMouseDown = false;
229    }
230    // Right mouse button up
231    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
232    {
233        CEGUI::MouseCursor::getSingleton().show( );
234        mRMouseDown = false;
235    }
236}
237//-----------------------------------------------------------------------
238void MouseQueryListener::mouseDragged (MouseEvent *e)
239 {
240         /*
241         // If we are dragging the left mouse button.   
242         if ( mLMouseDown )
243         {
244                mShipNode->translate(-e->getRelX() * 200, -e->getRelY() * 200, 0.0);
245     }
246         */
247         
248         // If we are dragging the right mouse button.
249         if ( mRMouseDown )
250         {
251                 mCamera->yaw( -e->getRelX() * mRotateSpeed );
252                 mCamera->pitch( -e->getRelY() * mRotateSpeed );
253         }
254}
255//-----------------------------------------------------------------------
256bool MouseQueryListener::frameStarted(const FrameEvent &evt)
257{
258        // clamp to terrain
259        static Ray updateRay;
260        updateRay.setOrigin(mCamera->getPosition());
261        updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);
262        raySceneQuery->setRay(updateRay);
263        RaySceneQueryResult& qryResult = raySceneQuery->execute();
264        RaySceneQueryResult::iterator i = qryResult.begin();
265         
266        if (i != qryResult.end() && i->worldFragment)
267        {
268                SceneQuery::WorldFragment* wf = i->worldFragment;
269                mCamera->setPosition(mCamera->getPosition().x,
270                        i->worldFragment->singleIntersection.y + 10,
271                        mCamera->getPosition().z);
272        }
273         
274        return ExampleFrameListener::frameStarted(evt);
275}
276//-----------------------------------------------------------------------
277bool MouseQueryListener::frameEnded(const FrameEvent& evt)
278{
279        if (mShutdownRequested)
280                return false;
281
282    if (timeDelay >= 0)
283        timeDelay -= evt.timeSinceLastFrame;
284
285    KEY_PRESSED(KC_SPACE, 0.3, changeAlgorithm());
286
287        KEY_PRESSED(KC_SUBTRACT, 0.3, changeThreshold(-10));
288        KEY_PRESSED(KC_ADD, 0, changeThreshold(10));
289        //KEY_PRESSED(KC_T, 1, change);
290     
291        changeStats();
292
293    return ExampleFrameListener::frameStarted(evt) && ExampleFrameListener::frameEnded(evt);       
294}
295//-----------------------------------------------------------------------
296void MouseQueryListener::changeThreshold(int incr)
297{
298        mThreshold += incr; if(mThreshold < 0) mThreshold = 0;
299       
300        char str[100]; sprintf(str,": %d", mThreshold);
301
302        mSceneMgr->setOption("Threshold", &mThreshold);
303        mThresholdInfo->setCaption(str);
304}
305//-----------------------------------------------------------------------
306void MouseQueryListener::changeAlgorithm()
307{
308    mCurrentAlgorithm = ++mCurrentAlgorithm % OcclusionCullingSceneTraverser::NUM_RENDERMODES;
309
310        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
311        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
312}
313//-----------------------------------------------------------------------
314void MouseQueryListener::changeStats()
315{
316        unsigned int opt = 0;
317        char str[100];
318       
319        mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
320        mFrustumCulledNodesInfo->setCaption(str);
321       
322        mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
323        mQueryCulledNodesInfo->setCaption(str);
324       
325        mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt);
326        mTraversedNodesInfo->setCaption(str);
327}
328//-----------------------------------------------------------------------
329void MouseQueryListener::keyPressed(KeyEvent* e)
330{
331        if(e->getKey() == KC_ESCAPE)
332    {
333                mShutdownRequested = true;
334                e->consume();
335                return;
336        }
337
338        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
339        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
340        e->consume();
341}
342//-----------------------------------------------------------------------
343void MouseQueryListener::keyReleased(KeyEvent* e)
344{
345        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
346        e->consume();
347}
348//-----------------------------------------------------------------------
349void MouseQueryListener::keyClicked(KeyEvent* e)
350{
351        // Do nothing
352        e->consume();
353}
354//-----------------------------------------------------------------------
355INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
356{
357    // Create application object
358    TestCullingApplication app;
359
360        try
361        {
362        app.go();
363    }
364        catch( Ogre::Exception& e )
365        {
366        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
367    }   
368
369    return 0;
370}
Note: See TracBrowser for help on using the repository browser.