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

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