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

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