source: trunk/VUT/work/TestCullingTerrain/TestCullingTerrainApplication.cpp @ 61

Revision 61, 15.1 KB checked in by mattausch, 20 years ago (diff)
RevLine 
[61]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
18#define WIN32_LEAN_AND_MEAN
19#include "windows.h"
20
21
22/************************************************/
23/* TestCullingTerrainApplication implementation */
24/************************************************/
25TestCullingTerrainApplication::~TestCullingTerrainApplication()
26{
27        delete mRayQueryExecutor;
28        delete mTerrainContentGenerator;
29}
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::generateSceneObject(const Vector3 &translationRatio,
47                                         const Vector3 &rotationRatio, const int idx, const String& entName)
48{
49        // Setup the ray scene query
50        /*Vector3 rotation = mMinAngle + rotationRatio * (mMaxAngle - mMinAngle);
51        Vector3 translation = mMinTranslation + translationRatio * (mMaxTranslation - mMinTranslation);
52
53        translation.y = 5000;
54    Ray ray(translation, Vector3::NEGATIVE_UNIT_Y);
55    mRaySceneQuery->setRay(ray);
56
57    // Execute query
58        RaySceneQueryResult &result = mRaySceneQuery->execute();
59        RaySceneQueryResult::iterator itr = result.begin( );
60
61        // Get results, create a node/entity on the position
62        if ( itr != result.end() && itr->worldFragment )
63        {
64                char name[16];
65                sprintf( name, "%s%d", entName.c_str(), mCount++ );
66
67                Entity *ent = mSceneMgr->createEntity( name, entName );
68                SceneNode currentObject = mSceneMgr->getRootSceneNode( )->createChildSceneNode( String(name) + "Node", itr->worldFragment->singleIntersection );
69                currentObject->attachObject( ent );
70                currentObject->setScale( 0.1f, 0.1f, 0.1f );
71        }*/
72}
73
74//-----------------------------------------------------------------------
75void TestCullingTerrainApplication::createScene( void )
76{
77        mRayQueryExecutor = new RayQueryExecutor(mSceneMgr);
78        mTerrainContentGenerator = new TerrainContentGenerator(mSceneMgr, mRayQueryExecutor);
79        // Set ambient light
80        mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
81       
82        // Create a light
83        Light* l = mSceneMgr->createLight("MainLight");
84        // Accept default settings: point light, white diffuse, just set position
85        // NB I could attach the light to a SceneNode if I wanted it to move automatically with
86        //  other objects, but I don't
87        l->setPosition(20,80,50);
88
89        // --Fog
90        // NB it's VERY important to set this before calling setWorldGeometry
91        // because the vertex program picked will be different
92        ColourValue fadeColour(0.93, 0.86, 0.76);
93        mWindow->getViewport(0)->setBackgroundColour(fadeColour);
94        //mSceneMgr->setFog( FOG_LINEAR, fadeColour, .001, 500, 1000);
95
96        // Create a skybox
97    //mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 500, false);
98        //mSceneMgr->setSkyDome( true, "Examples/CloudySky", 5, 8, 500, false );
99
100        /*      // Define the required skyplane
101        Plane plane;
102        // 5000 world units from the camera
103        plane.d = 5000;
104        // Above the camera, facing down
105        plane.normal = -Vector3::UNIT_Y;
106        // Create the plane 10000 units wide, tile the texture 3 times
107    mSceneMgr->setSkyPlane(true, plane, "Examples/SpaceSkyPlane",10000,3);*/
108
109        std::string terrain_cfg("terrain.cfg");
110#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
111        terrain_cfg = mResourcePath + terrain_cfg;
112#endif
113        mSceneMgr -> setWorldGeometry( terrain_cfg );
114        // Infinite far plane?
115        if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE))
116        {
117                mCamera->setFarClipDistance(0);
118        }
119
120        // Set a nice viewpoint
121        mCamera->setPosition(707,2500,528);
122        mCamera->setOrientation(Quaternion(-0.3486, 0.0122, 0.9365, 0.0329));
123
124        // CEGUI setup
125        setupGui();
126}
127//-----------------------------------------------------------------------
128void TestCullingTerrainApplication::setupGui( void )
129{
130         mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, ST_EXTERIOR_CLOSE);
131     mGUISystem = new CEGUI::System(mGUIRenderer);
132
133         // Mouse
134     CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLook.scheme");
135     CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseArrow");
136         mGUISystem->setDefaultMouseCursor(
137                (CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
138
139         CEGUI::MouseCursor::getSingleton().show( );
140}
141//-----------------------------------------------------------------------
142void TestCullingTerrainApplication::createFrameListener(void)
143{
144        mFrameListener= new MouseQueryListener(mWindow, mCamera, mSceneMgr, mGUIRenderer, mRayQueryExecutor);
145        mFrameListener->showDebugOverlay(true);
146        mRoot->addFrameListener(mFrameListener);
147}
148//-----------------------------------------------------------------------
149void TestCullingTerrainApplication::chooseSceneManager(void)
150{
151    //mSceneMgr = mRoot->getSceneManager(ST_GENERIC);
152        mSceneMgr = mRoot->getSceneManager(ST_EXTERIOR_CLOSE);
153}
154
155/***********************************************/
156/* MouseQueryListener implementation           */
157/***********************************************/
158//-----------------------------------------------------------------------
159MouseQueryListener::MouseQueryListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager, CEGUI::Renderer *renderer, RayQueryExecutor *rqe)
160        : ExampleFrameListener(win, cam, false, true), mGUIRenderer(renderer), mShutdownRequested(false), mRayQueryExecutor(rqe)
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 = 0;//VisibilitySceneTraverser::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        mRaySceneQuery = mSceneMgr->createRayQuery(Ray());
182
183        // show overlay
184        Overlay* pOver = OverlayManager::getSingleton().getByName("Example/VisibilityDemoOverlay");
185
186        mAlgorithmInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/AlgorithmInfo");
187        mThresholdInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/ThresholdInfo");
188        mFrustumCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/FrustumCulledNodesInfo");
189        mQueryCulledNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/QueryCulledNodesInfo");
190    mTraversedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/TraversedNodesInfo");
191        mSceneNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/SceneNodesInfo");
192        mHierarchyNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/HierarchyNodesInfo");
193        mRenderedNodesInfo = OverlayManager::getSingleton().getOverlayElement("Example/Occlusion/RenderedNodesInfo");
194
195        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
196        mThresholdInfo->setCaption(": 0");
197        mFrustumCulledNodesInfo->setCaption(": 0");
198        mQueryCulledNodesInfo->setCaption(": 0");
199        mTraversedNodesInfo->setCaption(": 0");
200        mSceneNodesInfo->setCaption(": 0");
201        mHierarchyNodesInfo->setCaption(": 0");
202        mRenderedNodesInfo->setCaption(": 0");
203               
204    pOver->show();
205}
206//-----------------------------------------------------------------------
207MouseQueryListener::~MouseQueryListener( )
208{
209        delete mRaySceneQuery;
210}
211//-----------------------------------------------------------------------
212void MouseQueryListener::mouseMoved (MouseEvent *e)
213{
214        // Update CEGUI with the mouse motion
215    CEGUI::System::getSingleton().injectMouseMove(e->getRelX() * mGUIRenderer->getWidth(), e->getRelY() * mGUIRenderer->getHeight());
216}
217//-----------------------------------------------------------------------
218void MouseQueryListener::mousePressed(MouseEvent* e)
219{
220     // Left mouse button down
221     if (e->getButtonID() & InputEvent::BUTTON0_MASK)
222     {
223                 CEGUI::MouseCursor::getSingleton().hide( );
224
225                 // Setup the ray scene query
226         Ray mouseRay = mCamera->getCameraToViewportRay( e->getX(), e->getY() );
227         mRaySceneQuery->setRay( mouseRay );
228
229         // Execute query
230         RaySceneQueryResult &result = mRaySceneQuery->execute();
231         RaySceneQueryResult::iterator itr = result.begin( );
232
233         // Get results, create a node/entity on the position
234         if ( itr != result.end() && itr->worldFragment )
235         {
236                         char name[16];
237             sprintf( name, "Robot%d", mCount++ );
238
239             Entity *ent = mSceneMgr->createEntity( name, "robot.mesh" );
240             mCurrentObject = mSceneMgr->getRootSceneNode( )->createChildSceneNode( String(name) + "Node", itr->worldFragment->singleIntersection );
241             mCurrentObject->attachObject( ent );
242             mCurrentObject->setScale( 0.1f, 0.1f, 0.1f );
243         }
244
245         mLMouseDown = true;
246     }
247     // Right mouse button down
248     else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
249     {
250         CEGUI::MouseCursor::getSingleton().hide( );
251         mRMouseDown = true;
252     } // else if
253} // mousePressed
254
255 //-----------------------------------------------------------------------
256void MouseQueryListener::mouseReleased(MouseEvent* e)
257{
258    // Left mouse button up
259    if (e->getButtonID() & InputEvent::BUTTON0_MASK)
260    {
261                CEGUI::MouseCursor::getSingleton().show( );
262        mLMouseDown = false;
263    }
264    // Right mouse button up
265    else if (e->getButtonID() & InputEvent::BUTTON1_MASK)
266    {
267        CEGUI::MouseCursor::getSingleton().show( );
268        mRMouseDown = false;
269    }
270}
271//-----------------------------------------------------------------------
272void MouseQueryListener::mouseDragged (MouseEvent *e)
273 {
274         // If we are dragging the left mouse button.           
275         if ( mLMouseDown )
276     {
277                 Ray mouseRay = mCamera->getCameraToViewportRay( e->getX(), e->getY() );
278                 mRaySceneQuery->setRay( mouseRay );
279
280                 RaySceneQueryResult &result = mRaySceneQuery->execute();
281                 RaySceneQueryResult::iterator itr = result.begin( );
282
283                 if ( itr != result.end() && itr->worldFragment )
284                 {
285                         mCurrentObject->setPosition( itr->worldFragment->singleIntersection );
286                 }
287     }
288         // If we are dragging the right mouse button.
289         if ( mRMouseDown )
290         {
291                 mCamera->yaw( -e->getRelX() * mRotateSpeed );
292                 mCamera->pitch( -e->getRelY() * mRotateSpeed );
293         }
294}
295//-----------------------------------------------------------------------
296bool MouseQueryListener::frameStarted(const FrameEvent &evt)
297{
298        // clamp to terrain
299        Vector3 camPos = mCamera->getPosition( );
300    Ray cameraRay( Vector3(camPos.x, 5000.0f, camPos.z), Vector3::NEGATIVE_UNIT_Y );
301    mRaySceneQuery->setRay( cameraRay );
302
303    // Perform the scene query
304    RaySceneQueryResult &queryResult = mRaySceneQuery->execute();
305    RaySceneQueryResult::iterator it = queryResult.begin( );
306
307        if (it != queryResult.end() && it->worldFragment)
308        {
309                SceneQuery::WorldFragment* wf = it->worldFragment;
310
311                mCamera->setPosition(mCamera->getPosition().x, wf->singleIntersection.y + 10,
312                        mCamera->getPosition().z);
313        }
314         
315        return ExampleFrameListener::frameStarted(evt);
316}
317//-----------------------------------------------------------------------
318bool MouseQueryListener::frameEnded(const FrameEvent& evt)
319{
320        if (mShutdownRequested)
321                return false;
322
323    if (timeDelay >= 0)
324        timeDelay -= evt.timeSinceLastFrame;
325
326    KEY_PRESSED(KC_SPACE, 0.3, changeAlgorithm());
327
328        KEY_PRESSED(KC_SUBTRACT, 0, changeThreshold(-10));
329        KEY_PRESSED(KC_ADD, 0, changeThreshold(10));
330        //KEY_PRESSED(KC_T, 1, change);
331     
332        changeStats();
333
334    return ExampleFrameListener::frameStarted(evt) && ExampleFrameListener::frameEnded(evt);       
335}
336//-----------------------------------------------------------------------
337void MouseQueryListener::changeThreshold(int incr)
338{
339        mThreshold += incr; if(mThreshold < 0) mThreshold = 0;
340       
341        char str[100]; sprintf(str,": %d", mThreshold);
342
343        mSceneMgr->setOption("Threshold", &mThreshold);
344        mThresholdInfo->setCaption(str);
345}
346//-----------------------------------------------------------------------
347void MouseQueryListener::changeAlgorithm()
348{
349    //mCurrentAlgorithm = ++mCurrentAlgorithm % VisibilitySceneTraverser::NUM_RENDERMODES;
350
351        mAlgorithmInfo->setCaption(": " + mCurrentAlgorithmCaptions[mCurrentAlgorithm]);
352        mSceneMgr->setOption("Algorithm", &mCurrentAlgorithm);
353}
354//-----------------------------------------------------------------------
355void MouseQueryListener::changeStats()
356{
357        unsigned int opt = 0;
358        char str[100];
359       
360        mSceneMgr->getOption("NumFrustumCulledNodes", &opt); sprintf(str,": %d", opt);
361        mFrustumCulledNodesInfo->setCaption(str);
362       
363        mSceneMgr->getOption("NumQueryCulledNodes", &opt); sprintf(str,": %d", opt);
364        mQueryCulledNodesInfo->setCaption(str);
365       
366        mSceneMgr->getOption("NumTraversedNodes", &opt); sprintf(str,": %d", opt);
367        mTraversedNodesInfo->setCaption(str);
368
369        mSceneMgr->getOption("NumSceneNodes", &opt); sprintf(str,": %d", opt);
370        mSceneNodesInfo->setCaption(str);
371
372        mSceneMgr->getOption("NumOctreeNodes", &opt); sprintf(str,": %d", opt);
373        mHierarchyNodesInfo->setCaption(str);
374
375        mSceneMgr->getOption("NumRenderedNodes", &opt); sprintf(str,": %d", opt);
376        mRenderedNodesInfo->setCaption(str);
377}
378//-----------------------------------------------------------------------
379void MouseQueryListener::keyPressed(KeyEvent* e)
380{
381        if(e->getKey() == KC_ESCAPE)
382    {
383                mShutdownRequested = true;
384                e->consume();
385                return;
386        }
387
388        CEGUI::System::getSingleton().injectKeyDown(e->getKey());
389        CEGUI::System::getSingleton().injectChar(e->getKeyChar());
390        e->consume();
391}
392//-----------------------------------------------------------------------
393void MouseQueryListener::keyReleased(KeyEvent* e)
394{
395        CEGUI::System::getSingleton().injectKeyUp(e->getKey());
396        e->consume();
397}
398//-----------------------------------------------------------------------
399void MouseQueryListener::keyClicked(KeyEvent* e)
400{
401        // Do nothing
402        e->consume();
403}
404//-----------------------------------------------------------------------
405INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
406{
407    // Create application object
408    TestCullingTerrainApplication app;
409
410        try
411        {
412        app.go();
413    }
414        catch( Ogre::Exception& e )
415        {
416        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
417    }   
418
419    return 0;
420}
Note: See TracBrowser for help on using the repository browser.