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

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