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

Revision 2874, 40.4 KB checked in by mattausch, 16 years ago (diff)

implemented glob-illum solution

Line 
1// occquery.cpp : Defines the entry point for the console application.
2//
3#include "glInterface.h"
4#include <math.h>
5#include <time.h>
6#include "common.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#include "Material.h"
26#include <Cg/cg.h>
27#include <Cg/cgGL.h>
28#include "glfont2.h"
29#include "PerformanceGraph.h"
30#include "Environment.h"
31#include "Halton.h"
32#include "Transform3.h"
33#include "SampleGenerator.h"
34#include "FrameBufferObject.h"
35#include "SsaoShader.h"
36#include "DeferredShader.h"
37
38
39using namespace std;
40using namespace CHCDemoEngine;
41
42
43static Environment env;
44
45
46/////////////
47//-- fbos
48
49FrameBufferObject *fbo;
50
51bool isFirstTexture = true;
52
53GLuint fontTex;
54
55/// the renderable scene geometry
56SceneEntityContainer sceneEntities;
57// traverses and renders the hierarchy
58RenderTraverser *traverser = NULL;
59/// the hierarchy
60Bvh *bvh = NULL;
61/// handles scene loading
62ResourceManager *loader = NULL;
63/// the scene camera
64Camera *camera = NULL;
65/// the scene camera
66Camera *visCamera = NULL;
67/// the visualization
68Visualization *visualization = NULL;
69/// the current render state
70RenderState state;
71/// the rendering algorithm
72int renderMode = RenderTraverser::CHCPLUSPLUS;
73// eye near plane distance
74float nearDist = 0.2f;
75/// the field of view
76float fov = 50.0f;
77/// the pixel threshold where a node is still considered invisible
78int threshold;
79
80int assumedVisibleFrames = 10;
81int maxBatchSize = 50;
82
83int trianglesPerVirtualLeaf = INITIAL_TRIANGLES_PER_VIRTUAL_LEAVES;
84
85SceneQuery *sceneQuery = NULL;
86RenderQueue *renderQueue = NULL;
87
88/// these values get scaled with the frame rate
89static float keyForwardMotion = 30.0f;
90static float keyRotation = 1.5f;
91
92/// elapsed time in milliseconds
93double elapsedTime = 1000.0f;
94double algTime = 1000.0f;
95
96static int winWidth = 1024;
97static int winHeight = 768;
98static float winAspectRatio = 1.0f;
99
100double accumulatedTime = 1000;
101float fps = 1e3f;
102
103float myfar = 0;
104
105glfont::GLFont myfont;
106
107// rendertexture
108static int texWidth = 1024;
109static int texHeight = 768;
110
111//static int texWidth = 512;
112//static int texHeight = 384;
113
114//static int texWidth = 2048;
115//static int texHeight = 2048;
116
117int renderedObjects = 0;
118int renderedNodes = 0;
119int renderedTriangles = 0;
120
121int issuedQueries = 0;
122int traversedNodes = 0;
123int frustumCulledNodes = 0;
124int queryCulledNodes = 0;
125int stateChanges = 0;
126int numBatches = 0;
127
128bool showHelp = false;
129bool showStatistics = false;
130bool showOptions = true;
131bool showBoundingVolumes = false;
132bool visMode = false;
133
134// mouse navigation state
135int xEyeBegin = 0;
136int yEyeBegin = 0;
137int yMotionBegin = 0;
138int verticalMotionBegin = 0;
139int horizontalMotionBegin = 0;
140
141bool useOptimization = false;
142bool useTightBounds = true;
143bool useRenderQueue = true;
144bool useMultiQueries = true;
145bool flyMode = true;
146
147SceneEntityContainer skyGeometry;
148
149bool leftKeyPressed = false;
150bool rightKeyPressed = false;
151bool upKeyPressed = false;
152bool downKeyPressed = false;
153bool descendKeyPressed = false;
154bool ascendKeyPressed = false;
155
156bool useSsao = false;
157static float ssaoExpFactor = 0.1f;
158
159bool showAlgorithmTime = false;
160
161GLubyte *randomNormals = NULL;
162
163PerfTimer frameTimer, algTimer;
164
165int renderType = RenderState::FIXED;
166
167PerformanceGraph *perfGraph = NULL;
168
169bool useFullScreen = false;
170
171bool useLODs = true;
172
173
174static Matrix4x4 matProjectionView = IdentityMatrix();
175
176
177
178// function forward declarations
179void InitExtensions();
180void DisplayVisualization();
181void InitGLstate();
182void InitRenderTexture();
183void InitCg();
184void CleanUp();
185void SetupEyeView();
186void UpdateEyeMtx();
187void SetupLighting();
188void DisplayStats();
189void Output(int x, int y, const char *string);
190void DrawHelpMessage();
191void RenderSky();
192void RenderVisibleObjects();
193
194void Begin2D();
195void End2D();
196void KeyBoard(unsigned char c, int x, int y);
197void DrawStatistics();
198void Display();
199void Special(int c, int x, int y);
200void KeyUp(unsigned char c, int x, int y);
201void SpecialKeyUp(int c, int x, int y);
202void Reshape(int w, int h);
203void Mouse(int button, int state, int x, int y);
204void LeftMotion(int x, int y);
205void RightMotion(int x, int y);
206void MiddleMotion(int x, int y);
207void CalcDecimalPoint(string &str, int d);
208void ResetTraverser();
209
210void KeyHorizontalMotion(float shift);
211void KeyVerticalMotion(float shift);
212
213void PlaceViewer(const Vector3 &oldPos);
214
215
216inline float KeyRotationAngle() { return keyRotation * elapsedTime * 1e-3f; }
217inline float KeyShift() { return keyForwardMotion * elapsedTime * 1e-3f; }
218
219void InitFBO();
220
221SsaoShader *ssaoShader = NULL;
222DeferredShader *deferredShader = NULL;
223
224GLenum mrt[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT};
225
226
227/////////
228//-- cg stuff
229
230static CGcontext sCgContext = NULL;
231static CGprogram sCgMrtVertexProgram = NULL;
232
233static CGparameter sModelViewProjMatrixParam;
234static CGparameter sMaxDepthParam;
235static CGparameter sMaxDepthParamTex;
236
237static Matrix4x4 oldViewProjMatrix;
238
239
240static void cgErrorCallback()
241{
242        CGerror lastError = cgGetError();
243
244        if(lastError)
245        {
246                printf("%s\n\n", cgGetErrorString(lastError));
247                printf("%s\n", cgGetLastListing(sCgContext));
248               
249                printf("Cg error, exiting...\n");
250
251                exit(0);
252        }
253}
254
255
256static void PrintGLerror(char *msg)
257{
258        GLenum errCode;
259        const GLubyte *errStr;
260       
261        if ((errCode = glGetError()) != GL_NO_ERROR)
262        {
263                errStr = gluErrorString(errCode);
264                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
265        }
266}
267
268
269int main(int argc, char* argv[])
270{
271        int returnCode = 0;
272
273        Vector3 camPos(.0f, .0f, .0f);
274        Vector3 camDir(.0f, 1.0f, .0f);
275
276        cout << "=== reading environment file ===" << endl << endl;
277
278        string envFileName = "default.env";
279        if (!env.Read(envFileName))
280        {
281                cerr << "loading environment " << envFileName << " failed!" << endl;
282        }
283        else
284        {
285                env.GetIntParam(string("assumedVisibleFrames"), assumedVisibleFrames);
286                env.GetIntParam(string("maxBatchSize"), maxBatchSize);
287                env.GetIntParam(string("trianglesPerVirtualLeaf"), trianglesPerVirtualLeaf);
288
289                env.GetFloatParam(string("keyForwardMotion"), keyForwardMotion);
290                env.GetFloatParam(string("keyRotation"), keyRotation);
291
292                env.GetIntParam(string("winWidth"), winWidth);
293                env.GetIntParam(string("winHeight"), winHeight);
294
295                env.GetBoolParam(string("useFullScreen"), useFullScreen);
296                env.GetFloatParam(string("expFactor"), ssaoExpFactor);
297                env.GetVectorParam(string("camPosition"), camPos);
298                env.GetVectorParam(string("camDirection"), camDir);
299
300                env.GetBoolParam(string("useLODs"), useLODs);
301
302                //env.GetStringParam(string("modelPath"), model_path);
303                //env.GetIntParam(string("numSssaoSamples"), numSsaoSamples);
304
305
306                cout << "assumedVisibleFrames: " << assumedVisibleFrames << endl;
307                cout << "maxBatchSize: " << maxBatchSize << endl;
308                cout << "trianglesPerVirtualLeaf: " << trianglesPerVirtualLeaf << endl;
309
310                cout << "keyForwardMotion: " << keyForwardMotion << endl;
311                cout << "keyRotation: " << keyRotation << endl;
312                cout << "winWidth: " << winWidth << endl;
313                cout << "winHeight: " << winHeight << endl;
314                cout << "useFullScreen: " << useFullScreen << endl;
315                cout << "useLODs: " << useLODs << endl;
316                cout << "camPosition: " << camPos << endl;
317                cout << "expFactor: " << ssaoExpFactor << endl;
318
319                //cout << "model path: " << model_path << endl;
320
321                cout << "**** end parameters ****" << endl;
322        }
323
324        ///////////////////////////
325
326        camera = new Camera(winWidth, winHeight, fov);
327        camera->SetNear(nearDist);
328       
329        camera->SetDirection(camDir);
330        camera->SetPosition(camPos);
331
332        visCamera = new Camera(winWidth, winHeight, fov);
333
334        visCamera->SetNear(0.0f);
335        visCamera->Yaw(.5 * M_PI);
336
337        renderQueue = new RenderQueue(&state, camera);
338
339        glutInitWindowSize(winWidth, winHeight);
340        glutInit(&argc, argv);
341        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE);
342        //glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
343        //glutInitDisplayString("samples=2");
344
345        SceneEntity::SetUseLODs(useLODs);
346
347
348        if (!useFullScreen)
349        {
350                glutCreateWindow("FriendlyCulling");
351        }
352        else
353        {
354                glutGameModeString( "1024x768:32@75" );
355                glutEnterGameMode();
356        }
357
358        glutDisplayFunc(Display);
359        glutKeyboardFunc(KeyBoard);
360        glutSpecialFunc(Special);
361        glutReshapeFunc(Reshape);
362        glutMouseFunc(Mouse);
363        glutIdleFunc(Display);
364        glutKeyboardUpFunc(KeyUp);
365        glutSpecialUpFunc(SpecialKeyUp);
366        glutIgnoreKeyRepeat(true);
367
368        // initialise gl graphics
369        InitExtensions();
370        InitGLstate();
371
372        glEnable(GL_MULTISAMPLE_ARB);
373        glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
374
375        InitFBO();
376       
377        LeftMotion(0, 0);
378        MiddleMotion(0, 0);
379
380        perfGraph = new PerformanceGraph(1000);
381
382        loader = new ResourceManager();
383
384        //const string filename("data/city/model/city.dem");
385        const string filename = string(model_path + "city.dem");
386
387        if (loader->Load(filename, sceneEntities))
388                cout << "scene " << filename << " loaded" << endl;
389        else
390        {
391                cerr << "loading scene " << filename << " failed" << endl;
392                CleanUp();
393                exit(0);
394        }
395
396        SceneEntityContainer dummy;
397
398        const string envname = string(model_path + "env.dem");
399
400        if (loader->Load(envname, skyGeometry))
401                cout << "sky box " << filename << " loaded" << endl;
402        else
403        {
404                cerr << "loading sky box " << filename << " failed" << endl;
405                CleanUp();
406                exit(0);
407        }
408
409        const string bvh_filename = string(model_path + "city.bvh");
410        BvhLoader bvhLoader;
411        bvh = bvhLoader.Load(bvh_filename, sceneEntities);
412
413        if (!bvh)
414        {
415                cerr << "loading bvh " << bvh_filename << " failed" << endl;
416                CleanUp();
417                exit(0);
418        }
419
420        // set far plane based on scene extent
421        myfar = 10.0f * Magnitude(bvh->GetBox().Diagonal());
422        bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
423
424        bvh->SetCamera(camera);
425       
426        InitCg();
427
428        DeferredShader::Init(sCgContext);
429        SsaoShader::Init(sCgContext);
430
431        deferredShader = new DeferredShader(texWidth, texHeight);
432        ssaoShader = new SsaoShader(texWidth, texHeight, camera, myfar / 10.0f);
433
434        // initialize the render traverser
435        ResetTraverser();
436
437        visualization = new Visualization(bvh, camera, NULL, &state);
438
439        sceneQuery = new SceneQuery(bvh->GetBox(), traverser);
440
441        // frame time is restarted every frame
442        frameTimer.Start();
443
444        // the rendering loop
445        glutMainLoop();
446
447        // clean up
448        CleanUp();
449
450        return 0;
451}
452
453
454void InitCg(void)
455{
456        // Setup Cg
457        cgSetErrorCallback(cgErrorCallback);
458
459        // Create cgContext.
460        sCgContext = cgCreateContext();
461
462        // get the best profile for this hardware
463        RenderState::sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
464        cgGLSetOptimalOptions(RenderState::sCgFragmentProfile);
465
466        RenderState::sCgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
467        cgGLSetOptimalOptions(RenderState::sCgVertexProfile);
468
469        sCgMrtVertexProgram =
470                cgCreateProgramFromFile(sCgContext,
471                                                                CG_SOURCE,
472                                                                "src/shaders/mrt.cg",
473                                                                RenderState::sCgVertexProfile,
474                                                                "vtx",
475                                                                NULL);
476
477        if (sCgMrtVertexProgram != NULL)
478        {
479                cgGLLoadProgram(sCgMrtVertexProgram);
480
481                Transform3::sModelMatrixParam = cgGetNamedParameter(sCgMrtVertexProgram, "ModelMatrix");
482                sModelViewProjMatrixParam = cgGetNamedParameter(sCgMrtVertexProgram, "ModelViewProj");
483        }
484
485        RenderState::sCgMrtFragmentTexProgram =
486                cgCreateProgramFromFile(sCgContext,
487                                                                CG_SOURCE,
488                                                                "src/shaders/mrt.cg",
489                                                                RenderState::sCgFragmentProfile,
490                                                                "fragtex",
491                                                                NULL);
492
493        if (RenderState::sCgMrtFragmentTexProgram != NULL)
494        {
495                cgGLLoadProgram(RenderState::sCgMrtFragmentTexProgram);
496
497                sMaxDepthParamTex = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "maxDepth");
498                Material::sDiffuseTexParam = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "diffuse");
499                Material::sAmbientTexParam = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "ambient");
500
501                cgGLSetParameter1f(sMaxDepthParamTex, 10.0f / myfar);
502                Debug << "maxdepth: " << 10.0f / myfar << endl;
503        }
504        else
505                cerr << "fragment tex program failed to load" << endl;
506
507        RenderState::sCgMrtFragmentProgram =
508                cgCreateProgramFromFile(sCgContext,
509                                                                CG_SOURCE,
510                                                                "src/shaders/mrt.cg",
511                                                                RenderState::sCgFragmentProfile,
512                                                                "frag",
513                                                                NULL);
514
515        if (RenderState::sCgMrtFragmentProgram != NULL)
516        {
517                cgGLLoadProgram(RenderState::sCgMrtFragmentProgram);
518
519                sMaxDepthParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "maxDepth");
520                Material::sDiffuseParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "diffuse");
521                Material::sAmbientParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "ambient");
522
523                cgGLSetParameter1f(sMaxDepthParam, 10.0f / myfar);
524        }
525        else
526                cerr << "fragment program failed to load" << endl;
527
528        PrintGLerror("init");
529
530        cout << "cg initialization successful" << endl;
531}
532
533
534void InitFBO()
535{
536        // this fbo basicly stores the scene information we get from standard rendering of a frame
537        // we store colors, normals, positions (for the ssao)
538        fbo = new FrameBufferObject(texWidth, texHeight, FrameBufferObject::DEPTH_32);
539
540        // the diffuse color buffer
541        fbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_MIPMAP_LINEAR, true);
542        //fbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST, false);
543
544        // the positions buffer
545        fbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_MIPMAP_LINEAR, true);
546        //fbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST, false);
547       
548        // the normals buffer
549        //fbo->AddColorBuffer(ColorBufferObject::BUFFER_UBYTE, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST, false);
550        fbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST, false);
551
552        PrintGLerror("fbo");
553}
554
555
556bool InitFont(void)
557{
558        glEnable(GL_TEXTURE_2D);
559
560        glGenTextures(1, &fontTex);
561        glBindTexture(GL_TEXTURE_2D, fontTex);
562        if (!myfont.Create("data/fonts/verdana.glf", fontTex))
563                return false;
564
565        glDisable(GL_TEXTURE_2D);
566       
567        return true;
568}
569
570
571void InitGLstate()
572{
573        glClearColor(0.5f, 0.5f, 0.8f, 0.0f);
574       
575        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
576        glPixelStorei(GL_PACK_ALIGNMENT,1);
577       
578        glDepthFunc(GL_LESS);
579        glEnable(GL_DEPTH_TEST);
580
581        SetupLighting();
582
583        glColor3f(1.0f, 1.0f, 1.0f);
584        glShadeModel(GL_SMOOTH);
585       
586        glMaterialf(GL_FRONT, GL_SHININESS, 64);
587        glEnable(GL_NORMALIZE);
588               
589        //glEnable(GL_ALPHA_TEST);
590        glDisable(GL_ALPHA_TEST);
591        glAlphaFunc(GL_GEQUAL, 0.8f);
592
593        glFrontFace(GL_CCW);
594        glCullFace(GL_BACK);
595        glEnable(GL_CULL_FACE);
596
597        //glDisable(GL_CULL_FACE);
598        glDisable(GL_TEXTURE_2D);
599
600        GLfloat ambientColor[] = {0.5, 0.5, 0.5, 1.0};
601        GLfloat diffuseColor[] = {1.0, 0.0, 0.0, 1.0};
602        GLfloat specularColor[] = {0.0, 0.0, 0.0, 1.0};
603
604        glMaterialfv(GL_FRONT, GL_AMBIENT, ambientColor);
605        glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor);
606        glMaterialfv(GL_FRONT, GL_SPECULAR, specularColor);
607
608        glDepthFunc(GL_LESS);
609
610        if (!InitFont())
611                cerr << "font creation failed" << endl;
612        else
613                cout << "successfully created font" << endl;
614}
615
616
617void DrawHelpMessage()
618{
619        const char *message[] =
620        {
621                "Help information",
622                "",
623                "'F1'           - shows/dismisses this message",
624                "'F2'           - shows/hides bird eye view",
625                "'F3'           - shows/hides bounds (boxes or tight bounds)",
626                "'F4',          - shows/hides parameters",
627                "'F5'           - shows/hides statistics",
628                "'F6',          - toggles between fly/walkmode",
629                "'F7',          - cycles throw render modes",
630                "'F8',          - enables/disables ambient occlusion (only deferred)",
631                "'F9',          - shows pure algorithm render time (using glFinish)",
632                "'SPACE'        - cycles through occlusion culling algorithms",
633                "",
634                "'MOUSE LEFT'        - turn left/right, move forward/backward",
635                "'MOUSE RIGHT'       - turn left/right, move forward/backward",
636                "'MOUSE MIDDLE'      - move up/down, left/right",
637                "'CURSOR UP/DOWN'    - move forward/backward",
638                "'CURSOR LEFT/RIGHT' - turn left/right",
639                "",
640                "'-'/'+'        - decreases/increases max batch size",
641                "'1'/'2'        - downward/upward motion",
642                "'3'/'4'        - decreases/increases triangles per virtual bvh leaf (sets bvh depth)",
643                "'5'/'6'        - decreases/increases assumed visible frames",
644                "",
645                "'R'            - use render queue",
646                "'B'            - use tight bounds",
647                "'M'            - use multiqueries",
648                "'O'            - use CHC optimization (geometry queries for leaves)",
649                0,
650        };
651       
652       
653        glColor4f(0.0f, 1.0f , 0.0f, 0.2f); // 20% green.
654
655        glRecti(30, 30, winWidth - 30, winHeight - 30);
656
657        glEnd();
658
659        glColor3f(1.0f, 1.0f, 1.0f);
660       
661        glEnable(GL_TEXTURE_2D);
662        myfont.Begin();
663
664        int x = 40, y = 30;
665
666        for(int i = 0; message[i] != 0; ++ i)
667        {
668                if(message[i][0] == '\0')
669                {
670                        y += 15;
671                }
672                else
673                {
674                        myfont.DrawString(message[i], x, winHeight - y);
675                        y += 25;
676                }
677        }
678        glDisable(GL_TEXTURE_2D);
679}
680
681
682void ResetTraverser()
683{
684        DEL_PTR(traverser);
685
686        bvh->ResetNodeClassifications();
687
688        switch (renderMode)
689        {
690        case RenderTraverser::CULL_FRUSTUM:
691                traverser = new FrustumCullingTraverser();
692                break;
693        case RenderTraverser::STOP_AND_WAIT:
694                traverser = new StopAndWaitTraverser();
695                break;
696        case RenderTraverser::CHC:
697                traverser = new CHCTraverser();
698                break;
699        case RenderTraverser::CHCPLUSPLUS:
700                traverser = new CHCPlusPlusTraverser();
701                break;
702       
703        default:
704                traverser = new FrustumCullingTraverser();
705        }
706
707        traverser->SetCamera(camera);
708        traverser->SetHierarchy(bvh);
709        traverser->SetRenderQueue(renderQueue);
710        traverser->SetRenderState(&state);
711        traverser->SetUseOptimization(useOptimization);
712        traverser->SetUseRenderQueue(useRenderQueue);
713        traverser->SetVisibilityThreshold(threshold);
714        traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
715        traverser->SetMaxBatchSize(maxBatchSize);
716        traverser->SetUseMultiQueries(useMultiQueries);
717        traverser->SetUseTightBounds(useTightBounds);
718        traverser->SetUseDepthPass(renderType == RenderState::DEPTH_PASS);
719        traverser->SetRenderQueue(renderQueue);
720}
721
722
723void SetupLighting()
724{
725        glEnable(GL_LIGHTING);
726        glEnable(GL_LIGHT0);
727        glEnable(GL_LIGHT1);
728       
729        GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
730        GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0};
731        GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
732           
733        GLfloat lmodel_ambient[] = {0.3f, 0.3f, 0.3f, 1.0f};
734
735        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
736        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
737        glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
738
739
740        ////////////
741        //-- second light
742
743        GLfloat ambient1[] = {0.2, 0.2, 0.2, 1.0};
744        GLfloat diffuse1[] = {1.0, 1.0, 1.0, 1.0};
745        //GLfloat diffuse1[] = {0.5, 0.5, 0.5, 1.0};
746        GLfloat specular1[] = {0.0, 0.0, 0.0, 1.0};
747
748        glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1);
749        glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1);
750        glLightfv(GL_LIGHT1, GL_SPECULAR, specular1);
751
752       
753        //////////////////////////////
754
755        GLfloat position[] = {0.8f, -1.0f, 0.7f, 0.0f};
756        glLightfv(GL_LIGHT0, GL_POSITION, position);
757
758        GLfloat position1[] = {-0.5f, 0.5f, 0.4f, 0.0f};
759        glLightfv(GL_LIGHT1, GL_POSITION, position1);
760
761        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
762        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
763        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SINGLE_COLOR_EXT);
764}
765
766
767void SetupEyeView()
768{
769        // store matrix of last frame
770        oldViewProjMatrix = matProjectionView;
771
772        glMatrixMode(GL_PROJECTION);
773        glLoadIdentity();
774
775        gluPerspective(fov, winAspectRatio, nearDist, myfar);
776
777        glMatrixMode(GL_MODELVIEW);
778        glLoadIdentity();
779
780        // set up the camera view
781        camera->SetupCameraView();
782
783        // set lights
784        GLfloat position[] = {0.8f, -1.0f, 0.7f, 0.0f};
785        glLightfv(GL_LIGHT0, GL_POSITION, position);
786
787        GLfloat position1[] = {-0.5f, 0.5f, 0.4f, 0.0f};
788        glLightfv(GL_LIGHT1, GL_POSITION, position1);
789
790       
791        /////////////////
792
793        Matrix4x4 matViewing, matProjection;
794
795        camera->GetModelViewMatrix(matViewing);
796        camera->GetProjectionMatrix(matProjection);
797
798        // store matrix for later use
799        matProjectionView = matViewing * matProjection;
800       
801        if (renderType == RenderState::DEFERRED)
802        {
803                // set modelview matrix for shaders
804                cgGLSetStateMatrixParameter(sModelViewProjMatrixParam,
805                                                                        CG_GL_MODELVIEW_PROJECTION_MATRIX,
806                                                                        CG_GL_MATRIX_IDENTITY);
807
808                static Matrix4x4 identity = IdentityMatrix();
809                cgGLSetMatrixParameterfc(Transform3::sModelMatrixParam, (const float *)identity.x);
810        }               
811}
812
813
814void KeyHorizontalMotion(float shift)
815{
816        Vector3 hvec = camera->GetDirection();
817        hvec.z = 0;
818
819        Vector3 pos = camera->GetPosition();
820        pos += hvec * shift;
821       
822        camera->SetPosition(pos);
823}
824
825
826void KeyVerticalMotion(float shift)
827{
828        Vector3 uvec = Vector3(0, 0, shift);
829
830        Vector3 pos = camera->GetPosition();
831        pos += uvec;
832       
833        camera->SetPosition(pos);
834}
835
836
837// the main rendering loop
838void Display()
839{       
840        Vector3 oldPos = camera->GetPosition();
841
842        if (leftKeyPressed)
843                camera->Pitch(KeyRotationAngle());
844        if (rightKeyPressed)
845                camera->Pitch(-KeyRotationAngle());
846        if (upKeyPressed)
847                KeyHorizontalMotion(KeyShift());
848        if (downKeyPressed)
849                KeyHorizontalMotion(-KeyShift());
850        if (ascendKeyPressed)
851                KeyVerticalMotion(KeyShift());
852        if (descendKeyPressed)
853                KeyVerticalMotion(-KeyShift());
854
855        // place view on ground
856        if (!flyMode) PlaceViewer(oldPos);
857
858        if (showAlgorithmTime)
859        {
860                glFinish();
861                algTimer.Start();
862        }
863       
864        // render without shading
865        switch (renderType)
866        {
867        case RenderState::FIXED:
868       
869                glEnable(GL_MULTISAMPLE_ARB);
870                //glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
871
872                fbo->Release();
873
874                state.SetRenderType(RenderState::FIXED);
875                glEnable(GL_LIGHTING);
876
877                cgGLDisableProfile(RenderState::sCgFragmentProfile);
878                cgGLDisableProfile(RenderState::sCgVertexProfile);
879
880                glDrawBuffers(1, mrt);
881
882                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
883
884                break;
885
886        case RenderState::DEPTH_PASS:
887
888                glEnable(GL_MULTISAMPLE_ARB);
889                //glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
890
891                fbo->Release();
892
893                cgGLDisableProfile(RenderState::sCgFragmentProfile);
894                cgGLDisableProfile(RenderState::sCgVertexProfile);
895
896                state.SetRenderType(RenderState::DEPTH_PASS);
897
898                // the scene is rendered withouth any shading   
899                glDisable(GL_LIGHTING);
900       
901                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
902
903                glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
904
905                glDrawBuffers(1, mrt);
906
907                break;
908       
909        case RenderState::DEFERRED:
910
911                // multisampling not working with deferred shading
912                //glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
913                glDisable(GL_MULTISAMPLE_ARB);
914
915                state.SetRenderType(RenderState::DEFERRED);
916
917                fbo->Bind();
918       
919                glPushAttrib(GL_VIEWPORT_BIT);
920                glViewport(0, 0, texWidth, texHeight);
921
922                cgGLEnableProfile(RenderState::sCgFragmentProfile);
923                cgGLBindProgram(RenderState::sCgMrtFragmentProgram);
924
925                cgGLEnableProfile(RenderState::sCgVertexProfile);
926                cgGLBindProgram(sCgMrtVertexProgram);
927
928                /// draw to 3 color buffers
929                glDrawBuffers(3, mrt);
930
931                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
932
933                break;
934        }
935
936
937        glDepthFunc(GL_LESS);
938
939        glDisable(GL_TEXTURE_2D);
940        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
941               
942
943        // reset lod levels for current frame
944        LODLevel::InitFrame(camera->GetPosition());
945
946
947        // bring eye modelview matrix up-to-date
948        SetupEyeView();
949
950        // actually render the scene geometry using one of the specified algorithms
951        traverser->RenderScene();
952
953
954
955        /////////
956        //-- do the rest of the rendering
957
958        glEnableClientState(GL_VERTEX_ARRAY);
959        glEnableClientState(GL_NORMAL_ARRAY);
960
961
962        // reset depth pass and render visible objects
963        if (renderType == RenderState::DEPTH_PASS)
964        {
965                glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
966                RenderVisibleObjects();
967        }
968       
969
970        ///////////////
971        //-- render sky
972
973        RenderSky();
974
975        state.Reset();
976
977        glDisableClientState(GL_VERTEX_ARRAY);
978        glDisableClientState(GL_NORMAL_ARRAY);
979
980
981        if (renderType == RenderState::DEFERRED)
982        {
983                fbo->Release();
984
985                cgGLDisableProfile(RenderState::sCgVertexProfile);
986                cgGLDisableProfile(RenderState::sCgFragmentProfile);
987
988                glDrawBuffers(1, mrt);
989
990                if (useSsao)
991                        ssaoShader->Render(fbo, oldViewProjMatrix, ssaoExpFactor);
992                else
993                        deferredShader->Render(fbo);
994        }
995       
996        ///////////
997
998        state.SetRenderType(RenderState::FIXED);
999
1000        if (showAlgorithmTime)
1001        {
1002                glFinish();
1003
1004                algTime = algTimer.Elapsedms();
1005                perfGraph->AddData(algTime);
1006
1007                perfGraph->Draw();
1008        }
1009        else
1010        {
1011                if (visMode) DisplayVisualization();
1012        }
1013
1014        //glFlush();
1015
1016        const bool restart = true;
1017        elapsedTime = frameTimer.Elapsedms(restart);
1018
1019        DisplayStats();
1020
1021        // flip textures for temporal smoothing
1022        isFirstTexture = !isFirstTexture;
1023
1024        glutSwapBuffers();
1025}
1026
1027
1028#pragma warning( disable : 4100 )
1029void KeyBoard(unsigned char c, int x, int y)
1030{
1031        switch(c)
1032        {
1033        case 27:
1034                CleanUp();
1035                exit(0);
1036                break;
1037        case 32: //space
1038                renderMode = (renderMode + 1) % RenderTraverser::NUM_TRAVERSAL_TYPES;
1039                ResetTraverser();
1040                break;
1041        case 'h':
1042        case 'H':
1043                showHelp = !showHelp;
1044                break;
1045        case '+':
1046                if (maxBatchSize < 10)
1047                        maxBatchSize = 10;
1048                else
1049                        maxBatchSize += 10;
1050
1051                traverser->SetMaxBatchSize(maxBatchSize);
1052                break;
1053        case '-':
1054                maxBatchSize -= 10;
1055                if (maxBatchSize < 0) maxBatchSize = 1;
1056                traverser->SetMaxBatchSize(maxBatchSize);               
1057                break;
1058        case 'M':
1059        case 'm':
1060                useMultiQueries = !useMultiQueries;
1061                traverser->SetUseMultiQueries(useMultiQueries);
1062                break;
1063        case '1':
1064                descendKeyPressed = true;
1065                break;
1066        case '2':
1067                ascendKeyPressed = true;
1068                break;
1069        case '3':
1070                if (trianglesPerVirtualLeaf >= 100)
1071                        trianglesPerVirtualLeaf -= 100;
1072                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1073                break;
1074        case '4':
1075                trianglesPerVirtualLeaf += 100;
1076                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1077                break;
1078        case '5':
1079                assumedVisibleFrames -= 1;
1080                if (assumedVisibleFrames < 1) assumedVisibleFrames = 1;
1081                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
1082                break;
1083        case '6':
1084                assumedVisibleFrames += 1;
1085                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);               
1086                break;
1087        case '7':
1088                ssaoExpFactor *= 0.5f;
1089                break;
1090        case '8':
1091                ssaoExpFactor *= 2.0f;
1092                if (ssaoExpFactor > 1.0f) ssaoExpFactor = 1.0f;
1093                break;
1094        case '9':
1095                useLODs = !useLODs;
1096                SceneEntity::SetUseLODs(useLODs);
1097                break;
1098        case 'o':
1099        case 'O':
1100                useOptimization = !useOptimization;
1101                traverser->SetUseOptimization(useOptimization);
1102                break;
1103        case 'a':
1104        case 'A':
1105                        leftKeyPressed = true;
1106                break;
1107        case 'd':
1108        case 'D':
1109                        rightKeyPressed = true;
1110                break;
1111        case 'w':
1112        case 'W':
1113                        upKeyPressed = true;
1114                break;
1115        case 's':
1116        case 'S':
1117                        downKeyPressed = true;
1118                break;
1119        case 'r':
1120        case 'R':
1121                {
1122                        useRenderQueue = !useRenderQueue;
1123                        traverser->SetUseRenderQueue(useRenderQueue);
1124                }
1125                break;
1126        case 'b':
1127        case 'B':
1128                {
1129                        useTightBounds = !useTightBounds;
1130                        traverser->SetUseTightBounds(useTightBounds);
1131                }
1132                break;
1133        default:
1134                return;
1135        }
1136
1137        glutPostRedisplay();
1138}
1139
1140
1141void SpecialKeyUp(int c, int x, int y)
1142{
1143        switch (c)
1144        {
1145        case GLUT_KEY_LEFT:
1146                leftKeyPressed = false;
1147                break;
1148        case GLUT_KEY_RIGHT:
1149                rightKeyPressed = false;
1150                break;
1151        case GLUT_KEY_UP:
1152                upKeyPressed = false;
1153                break;
1154        case GLUT_KEY_DOWN:
1155                downKeyPressed = false;
1156                break;
1157        default:
1158                return;
1159        }
1160        //glutPostRedisplay();
1161}
1162
1163
1164void KeyUp(unsigned char c, int x, int y)
1165{
1166        switch (c)
1167        {
1168        case 'A':
1169        case 'a':
1170                leftKeyPressed = false;
1171                break;
1172        case 'D':
1173        case 'd':
1174                rightKeyPressed = false;
1175                break;
1176        case 'W':
1177        case 'w':
1178                upKeyPressed = false;
1179                break;
1180        case 'S':
1181        case 's':
1182                downKeyPressed = false;
1183                break;
1184        case '1':
1185                descendKeyPressed = false;
1186                break;
1187        case '2':
1188                ascendKeyPressed = false;
1189                break;
1190       
1191        default:
1192                return;
1193        }
1194        //glutPostRedisplay();
1195}
1196
1197
1198void Special(int c, int x, int y)
1199{
1200        switch(c)
1201        {
1202        case GLUT_KEY_F1:
1203                showHelp = !showHelp;
1204                break;
1205        case GLUT_KEY_F2:
1206                visMode = !visMode;
1207                break;
1208        case GLUT_KEY_F3:
1209                showBoundingVolumes = !showBoundingVolumes;
1210                traverser->SetShowBounds(showBoundingVolumes);
1211                break;
1212        case GLUT_KEY_F4:
1213                showOptions = !showOptions;
1214                break;
1215        case GLUT_KEY_F5:
1216                showStatistics = !showStatistics;
1217                break;
1218        case GLUT_KEY_F6:
1219                flyMode = !flyMode;
1220                break;
1221        case GLUT_KEY_F7:
1222
1223                renderType = (renderType + 1) % 3;
1224                traverser->SetUseDepthPass(renderType == RenderState::DEPTH_PASS);
1225               
1226                break;
1227        case GLUT_KEY_F8:
1228                useSsao = !useSsao;
1229                break;
1230        case GLUT_KEY_F9:
1231                showAlgorithmTime = !showAlgorithmTime;
1232                break;
1233
1234        case GLUT_KEY_LEFT:
1235                {
1236                        leftKeyPressed = true;
1237                        camera->Pitch(KeyRotationAngle());
1238                }
1239                break;
1240        case GLUT_KEY_RIGHT:
1241                {
1242                        rightKeyPressed = true;
1243                        camera->Pitch(-KeyRotationAngle());
1244                }
1245                break;
1246        case GLUT_KEY_UP:
1247                {
1248                        upKeyPressed = true;
1249                        KeyHorizontalMotion(KeyShift());
1250                }
1251                break;
1252        case GLUT_KEY_DOWN:
1253                {
1254                        downKeyPressed = true;
1255                        KeyHorizontalMotion(-KeyShift());
1256                }
1257                break;
1258        default:
1259                return;
1260
1261        }
1262
1263        glutPostRedisplay();
1264}
1265
1266#pragma warning( default : 4100 )
1267
1268
1269void Reshape(int w, int h)
1270{
1271        winAspectRatio = 1.0f;
1272
1273        glViewport(0, 0, w, h);
1274       
1275        winWidth = w;
1276        winHeight = h;
1277
1278        if (w) winAspectRatio = (float) w / (float) h;
1279
1280        glMatrixMode(GL_PROJECTION);
1281        glLoadIdentity();
1282
1283        gluPerspective(fov, winAspectRatio, nearDist, myfar);
1284
1285        glMatrixMode(GL_MODELVIEW);
1286
1287        glutPostRedisplay();
1288}
1289
1290
1291void Mouse(int button, int state, int x, int y)
1292{
1293        if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
1294        {
1295                xEyeBegin = x;
1296                yMotionBegin = y;
1297
1298                glutMotionFunc(LeftMotion);
1299        }
1300        else if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN))
1301        {
1302                xEyeBegin = x;
1303                yEyeBegin = y;
1304                yMotionBegin = y;
1305
1306                glutMotionFunc(RightMotion);
1307        }
1308        else if ((button == GLUT_MIDDLE_BUTTON) && (state == GLUT_DOWN))
1309        {
1310                horizontalMotionBegin = x;
1311                verticalMotionBegin = y;
1312                glutMotionFunc(MiddleMotion);
1313        }
1314
1315        glutPostRedisplay();
1316}
1317
1318
1319/**     rotation for left/right mouse drag
1320        motion for up/down mouse drag
1321*/
1322void LeftMotion(int x, int y)
1323{
1324        Vector3 viewDir = camera->GetDirection();
1325        Vector3 pos = camera->GetPosition();
1326
1327        // don't move in the vertical direction
1328        Vector3 horView(viewDir[0], viewDir[1], 0);
1329       
1330        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
1331
1332        camera->Pitch(eyeXAngle);
1333
1334        pos += horView * (yMotionBegin - y) * 0.2f;
1335       
1336        camera->SetPosition(pos);
1337       
1338        xEyeBegin = x;
1339        yMotionBegin = y;
1340
1341        glutPostRedisplay();
1342}
1343
1344
1345/**     rotation for left / right mouse drag
1346        motion for up / down mouse drag
1347*/
1348void RightMotion(int x, int y)
1349{
1350        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
1351        float eyeYAngle = -0.2f *  M_PI * (yEyeBegin - y) / 180.0;
1352
1353        camera->Yaw(eyeYAngle);
1354        camera->Pitch(eyeXAngle);
1355
1356        xEyeBegin = x;
1357        yEyeBegin = y;
1358
1359        glutPostRedisplay();
1360}
1361
1362
1363// strafe
1364void MiddleMotion(int x, int y)
1365{
1366        Vector3 viewDir = camera->GetDirection();
1367        Vector3 pos = camera->GetPosition();
1368
1369        // the 90 degree rotated view vector
1370        // y zero so we don't move in the vertical
1371        Vector3 rVec(viewDir[0], viewDir[1], 0);
1372       
1373        Matrix4x4 rot = RotationZMatrix(M_PI * 0.5f);
1374        rVec = rot * rVec;
1375       
1376        pos -= rVec * (x - horizontalMotionBegin) * 0.1f;
1377        pos[2] += (verticalMotionBegin - y) * 0.1f;
1378
1379        camera->SetPosition(pos);
1380
1381        horizontalMotionBegin = x;
1382        verticalMotionBegin = y;
1383
1384        glutPostRedisplay();
1385}
1386
1387
1388void InitExtensions(void)
1389{
1390        GLenum err = glewInit();
1391
1392        if (GLEW_OK != err)
1393        {
1394                // problem: glewInit failed, something is seriously wrong
1395                fprintf(stderr,"Error: %s\n", glewGetErrorString(err));
1396                exit(1);
1397        }
1398        if  (!GLEW_ARB_occlusion_query)
1399        {
1400                printf("I require the GL_ARB_occlusion_query to work.\n");
1401                exit(1);
1402        }
1403}
1404
1405
1406void Begin2D()
1407{
1408        glDisable(GL_LIGHTING);
1409        glDisable(GL_DEPTH_TEST);
1410
1411        glMatrixMode(GL_PROJECTION);
1412        glPushMatrix();
1413        glLoadIdentity();
1414
1415        gluOrtho2D(0, winWidth, 0, winHeight);
1416
1417        glMatrixMode(GL_MODELVIEW);
1418        glPushMatrix();
1419        glLoadIdentity();
1420}
1421
1422
1423void End2D()
1424{
1425        glMatrixMode(GL_PROJECTION);
1426        glPopMatrix();
1427
1428        glMatrixMode(GL_MODELVIEW);
1429        glPopMatrix();
1430
1431        glEnable(GL_LIGHTING);
1432        glEnable(GL_DEPTH_TEST);
1433}
1434
1435
1436// displays the visualisation of culling algorithm
1437void DisplayVisualization()
1438{
1439        visualization->SetFrameId(traverser->GetCurrentFrameId());
1440       
1441        Begin2D();
1442        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1443        glEnable(GL_BLEND);
1444        glColor4f(0.0f ,0.0f, 0.0f, 0.5f);
1445
1446        glRecti(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth, winHeight);
1447        glDisable(GL_BLEND);
1448        End2D();
1449       
1450       
1451        AxisAlignedBox3 box = bvh->GetBox();
1452
1453        // hack: set far plane for viz
1454        camera->SetFar(0.35f * Magnitude(box.Diagonal()));
1455
1456        const float offs = box.Size().x * 0.3f;
1457       
1458        //Vector3 vizpos = Vector3(box.Min().x, box.Min().y + box.Size().y * 0.5f, box.Min().z + box.Size().z * 50);
1459        Vector3 vizpos = Vector3(box.Min().x, box.Min().y  - box.Size().y * 0.35f, box.Min().z + box.Size().z * 50);
1460       
1461        visCamera->SetPosition(vizpos);
1462        visCamera->ResetPitchAndYaw();
1463        //visCamera->Pitch(M_PI);
1464
1465        glPushAttrib(GL_VIEWPORT_BIT);
1466        glViewport(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth / 3, winHeight / 3);
1467
1468        glMatrixMode(GL_PROJECTION);
1469        glPushMatrix();
1470
1471        glLoadIdentity();
1472       
1473        glOrtho(-offs, offs, -offs, offs, 0.0f, box.Size().z * 100.0f);
1474
1475        glMatrixMode(GL_MODELVIEW);
1476        glPushMatrix();
1477
1478        visCamera->SetupCameraView();
1479
1480        //Matrix4x4 rotX = RotationXMatrix(camera->GetYaw());
1481        //glMultMatrixf((float *)rotX.x);
1482        Matrix4x4 rotZ = RotationZMatrix(-camera->GetPitch());
1483        glMultMatrixf((float *)rotZ.x);
1484
1485        Vector3 pos = camera->GetPosition();
1486        glTranslatef(-pos.x, -pos.y, -pos.z);
1487
1488
1489        GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
1490        glLightfv(GL_LIGHT0, GL_POSITION, position);
1491
1492        GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
1493        glLightfv(GL_LIGHT1, GL_POSITION, position1);
1494
1495        glClear(GL_DEPTH_BUFFER_BIT);
1496
1497
1498        ////////////
1499        //-- visualization of the occlusion culling
1500
1501        visualization->Render();
1502       
1503       
1504        // reset previous settings
1505        glPopAttrib();
1506
1507        glMatrixMode(GL_PROJECTION);
1508        glPopMatrix();
1509        glMatrixMode(GL_MODELVIEW);
1510        glPopMatrix();
1511}
1512
1513
1514// cleanup routine after the main loop
1515void CleanUp()
1516{
1517        DEL_PTR(traverser);
1518        DEL_PTR(sceneQuery);
1519        DEL_PTR(bvh);
1520        DEL_PTR(visualization);
1521        DEL_PTR(camera);
1522        DEL_PTR(loader);
1523        DEL_PTR(renderQueue);
1524        DEL_PTR(perfGraph);
1525
1526        if (sCgMrtVertexProgram)
1527                cgDestroyProgram(sCgMrtVertexProgram);
1528        if (RenderState::sCgMrtFragmentProgram)
1529                cgDestroyProgram(RenderState::sCgMrtFragmentProgram);
1530        if (RenderState::sCgMrtFragmentTexProgram)
1531                cgDestroyProgram(RenderState::sCgMrtFragmentTexProgram);
1532       
1533        if (sCgContext)
1534                cgDestroyContext(sCgContext);
1535}
1536
1537
1538// this function inserts a dezimal point after each 1000
1539void CalcDecimalPoint(string &str, int d, int len)
1540{
1541        static vector<int> numbers;
1542        numbers.clear();
1543
1544        static string shortStr;
1545        shortStr.clear();
1546
1547        static char hstr[100];
1548
1549        while (d != 0)
1550        {
1551                numbers.push_back(d % 1000);
1552                d /= 1000;
1553        }
1554
1555        // first element without leading zeros
1556        if (numbers.size() > 0)
1557        {
1558                sprintf(hstr, "%d", numbers.back());
1559                shortStr.append(hstr);
1560        }
1561       
1562        for (int i = (int)numbers.size() - 2; i >= 0; i--)
1563        {
1564                sprintf(hstr, ",%03d", numbers[i]);
1565                shortStr.append(hstr);
1566        }
1567
1568        int dif = len - (int)shortStr.size();
1569
1570        for (int i = 0; i < dif; ++ i)
1571        {
1572                str += " ";
1573        }
1574
1575        str.append(shortStr);
1576}
1577
1578
1579void DisplayStats()
1580{
1581        static char msg[9][300];
1582
1583        static double frameTime = elapsedTime;
1584        static double renderTime = algTime;
1585
1586        const float expFactor = 0.1f;
1587
1588        // if some strange render time spike happened in this frame => don't count
1589        if (elapsedTime < 500) frameTime = elapsedTime * expFactor + (1.0f - expFactor) * elapsedTime;
1590       
1591        static float rTime = 1000.0f;
1592
1593        if (showAlgorithmTime)
1594        {
1595                if (algTime < 500) renderTime = algTime * expFactor + (1.0f - expFactor) * renderTime;
1596        }
1597
1598        accumulatedTime += elapsedTime;
1599
1600        if (accumulatedTime > 500) // update every fraction of a second
1601        {       
1602                accumulatedTime = 0;
1603
1604                if (frameTime) fps = 1e3f / (float)frameTime;
1605
1606                rTime = renderTime;
1607                renderedObjects = traverser->GetStats().mNumRenderedGeometry;
1608                renderedNodes = traverser->GetStats().mNumRenderedNodes;
1609                renderedTriangles = traverser->GetStats().mNumRenderedTriangles;
1610
1611                traversedNodes = traverser->GetStats().mNumTraversedNodes;
1612                frustumCulledNodes = traverser->GetStats().mNumFrustumCulledNodes;
1613                queryCulledNodes = traverser->GetStats().mNumQueryCulledNodes;
1614                issuedQueries = traverser->GetStats().mNumIssuedQueries;
1615                stateChanges = traverser->GetStats().mNumStateChanges;
1616                numBatches = traverser->GetStats().mNumBatches;
1617        }
1618
1619
1620        Begin2D();
1621
1622        glEnable(GL_BLEND);
1623        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1624
1625        if (showHelp)
1626        {       
1627                DrawHelpMessage();
1628        }
1629        else
1630        {
1631                if (showOptions)
1632                {
1633                        glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
1634                        glRecti(5, winHeight - 95, winWidth * 2 / 3 - 5, winHeight - 5);
1635                }
1636
1637                if (showStatistics)
1638                {
1639                        glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
1640                        glRecti(5, winHeight - 165, winWidth * 2 / 3 - 5, winHeight - 100);
1641                }
1642
1643                glEnable(GL_TEXTURE_2D);
1644
1645                myfont.Begin();
1646
1647                if (showOptions)
1648                {
1649                        glColor3f(0.0f, 1.0f, 0.0f);
1650
1651                        int i = 0;
1652
1653                        static char *renderTypeStr[] = {"fixed function", "fixed function + depth pass", "deferred shading"};
1654       
1655                        sprintf(msg[i ++], "multiqueries: %d, tight bounds: %d, render queue: %d",
1656                                                        useMultiQueries, useTightBounds, useRenderQueue);
1657
1658                        sprintf(msg[i ++], "render technique: %s, SSAO: %d", renderTypeStr[renderType], useSsao);
1659
1660                        sprintf(msg[i ++], "triangles per virtual leaf: %5d", trianglesPerVirtualLeaf);
1661
1662                        sprintf(msg[i ++], "assumed visible frames: %4d, max batch size: %4d",
1663                                assumedVisibleFrames, maxBatchSize);
1664
1665                        for (int j = 0; j < 4; ++ j)
1666                                myfont.DrawString(msg[j], 10.0f, winHeight - 5 - j * 20);
1667                }
1668
1669                if (showStatistics)
1670                {
1671                        glColor3f(1.0f, 1.0f, 0.0f);
1672
1673                        string str;
1674                        string str2;
1675
1676                        int len = 10;
1677                        CalcDecimalPoint(str, renderedTriangles, len);
1678                        CalcDecimalPoint(str2, bvh->GetBvhStats().mTriangles, len);
1679
1680                        int i = 4;
1681
1682                        sprintf(msg[i ++], "rendered: %6d of %6d nodes, %s of %s triangles",
1683                                renderedNodes, bvh->GetNumVirtualNodes(), str.c_str(), str2.c_str());
1684
1685                        sprintf(msg[i ++], "traversed: %5d, frustum culled: %5d, query culled: %5d",
1686                                traversedNodes, frustumCulledNodes, queryCulledNodes);
1687
1688                        sprintf(msg[i ++], "issued queries: %5d, state changes: %5d, render batches: %5d",
1689                                issuedQueries, stateChanges, numBatches);
1690
1691                        for (int j = 4; j < 7; ++ j)
1692                                myfont.DrawString(msg[j], 10.0f, winHeight - (j + 1) * 20);
1693                }
1694
1695                glColor3f(1.0f, 1.0f, 1.0f);
1696                static char *alg_str[] = {"Frustum Cull", "Stop and Wait", "CHC", "CHC ++"};
1697               
1698                if (!showAlgorithmTime)
1699                {
1700                        sprintf(msg[7], "%s:  %6.1f fps", alg_str[renderMode], fps);
1701                }
1702                else
1703                {
1704                        sprintf(msg[7], "%s:  %6.1f ms", alg_str[renderMode], rTime);
1705                }
1706
1707                myfont.DrawString(msg[7], 1.3f, 690.0f, 760.0f);//, top_color, bottom_color);
1708               
1709                //sprintf(msg[8], "algorithm time: %6.1f ms", rTime);
1710                //myfont.DrawString(msg[8], 720.0f, 730.0f);           
1711        }
1712
1713        glDisable(GL_BLEND);
1714        glDisable(GL_TEXTURE_2D);
1715
1716        End2D();
1717}       
1718
1719
1720void RenderSky()
1721{
1722        SceneEntityContainer::const_iterator sit, sit_end = skyGeometry.end();
1723
1724        for (sit = skyGeometry.begin(); sit != sit_end; ++ sit)
1725                (*sit)->Render(&state);
1726}
1727
1728
1729void RenderVisibleObjects()
1730{
1731        state.SetRenderType(RenderState::FIXED);
1732        state.Reset();
1733
1734        glEnable(GL_LIGHTING);
1735        glDepthFunc(GL_LEQUAL);
1736
1737        //cout << "visible: " << (int)traverser->GetVisibleObjects().size() << endl;
1738
1739        SceneEntityContainer::const_iterator sit,
1740                sit_end = traverser->GetVisibleObjects().end();
1741
1742        for (sit = traverser->GetVisibleObjects().begin(); sit != sit_end; ++ sit)
1743                renderQueue->Enqueue(*sit);
1744               
1745        renderQueue->Apply();
1746
1747        glDepthFunc(GL_LESS);
1748}
1749
1750
1751void PlaceViewer(const Vector3 &oldPos)
1752{
1753        Vector3 playerPos = camera->GetPosition();
1754
1755        bool validIntersect = sceneQuery->CalcIntersection(playerPos);
1756
1757        if (validIntersect)
1758                // && ((playerPos.z - oldPos.z) < bvh->GetBox().Size(2) * 1e-1f))
1759        {
1760                camera->SetPosition(playerPos);
1761        }
1762}
Note: See TracBrowser for help on using the repository browser.