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

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