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

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