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

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