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

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