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

Revision 2800, 24.7 KB checked in by mattausch, 16 years ago (diff)

friendly culling debug version with timers, no materials

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