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

Revision 2802, 26.7 KB checked in by mattausch, 16 years ago (diff)

worked on renderqueue

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;
107
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        visCamera->SetNear(0.0f);
168        visCamera->Yaw(.5 * M_PI);
169
170        renderQueue = new RenderQueue(&state, camera);
171
172        glutInitWindowSize(winWidth, winHeight);
173        glutInit(&argc, argv);
174        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
175
176        glutCreateWindow("FriendlyCulling");
177
178        glutDisplayFunc(Display);
179        glutKeyboardFunc(KeyBoard);
180        glutSpecialFunc(Special);
181        glutReshapeFunc(Reshape);
182        glutMouseFunc(Mouse);
183        glutIdleFunc(Display);
184        glutKeyboardUpFunc(KeyUp);
185        glutSpecialUpFunc(SpecialKeyUp);
186        glutIgnoreKeyRepeat(true);
187
188        InitExtensions();
189        InitGLstate();
190
191        LeftMotion(0, 0);
192        MiddleMotion(0, 0);
193
194
195        loader = new ResourceManager();
196
197        //const string filename("data/city/model/city.dem");
198        const string filename = string(model_path + "city.dem");
199
200        if (loader->Load(filename, sceneEntities))
201                cout << "scene " << filename << " loaded" << endl;
202        else
203        {
204                cerr << "loading scene " << filename << " failed" << endl;
205                CleanUp();
206                exit(0);
207        }
208
209        SceneEntityContainer dummy;
210
211        const string envname = string(model_path + "env.dem");
212
213        if (loader->Load(envname, skyGeometry))
214                cout << "sky box " << filename << " loaded" << endl;
215        else
216        {
217                cerr << "loading sky box " << filename << " failed" << endl;
218                CleanUp();
219                exit(0);
220        }
221
222
223        const string bvh_filename = string(model_path + "city.bvh");
224        BvhLoader bvhLoader;
225        bvh = bvhLoader.Load(bvh_filename, sceneEntities);
226        //bvh = bvhLoader.Load("data/city/model/city.bvh", sceneEntities);
227
228        if (!bvh)
229        {
230                cerr << "loading bvh " << bvh_filename << " failed" << endl;
231                CleanUp();
232                exit(0);
233        }
234
235        bvh->SetCamera(camera);
236
237        ResetTraverser();
238
239        //camera->SetDirection(Vector3(0.961829f, 0.273652f, 0.0f));
240        camera->Pitch(-M_PI * 0.5);
241        camera->SetPosition(Vector3(483.398f, 242.364f, 186.078f));
242
243        visualization = new Visualization(bvh, camera, NULL, &state);
244
245        sceneQuery = new SceneQuery(bvh->GetBox(), traverser);
246
247
248        glutMainLoop();
249
250        // clean up
251        CleanUp();
252
253        return 0;
254}
255
256
257void InitGLstate(void)
258{
259        glClearColor(0.5f, 0.5f, 0.8f, 0.0f);
260       
261        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
262        glPixelStorei(GL_PACK_ALIGNMENT,1);
263       
264        glDepthFunc(GL_LESS);
265        glEnable(GL_DEPTH_TEST);
266
267        SetupLighting();
268
269        glColor3f(1.0f, 1.0f, 1.0f);
270        glShadeModel(GL_SMOOTH);
271       
272        glMaterialf(GL_FRONT, GL_SHININESS, 64);
273        glEnable(GL_NORMALIZE);
274               
275        //glEnable(GL_ALPHA_TEST);
276        glDisable(GL_ALPHA_TEST);
277        glAlphaFunc(GL_GEQUAL, 0.5f);
278
279        glFrontFace(GL_CCW);
280        glCullFace(GL_BACK);
281        glEnable(GL_CULL_FACE);
282        //glDisable(GL_CULL_FACE);
283        glDisable(GL_TEXTURE_2D);
284
285        GLfloat ambientColor[] = {0.5, 0.5, 0.5, 1.0};
286        GLfloat diffuseColor[] = {1.0, 0.0, 0.0, 1.0};
287        GLfloat specularColor[] = {0.0, 0.0, 0.0, 1.0};
288
289        glMaterialfv(GL_FRONT, GL_AMBIENT, ambientColor);
290        glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor);
291        glMaterialfv(GL_FRONT, GL_SPECULAR, specularColor);
292
293        glDepthFunc(GL_LESS);
294}
295
296
297void DrawHelpMessage(void)
298{
299        const char *message[] =
300        {
301                "Help information",
302                "",
303                "'F1'           - shows/dismisses this message",
304                "'F2'           - shows/hides bird eye view",
305                "'F3'           - shows/hides bounds (boxes or tight bounds)",
306                "'F4'           - shows/hides statistics",
307                "'F5',          - toggles between fly / walkmode",
308                "'F6',          - shows/hides parameters",
309                "'F7',          - depth pass",
310                "'SPACE'        - cycles through occlusion culling algorithms",
311                "",
312                "'MOUSE-LEFT'   - turn left/right, move forward/backward",
313                "'MOUSE-RIGHT'  - turn left/right, move forward/backward",
314                "'MOUSE-MIDDLE' - move up/down, left/right",
315                "'CURSOR UP'    - move forward",
316                "'CURSOR BACK'  - move backward",
317                "'CURSOR RIGHT' - turn right",
318                "'CURSOR LEFT'  - turn left",
319                "",
320                "'-'            - decreases max batch size",
321                "'+'            - increases max batch size",
322                "'4'            - decrease triangles per virtual leaf (sets depth of bvh)",
323                "'5'            - increase triangles per virtual leaf (sets depth of bvh)",
324                "'6'            - decrease assumed visible frames",
325                "'7'            - increase assumed visible frames",
326                "'8'            - downward motion",
327                "'9'            - upward motion",
328                "",
329                "'R'            - use render queue",
330                "'B'            - use tight bounds",
331                "'M'            - use multiqueries",
332                "'O'            - use CHC optimization (geometry queries for leaves)",
333                0,
334        };
335       
336       
337        int x = 40, y = 60;
338
339        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
340        glEnable(GL_BLEND);
341        glColor4f(0.0f, 1.0f , 0.0f, 0.2f);  // 20% green.
342
343        // Drawn clockwise because the flipped Y axis flips CCW and CW.
344        glRecti(winWidth - 30, 30, 30, winHeight - 30);
345       
346        glDisable(GL_BLEND);
347       
348        glColor3f(1.0f, 1.0f, 1.0f);
349       
350        for(int i = 0; message[i] != 0; i++)
351        {
352                if(message[i][0] == '\0')
353                {
354                        y += 15;
355                }
356                else
357                {
358                        Output(x, y, message[i]);
359                        y += 20;
360                }
361        }
362}
363
364
365void ResetTraverser()
366{
367        DEL_PTR(traverser);
368
369        bvh->ResetNodeClassifications();
370
371        switch (renderMode)
372        {
373        case RenderTraverser::CULL_FRUSTUM:
374                traverser = new FrustumCullingTraverser();
375                break;
376        case RenderTraverser::STOP_AND_WAIT:
377                traverser = new StopAndWaitTraverser();
378                break;
379        case RenderTraverser::CHC:
380                traverser = new CHCTraverser();
381                break;
382        case RenderTraverser::CHCPLUSPLUS:
383                traverser = new CHCPlusPlusTraverser();
384                break;
385       
386        default:
387                traverser = new FrustumCullingTraverser();
388        }
389
390        traverser->SetCamera(camera);
391        traverser->SetHierarchy(bvh);
392        traverser->SetRenderQueue(renderQueue);
393        traverser->SetRenderState(&state);
394        traverser->SetUseOptimization(useOptimization);
395        traverser->SetUseRenderQueue(useRenderQueue);
396        traverser->SetVisibilityThreshold(threshold);
397        traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
398        traverser->SetMaxBatchSize(maxBatchSize);
399        traverser->SetUseMultiQueries(useMultiQueries);
400        traverser->SetUseTightBounds(useTightBounds);
401        traverser->SetUseDepthPass(depthPass);
402        traverser->SetRenderQueue(renderQueue);
403}
404
405
406void SetupLighting()
407{
408        glEnable(GL_LIGHTING);
409        glEnable(GL_LIGHT0);
410        //glEnable(GL_LIGHT1);
411        glDisable(GL_LIGHT1);
412
413        //GLfloat ambient[] = {0.5, 0.5, 0.5, 1.0};
414        GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
415        GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0};
416        GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
417           
418        GLfloat lmodel_ambient[] = {0.5f, 0.5f, 0.5f, 1.0f};
419        //GLfloat lmodel_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
420
421        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
422        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
423        glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
424
425        GLfloat position[] = {1.0, 1.0, 1.0, 0.0};
426        glLightfv(GL_LIGHT0, GL_POSITION, position);
427
428
429        ////////////
430        //-- second light
431
432        GLfloat ambient1[] = {0.5, 0.5, 0.5, 1.0};
433        //GLfloat diffuse1[] = {1.0, 1.0, 1.0, 1.0};
434        GLfloat diffuse1[] = {0.5, 0.5, 0.5, 1.0};
435        GLfloat specular1[] = {0.5, 0.5, 0.5, 1.0};
436
437        glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1);
438        glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1);
439        glLightfv(GL_LIGHT1, GL_SPECULAR, specular1);
440       
441        GLfloat position1[] = {0.0, 1.0, 0.0, 1.0};
442        glLightfv(GL_LIGHT1, GL_POSITION, position1);
443
444        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
445        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
446        //glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
447        //glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);
448        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SINGLE_COLOR_EXT);
449}
450
451
452void SetupEyeView()
453{
454        glMatrixMode(GL_PROJECTION);
455        glLoadIdentity();
456
457        gluPerspective(fov, 1.0f / winAspectRatio, nearDist, 10.0f * Magnitude(bvh->GetBox().Diagonal()));
458
459        glMatrixMode(GL_MODELVIEW);
460        glLoadIdentity();
461        camera->SetupCameraView();
462
463        GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
464        glLightfv(GL_LIGHT0, GL_POSITION, position);
465
466        GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
467        glLightfv(GL_LIGHT1, GL_POSITION, position1);
468}
469
470
471void KeyHorizontalMotion(float shift)
472{
473        Vector3 hvec = camera->GetDirection();
474        hvec.z = 0;
475
476        Vector3 pos = camera->GetPosition();
477        pos += hvec * shift;
478       
479        camera->SetPosition(pos);
480}
481
482
483void KeyVerticalMotion(float shift)
484{
485        Vector3 uvec = Vector3(0, 0, shift);
486
487        Vector3 pos = camera->GetPosition();
488        pos += uvec;
489       
490        camera->SetPosition(pos);
491}
492
493
494
495void Display()
496{       
497        PerfTimer frameTimer, algTimer;
498        frameTimer.Start();
499
500        Vector3 oldPos = camera->GetPosition();
501
502        if (leftKeyPressed)
503                camera->Pitch(KeyRotationAngle());
504        if (rightKeyPressed)
505                camera->Pitch(-KeyRotationAngle());
506        if (upKeyPressed)
507                KeyHorizontalMotion(KeyShift());
508        if (downKeyPressed)
509                KeyHorizontalMotion(-KeyShift());
510        if (eightKeyPressed)
511                KeyVerticalMotion(-KeyShift());
512        if (nineKeyPressed)
513                KeyVerticalMotion(KeyShift());
514
515        // place view on ground
516        if (!flyMode) PlaceViewer(oldPos);
517
518        // note: have to flush queue in order to get reliable timings
519        // for optimal performance, remove this
520        //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
574       
575        // note: have to flush queue in order to get reliable timings
576        // for optimal performance, remove this
577        //glFinish();
578        algTime = algTimer.Elapsedms();
579
580        ///////////
581
582        if (visMode) DisplayVisualization();
583       
584        DisplayStats();
585
586        glutSwapBuffers();
587
588        elapsedTime = frameTimer.Elapsed();
589}
590
591
592#pragma warning( disable : 4100 )
593void KeyBoard(unsigned char c, int x, int y)
594{
595        switch(c)
596        {
597        case 27:
598                CleanUp();
599                exit(0);
600                break;
601        case 32: //space
602                renderMode = (renderMode + 1) % RenderTraverser::NUM_TRAVERSAL_TYPES;
603                ResetTraverser();
604                break;
605        case 'h':
606        case 'H':
607                showHelp = !showHelp;
608                break;
609        case '+':
610                maxBatchSize += 10;
611                traverser->SetMaxBatchSize(maxBatchSize);
612                break;
613        case '-':
614                maxBatchSize -= 10;
615                if (maxBatchSize < 0) maxBatchSize = 1;
616                traverser->SetMaxBatchSize(maxBatchSize);               
617                break;
618        case '6':
619                assumedVisibleFrames -= 1;
620                if (assumedVisibleFrames < 1) assumedVisibleFrames = 1;
621                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
622                break;
623        case '7':
624                assumedVisibleFrames += 1;
625                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);               
626                break;
627        case 'M':
628        case 'm':
629                useMultiQueries = !useMultiQueries;
630                traverser->SetUseMultiQueries(useMultiQueries);
631                break;
632        case '8':
633                        eightKeyPressed = true;
634                        break;
635        case '9':
636                        nineKeyPressed = true;
637                        break;
638        case 'o':
639        case 'O':
640                useOptimization = !useOptimization;
641                traverser->SetUseOptimization(useOptimization);
642                break;
643        case 'a':
644        case 'A':
645                        leftKeyPressed = true;
646                break;
647        case 'd':
648        case 'D':
649                        rightKeyPressed = true;
650                break;
651        case 'w':
652        case 'W':
653                        upKeyPressed = true;
654                break;
655        case 'x':
656        case 'X':
657                        downKeyPressed = true;
658                break;
659        case 'r':
660        case 'R':
661                {
662                        useRenderQueue = !useRenderQueue;
663                        traverser->SetUseRenderQueue(useRenderQueue);
664                }
665                break;
666        case 'b':
667        case 'B':
668                {
669                        useTightBounds = !useTightBounds;
670                        traverser->SetUseTightBounds(useTightBounds);
671                }
672                break;
673        case '4':
674                if (trianglesPerVirtualLeaf >= 100)
675                        trianglesPerVirtualLeaf -= 100;
676
677                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
678                break;
679        case '5':
680                trianglesPerVirtualLeaf += 100;
681                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
682                break;
683        default:
684                return;
685        }
686
687        glutPostRedisplay();
688}
689
690
691void SpecialKeyUp(int c, int x, int y)
692{
693        switch (c)
694        {
695        case GLUT_KEY_LEFT:
696                leftKeyPressed = false;
697                break;
698        case GLUT_KEY_RIGHT:
699                rightKeyPressed = false;
700                break;
701        case GLUT_KEY_UP:
702                upKeyPressed = false;
703                break;
704        case GLUT_KEY_DOWN:
705                downKeyPressed = false;
706                break;
707        default:
708                return;
709        }
710        //glutPostRedisplay();
711}
712
713
714void KeyUp(unsigned char c, int x, int y)
715{
716        switch (c)
717        {
718        case 'A':
719        case 'a':
720                leftKeyPressed = false;
721                break;
722        case 'D':
723        case 'd':
724                rightKeyPressed = false;
725                break;
726        case 'W':
727        case 'w':
728                upKeyPressed = false;
729                break;
730        case 'X':
731        case 'x':
732                downKeyPressed = false;
733                break;
734        case '8':
735                eightKeyPressed = false;
736                break;
737       
738        case '9':
739                nineKeyPressed = false;
740                break;
741       
742        default:
743                return;
744        }
745        //glutPostRedisplay();
746}
747
748
749void Special(int c, int x, int y)
750{
751        switch(c)
752        {
753        case GLUT_KEY_F1:
754                showHelp = !showHelp;
755                break;
756        case GLUT_KEY_F2:
757                visMode = !visMode;
758                break;
759        case GLUT_KEY_F3:
760                showBoundingVolumes = !showBoundingVolumes;
761                traverser->SetShowBounds(showBoundingVolumes);
762                break;
763        case GLUT_KEY_F4:
764                showStatistics = !showStatistics;
765                break;
766        case GLUT_KEY_F5:
767                showOptions = !showOptions;
768                break;
769        case GLUT_KEY_F6:
770                flyMode = !flyMode;
771                break;
772        case GLUT_KEY_F7:
773                depthPass = !depthPass;
774                traverser->SetUseDepthPass(depthPass);
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 / 4, winHeight / 3);
996        glDisable(GL_BLEND);
997        End2D();
998       
999       
1000        AxisAlignedBox3 box = bvh->GetBox();
1001
1002        const float xoffs = box.Size().x * 0.5f;
1003        const float yoffs = box.Size().y * 0.5f;
1004
1005        Vector3 vizpos = Vector3(box.Center().x, box.Center().y, box.Max().z);
1006        visCamera->SetPosition(vizpos);
1007       
1008        glViewport(winWidth - winWidth / 4, winHeight - winHeight / 3, winWidth / 4, winHeight / 3);
1009
1010        glMatrixMode(GL_PROJECTION);
1011        glLoadIdentity();
1012       
1013        glOrtho(-xoffs, xoffs, -yoffs, yoffs, 0.0f, box.Size().z);
1014
1015        glMatrixMode(GL_MODELVIEW);
1016
1017        visCamera->SetupCameraView();
1018       
1019        GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
1020        glLightfv(GL_LIGHT0, GL_POSITION, position);
1021
1022        GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
1023        glLightfv(GL_LIGHT1, GL_POSITION, position1);
1024
1025        glClear(GL_DEPTH_BUFFER_BIT);
1026
1027        ////////////
1028        //-- visualization of the occlusion culling
1029
1030        visualization->Render();
1031       
1032        glViewport(0, 0, winWidth, winHeight);
1033}
1034
1035
1036// cleanup routine after the main loop
1037void CleanUp()
1038{
1039        DEL_PTR(traverser);
1040        DEL_PTR(sceneQuery);
1041        DEL_PTR(bvh);
1042        DEL_PTR(visualization);
1043        DEL_PTR(camera);
1044        DEL_PTR(loader);
1045        DEL_PTR(renderQueue);
1046}
1047
1048
1049// this function inserts a dezimal point after each 1000
1050void CalcDecimalPoint(string &str, int d)
1051{
1052        vector<int> numbers;
1053        char hstr[100];
1054
1055        while (d != 0)
1056        {
1057                numbers.push_back(d % 1000);
1058                d /= 1000;
1059        }
1060
1061        // first element without leading zeros
1062        if (numbers.size() > 0)
1063        {
1064                sprintf(hstr, "%d", numbers.back());
1065                str.append(hstr);
1066        }
1067       
1068        for (int i = (int)numbers.size() - 2; i >= 0; i--)
1069        {
1070                sprintf(hstr, ",%03d", numbers[i]);
1071                str.append(hstr);
1072        }
1073}
1074
1075
1076void DisplayStats()
1077{
1078        char *msg[] = {"Frustum Culling", "Stop and Wait",
1079                                    "CHC", "CHC ++"};
1080
1081        char msg2[400];
1082        char msg3[200];
1083        char msg4[200];
1084        char msg5[200];
1085        char msg6[200];
1086        char msg7[200];
1087        char msg8[200];
1088
1089
1090        static double renderTime = algTime;
1091        const float expFactor = 0.3f;
1092
1093        //if (useRenderQueue) cout << "rq overhead: " << 1e6f * rqTimer.TotalTime() << " ms" << endl;
1094
1095        // if some strange render time spike happened in this frame => don't count
1096        //if (algTime < 1000) renderTime = algTime * expFactor + (1.0f - expFactor) * algTime;
1097
1098        renderTime = 1e3f * (elapsedTime * expFactor + (1.0f - expFactor) * elapsedTime);
1099
1100        accumulatedTime += elapsedTime * 1e3f;
1101
1102        if (accumulatedTime > 500) // update every fraction of a second
1103        {       
1104                accumulatedTime = 0;
1105                if (renderTime) fps = 1e3f / (float)renderTime;
1106
1107                renderedObjects = traverser->GetStats().mNumRenderedGeometry;
1108                renderedNodes = traverser->GetStats().mNumRenderedNodes;
1109                renderedTriangles = traverser->GetStats().mNumRenderedTriangles;
1110
1111                traversedNodes = traverser->GetStats().mNumTraversedNodes;
1112                frustumCulledNodes = traverser->GetStats().mNumFrustumCulledNodes;
1113                queryCulledNodes = traverser->GetStats().mNumQueryCulledNodes;
1114                issuedQueries = traverser->GetStats().mNumIssuedQueries;
1115                stateChanges = traverser->GetStats().mNumStateChanges;
1116                numBatches = traverser->GetStats().mNumBatches;
1117        }
1118
1119        sprintf(msg2, "assumed visible frames: %4d, max batch size: %4d",
1120                      assumedVisibleFrames, maxBatchSize);
1121
1122        sprintf(msg3, "render queue: %d, depth pass: %d, multiqueries: %d, tight bounds: %d",
1123                      useRenderQueue, depthPass, useMultiQueries, useTightBounds);
1124
1125        string str;
1126        string str2;
1127
1128        CalcDecimalPoint(str, renderedTriangles);
1129        CalcDecimalPoint(str2, bvh->GetBvhStats().mTriangles);
1130
1131        sprintf(msg4, "rendered nodes: %6d (of %6d), rendered triangles: %s (of %s)",
1132                          renderedNodes, bvh->GetNumVirtualNodes(), str.c_str(), str2.c_str());
1133
1134        sprintf(msg5, "traversed: %5d, frustum culled: %5d, query culled: %5d",
1135                          traversedNodes, frustumCulledNodes, queryCulledNodes);
1136
1137        sprintf(msg6, "issued queries: %5d, state changes: %5d, render batches: %5d", issuedQueries, stateChanges, numBatches);
1138
1139        sprintf(msg8, "triangles per virtual leaf: %5d", trianglesPerVirtualLeaf);
1140
1141        sprintf(msg7, "fps: %6.1f", fps);
1142
1143
1144        Begin2D();
1145       
1146        if(showHelp)
1147        {       
1148                DrawHelpMessage();
1149        }
1150        else
1151        {
1152                glColor3f(1.0f, 1.0f, 1.0f);
1153                //glColor3f(1.0f, 0.0f, 0.0f);
1154                Output(850, 30, msg[renderMode]);
1155
1156               
1157                if (showStatistics)
1158                {
1159                        Output(20, 30, msg4);
1160                        Output(20, 60, msg5);
1161                        Output(20, 90, msg6);
1162                        Output(20, 120, msg7);
1163                }
1164
1165                if (showOptions)
1166                {
1167                        Output(20, 150, msg2);
1168                        Output(20, 180, msg3);
1169                        Output(20, 210, msg8);
1170                }
1171        }
1172
1173        End2D();
1174}       
1175
1176
1177void RenderSky()
1178{
1179        SceneEntityContainer::const_iterator sit, sit_end = skyGeometry.end();
1180
1181        for (sit = skyGeometry.begin(); sit != sit_end; ++ sit)
1182                (*sit)->Render(&state);
1183}
1184
1185
1186void RenderVisibleObjects()
1187{
1188        state.SetDepthPass(false);
1189        state.Reset();
1190
1191        glEnable(GL_LIGHTING);
1192        glDepthFunc(GL_LEQUAL);
1193
1194        //cout << "visible: " << (int)traverser->GetVisibleObjects().size() << endl;
1195
1196        SceneEntityContainer::const_iterator sit,
1197                sit_end = traverser->GetVisibleObjects().end();
1198
1199        for (sit = traverser->GetVisibleObjects().begin(); sit != sit_end; ++ sit)
1200                renderQueue->Enqueue(*sit);
1201               
1202        renderQueue->Apply();
1203
1204        glDepthFunc(GL_LESS);
1205}
1206
1207
1208void PlaceViewer(const Vector3 &oldPos)
1209{
1210        Vector3 playerPos = camera->GetPosition();
1211
1212        bool validIntersect = sceneQuery->CalcIntersection(playerPos);
1213
1214        if (validIntersect &&
1215                (( playerPos.z - oldPos.z) < bvh->GetBox().Size(2) * 1e-1f))
1216        {
1217                camera->SetPosition(playerPos);
1218        }
1219}
Note: See TracBrowser for help on using the repository browser.