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

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