source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp @ 2806

Revision 2806, 26.9 KB checked in by mattausch, 16 years ago (diff)

improved visualization

Line 
1// occquery.cpp : Defines the entry point for the console application.
2//
3#include <math.h>
4#include <time.h>
5#include "common.h"
6#include "glInterface.h"
7#include "RenderTraverser.h"
8#include "SceneEntity.h"
9#include "Vector3.h"
10#include "Matrix4x4.h"
11#include "ResourceManager.h"
12#include "Bvh.h"
13#include "Camera.h"
14#include "Geometry.h"
15#include "BvhLoader.h"
16#include "FrustumCullingTraverser.h"
17#include "StopAndWaitTraverser.h"
18#include "CHCTraverser.h"
19#include "CHCPlusPlusTraverser.h"
20#include "Visualization.h"
21#include "RenderState.h"
22#include "Timer/PerfTimer.h"
23#include "SceneQuery.h"
24#include "RenderQueue.h"
25
26
27using namespace std;
28using namespace CHCDemoEngine;
29
30
31
32/// the renderable scene geometry
33SceneEntityContainer sceneEntities;
34// traverses and renders the hierarchy
35RenderTraverser *traverser = NULL;
36/// the hierarchy
37Bvh *bvh = NULL;
38/// handles scene loading
39ResourceManager *loader = NULL;
40/// the scene camera
41Camera *camera = NULL;
42/// the scene camera
43Camera *visCamera = NULL;
44/// the visualization
45Visualization *visualization = NULL;
46/// the current render state
47RenderState state;
48/// the rendering algorithm
49int renderMode = RenderTraverser::CHCPLUSPLUS;
50// eye near plane distance
51float nearDist = 0.1f;
52/// the pixel threshold where a node is still considered invisible
53int threshold;
54
55float fov = 50.0f;
56
57int assumedVisibleFrames = 10;
58int maxBatchSize = 50;
59
60int trianglesPerVirtualLeaf = INITIAL_TRIANGLES_PER_VIRTUAL_LEAVES;
61
62SceneQuery *sceneQuery = NULL;
63RenderQueue *renderQueue = NULL;
64
65
66/// these values get scaled with the frame rate
67const float keyForwardMotion = 50.0f;
68const float keyRotation = 2.0f;
69/// elapsed time in seconds
70double elapsedTime = 1.0f;
71double algTime = 1.0f;
72
73int winWidth = 1024;
74int winHeight = 768;
75float winAspectRatio = 1.0f;
76
77double accumulatedTime = 1000;
78float fps = 1e3f;
79
80int renderedObjects = 0;
81int renderedNodes = 0;
82int renderedTriangles = 0;
83
84int issuedQueries = 0;
85int traversedNodes = 0;
86int frustumCulledNodes = 0;
87int queryCulledNodes = 0;
88int stateChanges = 0;
89int numBatches = 0;
90
91bool showHelp = false;
92bool showStatistics = true;
93bool showOptions = true;
94bool showBoundingVolumes = false;
95bool visMode = false;
96
97// mouse navigation state
98int xEyeBegin, yEyeBegin, yMotionBegin = 0;
99int verticalMotionBegin, horizontalMotionBegin = 0;
100
101bool useOptimization = false;
102bool useTightBounds = true;
103bool useRenderQueue = true;
104bool useMultiQueries = true;
105bool flyMode = true;
106bool depthPass = false;
107bool useGlFinish = false;
108
109SceneEntityContainer skyGeometry;
110
111bool leftKeyPressed = false;
112bool rightKeyPressed = false;
113bool upKeyPressed = false;
114bool downKeyPressed = false;
115bool nineKeyPressed = false;
116bool eightKeyPressed = false;
117
118
119void InitExtensions();
120void DisplayVisualization();
121void InitGLstate();
122void CleanUp();
123void SetupEyeView();
124void UpdateEyeMtx();
125void SetupLighting();
126void DisplayStats();
127void Output(int x, int y, const char *string);
128void DrawHelpMessage();
129void RenderSky();
130void RenderVisibleObjects();
131
132void Begin2D();
133void End2D();
134void KeyBoard(unsigned char c, int x, int y);
135void DrawStatistics();
136void Display();
137void Special(int c, int x, int y);
138void KeyUp(unsigned char c, int x, int y);
139void SpecialKeyUp(int c, int x, int y);
140void Reshape(int w, int h);
141void Mouse(int button, int state, int x, int y);
142void LeftMotion(int x, int y);
143void RightMotion(int x, int y);
144void MiddleMotion(int x, int y);
145void CalcDecimalPoint(string &str, int d);
146void ResetTraverser();
147
148void KeyHorizontalMotion(float shift);
149void KeyVerticalMotion(float shift);
150
151void PlaceViewer(const Vector3 &oldPos);
152
153
154inline float KeyRotationAngle() { return keyRotation * elapsedTime; }
155inline float KeyShift() { return keyForwardMotion * elapsedTime; }
156
157
158
159int main(int argc, char* argv[])
160{
161        int returnCode = 0;
162
163        camera = new Camera(winWidth, winHeight, fov);
164        camera->SetNear(nearDist);
165       
166        visCamera = new Camera(winWidth, winHeight, fov);
167
168        visCamera->SetNear(0.0f);
169        visCamera->Yaw(.5 * M_PI);
170
171        renderQueue = new RenderQueue(&state, camera);
172
173        glutInitWindowSize(winWidth, winHeight);
174        glutInit(&argc, argv);
175        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
176
177        glutCreateWindow("FriendlyCulling");
178
179        glutDisplayFunc(Display);
180        glutKeyboardFunc(KeyBoard);
181        glutSpecialFunc(Special);
182        glutReshapeFunc(Reshape);
183        glutMouseFunc(Mouse);
184        glutIdleFunc(Display);
185        glutKeyboardUpFunc(KeyUp);
186        glutSpecialUpFunc(SpecialKeyUp);
187        glutIgnoreKeyRepeat(true);
188
189        InitExtensions();
190        InitGLstate();
191
192        LeftMotion(0, 0);
193        MiddleMotion(0, 0);
194
195
196        loader = new ResourceManager();
197
198        //const string filename("data/city/model/city.dem");
199        const string filename = string(model_path + "city.dem");
200
201        if (loader->Load(filename, sceneEntities))
202                cout << "scene " << filename << " loaded" << endl;
203        else
204        {
205                cerr << "loading scene " << filename << " failed" << endl;
206                CleanUp();
207                exit(0);
208        }
209
210        SceneEntityContainer dummy;
211
212        const string envname = string(model_path + "env.dem");
213
214        if (loader->Load(envname, skyGeometry))
215                cout << "sky box " << filename << " loaded" << endl;
216        else
217        {
218                cerr << "loading sky box " << filename << " failed" << endl;
219                CleanUp();
220                exit(0);
221        }
222
223
224        const string bvh_filename = string(model_path + "city.bvh");
225        BvhLoader bvhLoader;
226        bvh = bvhLoader.Load(bvh_filename, sceneEntities);
227        //bvh = bvhLoader.Load("data/city/model/city.bvh", sceneEntities);
228
229        if (!bvh)
230        {
231                cerr << "loading bvh " << bvh_filename << " failed" << endl;
232                CleanUp();
233                exit(0);
234        }
235
236        camera->SetFar(0.7f * Magnitude(bvh->GetBox().Diagonal()));
237
238        bvh->SetCamera(camera);
239
240        ResetTraverser();
241
242        camera->Pitch(-M_PI * 0.5);
243        camera->SetPosition(Vector3(483.398f, 242.364f, 186.078f));
244
245        visualization = new Visualization(bvh, camera, NULL, &state);
246
247        sceneQuery = new SceneQuery(bvh->GetBox(), traverser);
248
249
250        glutMainLoop();
251
252        // clean up
253        CleanUp();
254
255        return 0;
256}
257
258
259void InitGLstate(void)
260{
261        glClearColor(0.5f, 0.5f, 0.8f, 0.0f);
262       
263        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
264        glPixelStorei(GL_PACK_ALIGNMENT,1);
265       
266        glDepthFunc(GL_LESS);
267        glEnable(GL_DEPTH_TEST);
268
269        SetupLighting();
270
271        glColor3f(1.0f, 1.0f, 1.0f);
272        glShadeModel(GL_SMOOTH);
273       
274        glMaterialf(GL_FRONT, GL_SHININESS, 64);
275        glEnable(GL_NORMALIZE);
276               
277        //glEnable(GL_ALPHA_TEST);
278        glDisable(GL_ALPHA_TEST);
279        glAlphaFunc(GL_GEQUAL, 0.5f);
280
281        glFrontFace(GL_CCW);
282        glCullFace(GL_BACK);
283        glEnable(GL_CULL_FACE);
284        //glDisable(GL_CULL_FACE);
285        glDisable(GL_TEXTURE_2D);
286
287        GLfloat ambientColor[] = {0.5, 0.5, 0.5, 1.0};
288        GLfloat diffuseColor[] = {1.0, 0.0, 0.0, 1.0};
289        GLfloat specularColor[] = {0.0, 0.0, 0.0, 1.0};
290
291        glMaterialfv(GL_FRONT, GL_AMBIENT, ambientColor);
292        glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor);
293        glMaterialfv(GL_FRONT, GL_SPECULAR, specularColor);
294
295        glDepthFunc(GL_LESS);
296}
297
298
299void DrawHelpMessage(void)
300{
301        const char *message[] =
302        {
303                "Help information",
304                "",
305                "'F1'           - shows/dismisses this message",
306                "'F2'           - shows/hides bird eye view",
307                "'F3'           - shows/hides bounds (boxes or tight bounds)",
308                "'F4'           - shows/hides statistics",
309                "'F5',          - toggles between fly / walkmode",
310                "'F6',          - shows/hides parameters",
311                "'F7',          - depth pass",
312                "'F8',          - enable/disable glFinish for more accurate timings",
313                "'SPACE'        - cycles through occlusion culling algorithms",
314                "",
315                "'MOUSE-LEFT'   - turn left/right, move forward/backward",
316                "'MOUSE-RIGHT'  - turn left/right, move forward/backward",
317                "'MOUSE-MIDDLE' - move up/down, left/right",
318                "'CURSOR UP'    - move forward",
319                "'CURSOR BACK'  - move backward",
320                "'CURSOR RIGHT' - turn right",
321                "'CURSOR LEFT'  - turn left",
322                "",
323                "'-'            - decreases max batch size",
324                "'+'            - increases max batch size",
325                "'4'            - decrease triangles per virtual leaf (sets depth of bvh)",
326                "'5'            - increase triangles per virtual leaf (sets depth of bvh)",
327                "'6'            - decrease assumed visible frames",
328                "'7'            - increase assumed visible frames",
329                "'8'            - downward motion",
330                "'9'            - upward motion",
331                "",
332                "'R'            - use render queue",
333                "'B'            - use tight bounds",
334                "'M'            - use multiqueries",
335                "'O'            - use CHC optimization (geometry queries for leaves)",
336                0,
337        };
338       
339       
340        int x = 40, y = 60;
341
342        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
343        glEnable(GL_BLEND);
344        glColor4f(0.0f, 1.0f , 0.0f, 0.2f);  // 20% green.
345
346        // Drawn clockwise because the flipped Y axis flips CCW and CW.
347        glRecti(winWidth - 30, 30, 30, winHeight - 30);
348       
349        glDisable(GL_BLEND);
350       
351        glColor3f(1.0f, 1.0f, 1.0f);
352       
353        for(int i = 0; message[i] != 0; i++)
354        {
355                if(message[i][0] == '\0')
356                {
357                        y += 15;
358                }
359                else
360                {
361                        Output(x, y, message[i]);
362                        y += 20;
363                }
364        }
365}
366
367
368void ResetTraverser()
369{
370        DEL_PTR(traverser);
371
372        bvh->ResetNodeClassifications();
373
374        switch (renderMode)
375        {
376        case RenderTraverser::CULL_FRUSTUM:
377                traverser = new FrustumCullingTraverser();
378                break;
379        case RenderTraverser::STOP_AND_WAIT:
380                traverser = new StopAndWaitTraverser();
381                break;
382        case RenderTraverser::CHC:
383                traverser = new CHCTraverser();
384                break;
385        case RenderTraverser::CHCPLUSPLUS:
386                traverser = new CHCPlusPlusTraverser();
387                break;
388       
389        default:
390                traverser = new FrustumCullingTraverser();
391        }
392
393        traverser->SetCamera(camera);
394        traverser->SetHierarchy(bvh);
395        traverser->SetRenderQueue(renderQueue);
396        traverser->SetRenderState(&state);
397        traverser->SetUseOptimization(useOptimization);
398        traverser->SetUseRenderQueue(useRenderQueue);
399        traverser->SetVisibilityThreshold(threshold);
400        traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
401        traverser->SetMaxBatchSize(maxBatchSize);
402        traverser->SetUseMultiQueries(useMultiQueries);
403        traverser->SetUseTightBounds(useTightBounds);
404        traverser->SetUseDepthPass(depthPass);
405        traverser->SetRenderQueue(renderQueue);
406}
407
408
409void SetupLighting()
410{
411        glEnable(GL_LIGHTING);
412        glEnable(GL_LIGHT0);
413        //glEnable(GL_LIGHT1);
414        glDisable(GL_LIGHT1);
415
416        //GLfloat ambient[] = {0.5, 0.5, 0.5, 1.0};
417        GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
418        GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0};
419        GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
420           
421        GLfloat lmodel_ambient[] = {0.5f, 0.5f, 0.5f, 1.0f};
422        //GLfloat lmodel_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
423
424        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
425        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
426        glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
427
428        GLfloat position[] = {1.0, 1.0, 1.0, 0.0};
429        glLightfv(GL_LIGHT0, GL_POSITION, position);
430
431
432        ////////////
433        //-- second light
434
435        GLfloat ambient1[] = {0.5, 0.5, 0.5, 1.0};
436        //GLfloat diffuse1[] = {1.0, 1.0, 1.0, 1.0};
437        GLfloat diffuse1[] = {0.5, 0.5, 0.5, 1.0};
438        GLfloat specular1[] = {0.5, 0.5, 0.5, 1.0};
439
440        glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1);
441        glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1);
442        glLightfv(GL_LIGHT1, GL_SPECULAR, specular1);
443       
444        GLfloat position1[] = {0.0, 1.0, 0.0, 1.0};
445        glLightfv(GL_LIGHT1, GL_POSITION, position1);
446
447        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
448        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
449        //glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
450        //glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);
451        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SINGLE_COLOR_EXT);
452}
453
454
455void SetupEyeView()
456{
457        glMatrixMode(GL_PROJECTION);
458        glLoadIdentity();
459
460        gluPerspective(fov, 1.0f / winAspectRatio, nearDist, 10.0f * Magnitude(bvh->GetBox().Diagonal()));
461
462        glMatrixMode(GL_MODELVIEW);
463        glLoadIdentity();
464        camera->SetupCameraView();
465
466        GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
467        glLightfv(GL_LIGHT0, GL_POSITION, position);
468
469        GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
470        glLightfv(GL_LIGHT1, GL_POSITION, position1);
471}
472
473
474void KeyHorizontalMotion(float shift)
475{
476        Vector3 hvec = camera->GetDirection();
477        hvec.z = 0;
478
479        Vector3 pos = camera->GetPosition();
480        pos += hvec * shift;
481       
482        camera->SetPosition(pos);
483}
484
485
486void KeyVerticalMotion(float shift)
487{
488        Vector3 uvec = Vector3(0, 0, shift);
489
490        Vector3 pos = camera->GetPosition();
491        pos += uvec;
492       
493        camera->SetPosition(pos);
494}
495
496
497
498void Display()
499{       
500        PerfTimer frameTimer, algTimer;
501        frameTimer.Start();
502
503        Vector3 oldPos = camera->GetPosition();
504
505        if (leftKeyPressed)
506                camera->Pitch(KeyRotationAngle());
507        if (rightKeyPressed)
508                camera->Pitch(-KeyRotationAngle());
509        if (upKeyPressed)
510                KeyHorizontalMotion(KeyShift());
511        if (downKeyPressed)
512                KeyHorizontalMotion(-KeyShift());
513        if (eightKeyPressed)
514                KeyVerticalMotion(-KeyShift());
515        if (nineKeyPressed)
516                KeyVerticalMotion(KeyShift());
517
518        // place view on ground
519        if (!flyMode) PlaceViewer(oldPos);
520
521        if (useGlFinish) glFinish();
522
523        algTimer.Start();
524
525        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
526
527        glDepthFunc(GL_LESS);
528        glDisable(GL_TEXTURE_2D);
529        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
530
531        // render without shading
532        if (depthPass)
533        {
534                state.SetDepthPass(true);
535                glDisable(GL_LIGHTING);
536        }
537        else
538        {
539                state.SetDepthPass(false);
540                glEnable(GL_LIGHTING);
541        }
542
543        // bring eye modelview matrix up-to-date
544        SetupEyeView();
545
546        // actually render the scene geometry using one of the specified algorithms
547        traverser->RenderScene();
548
549
550        //////
551        //-- other rendering
552
553        glEnableClientState(GL_VERTEX_ARRAY);
554        glEnableClientState(GL_NORMAL_ARRAY);
555
556
557        // reset depth pass and render visible objects
558        if (depthPass)
559        {
560                RenderVisibleObjects();
561        }
562       
563
564        ///////////////
565        //-- render sky
566
567        RenderSky();
568
569        state.Reset();
570
571        glDisableClientState(GL_VERTEX_ARRAY);
572        glDisableClientState(GL_NORMAL_ARRAY);
573
574        if (useGlFinish) glFinish();
575
576        algTime = algTimer.Elapsedms();
577
578        ///////////
579
580        if (visMode) DisplayVisualization();
581       
582        DisplayStats();
583
584        glutSwapBuffers();
585
586        elapsedTime = frameTimer.Elapsed();
587}
588
589
590#pragma warning( disable : 4100 )
591void KeyBoard(unsigned char c, int x, int y)
592{
593        switch(c)
594        {
595        case 27:
596                CleanUp();
597                exit(0);
598                break;
599        case 32: //space
600                renderMode = (renderMode + 1) % RenderTraverser::NUM_TRAVERSAL_TYPES;
601                ResetTraverser();
602                break;
603        case 'h':
604        case 'H':
605                showHelp = !showHelp;
606                break;
607        case '+':
608                maxBatchSize += 10;
609                traverser->SetMaxBatchSize(maxBatchSize);
610                break;
611        case '-':
612                maxBatchSize -= 10;
613                if (maxBatchSize < 0) maxBatchSize = 1;
614                traverser->SetMaxBatchSize(maxBatchSize);               
615                break;
616        case '6':
617                assumedVisibleFrames -= 1;
618                if (assumedVisibleFrames < 1) assumedVisibleFrames = 1;
619                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
620                break;
621        case '7':
622                assumedVisibleFrames += 1;
623                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);               
624                break;
625        case 'M':
626        case 'm':
627                useMultiQueries = !useMultiQueries;
628                traverser->SetUseMultiQueries(useMultiQueries);
629                break;
630        case '8':
631                        eightKeyPressed = true;
632                        break;
633        case '9':
634                        nineKeyPressed = true;
635                        break;
636        case 'o':
637        case 'O':
638                useOptimization = !useOptimization;
639                traverser->SetUseOptimization(useOptimization);
640                break;
641        case 'a':
642        case 'A':
643                        leftKeyPressed = true;
644                break;
645        case 'd':
646        case 'D':
647                        rightKeyPressed = true;
648                break;
649        case 'w':
650        case 'W':
651                        upKeyPressed = true;
652                break;
653        case 'x':
654        case 'X':
655                        downKeyPressed = true;
656                break;
657        case 'r':
658        case 'R':
659                {
660                        useRenderQueue = !useRenderQueue;
661                        traverser->SetUseRenderQueue(useRenderQueue);
662                }
663                break;
664        case 'b':
665        case 'B':
666                {
667                        useTightBounds = !useTightBounds;
668                        traverser->SetUseTightBounds(useTightBounds);
669                }
670                break;
671        case '4':
672                if (trianglesPerVirtualLeaf >= 100)
673                        trianglesPerVirtualLeaf -= 100;
674
675                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
676                break;
677        case '5':
678                trianglesPerVirtualLeaf += 100;
679                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
680                break;
681        default:
682                return;
683        }
684
685        glutPostRedisplay();
686}
687
688
689void SpecialKeyUp(int c, int x, int y)
690{
691        switch (c)
692        {
693        case GLUT_KEY_LEFT:
694                leftKeyPressed = false;
695                break;
696        case GLUT_KEY_RIGHT:
697                rightKeyPressed = false;
698                break;
699        case GLUT_KEY_UP:
700                upKeyPressed = false;
701                break;
702        case GLUT_KEY_DOWN:
703                downKeyPressed = false;
704                break;
705        default:
706                return;
707        }
708        //glutPostRedisplay();
709}
710
711
712void KeyUp(unsigned char c, int x, int y)
713{
714        switch (c)
715        {
716        case 'A':
717        case 'a':
718                leftKeyPressed = false;
719                break;
720        case 'D':
721        case 'd':
722                rightKeyPressed = false;
723                break;
724        case 'W':
725        case 'w':
726                upKeyPressed = false;
727                break;
728        case 'X':
729        case 'x':
730                downKeyPressed = false;
731                break;
732        case '8':
733                eightKeyPressed = false;
734                break;
735       
736        case '9':
737                nineKeyPressed = false;
738                break;
739       
740        default:
741                return;
742        }
743        //glutPostRedisplay();
744}
745
746
747void Special(int c, int x, int y)
748{
749        switch(c)
750        {
751        case GLUT_KEY_F1:
752                showHelp = !showHelp;
753                break;
754        case GLUT_KEY_F2:
755                visMode = !visMode;
756                break;
757        case GLUT_KEY_F3:
758                showBoundingVolumes = !showBoundingVolumes;
759                traverser->SetShowBounds(showBoundingVolumes);
760                break;
761        case GLUT_KEY_F4:
762                showStatistics = !showStatistics;
763                break;
764        case GLUT_KEY_F5:
765                showOptions = !showOptions;
766                break;
767        case GLUT_KEY_F6:
768                flyMode = !flyMode;
769                break;
770        case GLUT_KEY_F7:
771                depthPass = !depthPass;
772                traverser->SetUseDepthPass(depthPass);
773                break;
774        case GLUT_KEY_F8:
775                useGlFinish = !useGlFinish;
776                break;
777        case GLUT_KEY_LEFT:
778                {
779                        leftKeyPressed = true;
780                        camera->Pitch(KeyRotationAngle());
781                }
782                break;
783        case GLUT_KEY_RIGHT:
784                {
785                        rightKeyPressed = true;
786                        camera->Pitch(-KeyRotationAngle());
787                }
788                break;
789        case GLUT_KEY_UP:
790                {
791                        upKeyPressed = true;
792                        KeyHorizontalMotion(KeyShift());
793                }
794                break;
795        case GLUT_KEY_DOWN:
796                {
797                        downKeyPressed = true;
798                        KeyHorizontalMotion(-KeyShift());
799                }
800                break;
801        default:
802                return;
803
804        }
805
806        glutPostRedisplay();
807}
808
809#pragma warning( default : 4100 )
810
811
812void Reshape(int w, int h)
813{
814        winAspectRatio = 1.0f;
815
816        glViewport(0, 0, w, h);
817       
818        winWidth = w;
819        winHeight = h;
820
821        if (w) winAspectRatio = (float) h / (float) w;
822
823        glMatrixMode(GL_PROJECTION);
824        glLoadIdentity();
825
826        gluPerspective(fov, 1.0f / winAspectRatio, nearDist, 10.0f * Magnitude(bvh->GetBox().Diagonal()));
827
828        glMatrixMode(GL_MODELVIEW);
829
830        glutPostRedisplay();
831}
832
833
834void Mouse(int button, int state, int x, int y)
835{
836        if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
837        {
838                xEyeBegin = x;
839                yMotionBegin = y;
840
841                glutMotionFunc(LeftMotion);
842        }
843        else if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN))
844        {
845                yEyeBegin = y;
846                yMotionBegin = y;
847
848                glutMotionFunc(RightMotion);
849        }
850        else if ((button == GLUT_MIDDLE_BUTTON) && (state == GLUT_DOWN))
851        {
852                horizontalMotionBegin = x;
853                verticalMotionBegin = y;
854                glutMotionFunc(MiddleMotion);
855        }
856
857        glutPostRedisplay();
858}
859
860
861/**     rotation for left/right mouse drag
862        motion for up/down mouse drag
863*/
864void LeftMotion(int x, int y)
865{
866        Vector3 viewDir = camera->GetDirection();
867        Vector3 pos = camera->GetPosition();
868
869        // don't move in the vertical direction
870        Vector3 horView(viewDir[0], viewDir[1], 0);
871       
872        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
873
874        camera->Pitch(eyeXAngle);
875
876        pos += horView * (yMotionBegin - y) * 0.2f;
877       
878        camera->SetPosition(pos);
879       
880        xEyeBegin = x;
881        yMotionBegin = y;
882
883        glutPostRedisplay();
884}
885
886
887/**     rotation for left / right mouse drag
888        motion for up / down mouse drag
889*/
890void RightMotion(int x, int y)
891{
892        float eyeYAngle = -0.2f *  M_PI * (yEyeBegin - y) / 180.0;
893
894        camera->Yaw(eyeYAngle);
895
896        yEyeBegin = y;
897        glutPostRedisplay();
898}
899
900
901// strafe
902void MiddleMotion(int x, int y)
903{
904        Vector3 viewDir = camera->GetDirection();
905        Vector3 pos = camera->GetPosition();
906
907        // the 90 degree rotated view vector
908        // y zero so we don't move in the vertical
909        Vector3 rVec(viewDir[0], viewDir[1], 0);
910       
911        Matrix4x4 rot = RotationZMatrix(M_PI * 0.5f);
912        rVec = rot * rVec;
913       
914        pos -= rVec * (x - horizontalMotionBegin) * 0.1f;
915        pos[2] += (verticalMotionBegin - y) * 0.1f;
916
917        camera->SetPosition(pos);
918
919        horizontalMotionBegin = x;
920        verticalMotionBegin = y;
921
922        glutPostRedisplay();
923}
924
925
926void InitExtensions(void)
927{
928        GLenum err = glewInit();
929
930        if (GLEW_OK != err)
931        {
932                // problem: glewInit failed, something is seriously wrong
933                fprintf(stderr,"Error: %s\n", glewGetErrorString(err));
934                exit(1);
935        }
936        if  (!GLEW_ARB_occlusion_query)
937        {
938                printf("I require the GL_ARB_occlusion_query to work.\n");
939                exit(1);
940        }
941}
942
943
944void Begin2D(void)
945{
946        glDisable(GL_LIGHTING);
947        glDisable(GL_DEPTH_TEST);
948
949        glPushMatrix();
950        glLoadIdentity();
951
952        glMatrixMode(GL_PROJECTION);
953        glPushMatrix();
954        glLoadIdentity();
955        gluOrtho2D(0, winWidth, winHeight, 0);
956}
957
958
959void End2D(void)
960{
961        glPopMatrix();
962        glMatrixMode(GL_MODELVIEW);
963        glPopMatrix();
964
965        glEnable(GL_LIGHTING);
966        glEnable(GL_DEPTH_TEST);
967}
968
969
970void Output(int x, int y, const char *string)
971{
972        if (string != 0)
973        {
974                size_t len, i;
975                glRasterPos2f(x, y);
976                len = strlen(string);
977               
978                for (i = 0; i < len; ++ i)
979                {
980                        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, string[i]);
981                }
982        }
983}
984
985
986// displays the visualisation of culling algorithm
987void DisplayVisualization()
988{
989        visualization->SetFrameId(traverser->GetCurrentFrameId());
990       
991        Begin2D();
992        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
993        glEnable(GL_BLEND);
994        glColor4f(0.0,0.0,0.0,0.5);
995
996        glRecti(winWidth, 0, winWidth - winWidth / 3, winHeight / 3);
997        glDisable(GL_BLEND);
998        End2D();
999       
1000       
1001        AxisAlignedBox3 box = bvh->GetBox();
1002
1003        const float xoffs = box.Size().x * 0.5f;
1004        const float yoffs = box.Size().y * 0.5f;
1005
1006        Vector3 pos = camera->GetPosition();
1007
1008        Vector3 vizpos = Vector3(box.Min().x, box.Min().y + 700, box.Min().z + box.Size().z * 50);
1009       
1010        visCamera->SetPosition(vizpos);
1011       
1012        glViewport(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth / 3, winHeight / 3);
1013
1014        glMatrixMode(GL_PROJECTION);
1015        glLoadIdentity();
1016       
1017        glOrtho(-xoffs, xoffs, -xoffs, xoffs, 0.0f, box.Size().z * 100.0f);
1018
1019        glMatrixMode(GL_MODELVIEW);
1020
1021        visCamera->SetupCameraView();
1022
1023        Matrix4x4 rotZ = RotationZMatrix(-camera->GetPitch());
1024        glMultMatrixf((float *)rotZ.x);
1025
1026        glTranslatef(-pos.x, -pos.y, -pos.z);
1027
1028
1029        GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
1030        glLightfv(GL_LIGHT0, GL_POSITION, position);
1031
1032        GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
1033        glLightfv(GL_LIGHT1, GL_POSITION, position1);
1034
1035        glClear(GL_DEPTH_BUFFER_BIT);
1036
1037
1038        ////////////
1039        //-- visualization of the occlusion culling
1040
1041        visualization->Render();
1042       
1043        // reset vp
1044        glViewport(0, 0, winWidth, winHeight);
1045}
1046
1047
1048// cleanup routine after the main loop
1049void CleanUp()
1050{
1051        DEL_PTR(traverser);
1052        DEL_PTR(sceneQuery);
1053        DEL_PTR(bvh);
1054        DEL_PTR(visualization);
1055        DEL_PTR(camera);
1056        DEL_PTR(loader);
1057        DEL_PTR(renderQueue);
1058}
1059
1060
1061// this function inserts a dezimal point after each 1000
1062void CalcDecimalPoint(string &str, int d)
1063{
1064        vector<int> numbers;
1065        char hstr[100];
1066
1067        while (d != 0)
1068        {
1069                numbers.push_back(d % 1000);
1070                d /= 1000;
1071        }
1072
1073        // first element without leading zeros
1074        if (numbers.size() > 0)
1075        {
1076                sprintf(hstr, "%d", numbers.back());
1077                str.append(hstr);
1078        }
1079       
1080        for (int i = (int)numbers.size() - 2; i >= 0; i--)
1081        {
1082                sprintf(hstr, ",%03d", numbers[i]);
1083                str.append(hstr);
1084        }
1085}
1086
1087
1088void DisplayStats()
1089{
1090        char *msg[] = {"Frustum Culling", "Stop and Wait",
1091                                    "CHC", "CHC ++"};
1092
1093        char msg2[400];
1094        char msg3[200];
1095        char msg4[200];
1096        char msg5[200];
1097        char msg6[200];
1098        char msg7[200];
1099        char msg8[200];
1100
1101
1102        static double renderTime = algTime;
1103        const float expFactor = 0.3f;
1104
1105        //if (useRenderQueue) cout << "rq overhead: " << 1e6f * rqTimer.TotalTime() << " ms" << endl;
1106
1107        // if some strange render time spike happened in this frame => don't count
1108        if (algTime < 1000) renderTime = algTime * expFactor + (1.0f - expFactor) * algTime;
1109        //renderTime = 1e3f * (elapsedTime * expFactor + (1.0f - expFactor) * elapsedTime);
1110
1111        accumulatedTime += elapsedTime * 1e3f;
1112
1113        if (accumulatedTime > 500) // update every fraction of a second
1114        {       
1115                accumulatedTime = 0;
1116                if (renderTime) fps = 1e3f / (float)renderTime;
1117
1118                renderedObjects = traverser->GetStats().mNumRenderedGeometry;
1119                renderedNodes = traverser->GetStats().mNumRenderedNodes;
1120                renderedTriangles = traverser->GetStats().mNumRenderedTriangles;
1121
1122                traversedNodes = traverser->GetStats().mNumTraversedNodes;
1123                frustumCulledNodes = traverser->GetStats().mNumFrustumCulledNodes;
1124                queryCulledNodes = traverser->GetStats().mNumQueryCulledNodes;
1125                issuedQueries = traverser->GetStats().mNumIssuedQueries;
1126                stateChanges = traverser->GetStats().mNumStateChanges;
1127                numBatches = traverser->GetStats().mNumBatches;
1128        }
1129
1130        sprintf(msg2, "assumed visible frames: %4d, max batch size: %4d",
1131                      assumedVisibleFrames, maxBatchSize);
1132
1133        sprintf(msg3, "multiqueries: %d, tight bounds: %d, render queue: %d, depth pass: %d, glFinish: %d",
1134                      useMultiQueries, useTightBounds, useRenderQueue, depthPass, useGlFinish);
1135
1136        string str;
1137        string str2;
1138
1139        CalcDecimalPoint(str, renderedTriangles);
1140        CalcDecimalPoint(str2, bvh->GetBvhStats().mTriangles);
1141
1142        sprintf(msg4, "rendered nodes: %6d (of %6d), rendered triangles: %s (of %s)",
1143                          renderedNodes, bvh->GetNumVirtualNodes(), str.c_str(), str2.c_str());
1144
1145        sprintf(msg5, "traversed: %5d, frustum culled: %5d, query culled: %5d",
1146                          traversedNodes, frustumCulledNodes, queryCulledNodes);
1147
1148        sprintf(msg6, "issued queries: %5d, state changes: %5d, render batches: %5d", issuedQueries, stateChanges, numBatches);
1149
1150        sprintf(msg8, "triangles per virtual leaf: %5d", trianglesPerVirtualLeaf);
1151
1152        sprintf(msg7, "fps: %6.1f", fps);
1153
1154
1155        Begin2D();
1156       
1157        if(showHelp)
1158        {       
1159                DrawHelpMessage();
1160        }
1161        else
1162        {
1163                glColor3f(1.0f, 1.0f, 1.0f);
1164                //glColor3f(1.0f, 0.0f, 0.0f);
1165                Output(850, 30, msg[renderMode]);
1166
1167               
1168                if (showStatistics)
1169                {
1170                        Output(20, 30, msg4);
1171                        Output(20, 60, msg5);
1172                        Output(20, 90, msg6);
1173                        Output(20, 120, msg7);
1174                }
1175
1176                if (showOptions)
1177                {
1178                        Output(20, 150, msg2);
1179                        Output(20, 180, msg3);
1180                        Output(20, 210, msg8);
1181                }
1182        }
1183
1184        End2D();
1185}       
1186
1187
1188void RenderSky()
1189{
1190        SceneEntityContainer::const_iterator sit, sit_end = skyGeometry.end();
1191
1192        for (sit = skyGeometry.begin(); sit != sit_end; ++ sit)
1193                (*sit)->Render(&state);
1194}
1195
1196
1197void RenderVisibleObjects()
1198{
1199        state.SetDepthPass(false);
1200        state.Reset();
1201
1202        glEnable(GL_LIGHTING);
1203        glDepthFunc(GL_LEQUAL);
1204
1205        //cout << "visible: " << (int)traverser->GetVisibleObjects().size() << endl;
1206
1207        SceneEntityContainer::const_iterator sit,
1208                sit_end = traverser->GetVisibleObjects().end();
1209
1210        for (sit = traverser->GetVisibleObjects().begin(); sit != sit_end; ++ sit)
1211                renderQueue->Enqueue(*sit);
1212               
1213        renderQueue->Apply();
1214
1215        glDepthFunc(GL_LESS);
1216}
1217
1218
1219void PlaceViewer(const Vector3 &oldPos)
1220{
1221        Vector3 playerPos = camera->GetPosition();
1222
1223        bool validIntersect = sceneQuery->CalcIntersection(playerPos);
1224
1225        if (validIntersect &&
1226                (( playerPos.z - oldPos.z) < bvh->GetBox().Size(2) * 1e-1f))
1227        {
1228                camera->SetPosition(playerPos);
1229        }
1230}
Note: See TracBrowser for help on using the repository browser.