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

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