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

Revision 3369, 72.8 KB checked in by mattausch, 15 years ago (diff)

cleaned up code: working ok now

Line 
1// chcdemo.cpp : Defines the entry point for the console application.
2//
3
4
5#include "common.h"
6
7#ifdef _CRT_SET
8        #define _CRTDBG_MAP_ALLOC
9        #include <stdlib.h>
10        #include <crtdbg.h>
11
12        // redefine new operator
13        #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
14        #define new DEBUG_NEW
15#endif
16
17#include <math.h>
18#include <time.h>
19#include "glInterface.h"
20
21
22#include "RenderTraverser.h"
23#include "SceneEntity.h"
24#include "Vector3.h"
25#include "Matrix4x4.h"
26#include "ResourceManager.h"
27#include "Bvh.h"
28#include "Camera.h"
29#include "Geometry.h"
30#include "BvhLoader.h"
31#include "FrustumCullingTraverser.h"
32#include "StopAndWaitTraverser.h"
33#include "CHCTraverser.h"
34#include "CHCPlusPlusTraverser.h"
35#include "Visualization.h"
36#include "RenderState.h"
37#include "Timer/PerfTimer.h"
38#include "SceneQuery.h"
39#include "RenderQueue.h"
40#include "Material.h"
41#include "glfont2.h"
42#include "PerformanceGraph.h"
43#include "Environment.h"
44#include "Halton.h"
45#include "Transform3.h"
46#include "SampleGenerator.h"
47#include "FrameBufferObject.h"
48#include "DeferredRenderer.h"
49#include "ShadowMapping.h"
50#include "Light.h"
51#include "SceneEntityConverter.h"
52#include "SkyPreetham.h"
53#include "Texture.h"
54#include "ShaderManager.h"
55#include "MotionPath.h"
56#include "ShaderProgram.h"
57#include "Shape.h"
58#include "WalkThroughRecorder.h"
59#include "StatsWriter.h"
60#include "VisibilitySolutionLoader.h"
61#include "ViewCellsTree.h"
62#include "PvsCollectionRenderer.h"
63#include "ObjExporter.h"
64#include "BvhExporter.h"
65
66
67using namespace std;
68using namespace CHCDemoEngine;
69
70
71/// the environment for the program parameter
72static Environment env;
73
74
75GLuint fontTex;
76/// the fbo used for MRT
77FrameBufferObject *fbo = NULL;
78/// the renderable scene geometry
79SceneEntityContainer staticObjects;
80/// the dynamic objects in the scene
81SceneEntityContainer dynamicObjects;
82// traverses and renders the hierarchy
83RenderTraverser *traverser = NULL;
84/// the hierarchy
85Bvh *bvh = NULL;
86/// handles scene loading
87ResourceManager *resourceManager = NULL;
88/// handles scene loading
89ShaderManager *shaderManager = NULL;
90/// the scene camera
91PerspectiveCamera *camera = NULL;
92/// the scene camera
93PerspectiveCamera *visCamera = NULL;
94/// the visualization
95Visualization *visualization = NULL;
96/// the current render renderState
97RenderState renderState;
98/// the rendering algorithm
99int renderMode = RenderTraverser::CHCPLUSPLUS;
100/// eye near plane distance
101const float nearDist = 0.2f;
102//const float nearDist = 1.0f;
103/// eye far plane distance
104float farDist = 1e6f;
105/// the field of view
106//const float fov = 50.0f;
107const float fov = 90.0f;
108
109float skyDomeScaleFactor = 80.0f;
110
111SceneQuery *sceneQuery = NULL;
112RenderQueue *renderQueue = NULL;
113/// traverses and renders the hierarchy
114RenderTraverser *shadowTraverser = NULL;
115/// the skylight + skydome model
116SkyPreetham *preetham = NULL;
117
118MotionPath *motionPath = NULL;
119/// max depth where candidates for tighter bounds are searched
120int maxDepthForTestingChildren = 3;
121/// use full resolution for ssao or half
122bool ssaoUseFullResolution = false;
123
124/// store the frames as tga
125bool recordFrames = false;
126/// record the taken path
127bool recordPath = false;
128/// replays the recorded path
129bool replayPath = false;
130/// frame number for replay
131int currentReplayFrame = -1;
132
133string recordedFramesSuffix("frames");
134string statsFilename("stats");
135
136string filename("city");
137string bvhname("");
138string visibilitySolution("");
139
140
141/// the walkThroughRecorder
142WalkThroughRecorder *walkThroughRecorder = NULL;
143WalkThroughPlayer *walkThroughPlayer = NULL;
144StatsWriter *statsWriter = NULL;
145
146bool makeSnapShot = false;
147
148ViewCellsTree *viewCellsTree = NULL;
149ViewCell *viewCell = NULL;
150
151bool useSkylightForIllum = true;
152bool showFPS = true;
153static int globalVisibleId = 0;
154PerfTimer applicationTimer;
155
156float shotRays = .0f;
157/// the visibility solution is initialized at this number of rays shot that
158int visibilitySolutionInitialState = 0;
159
160Vector3 defaultAmbient(0.2f);
161Vector3 defaultDiffuse(1.0f);
162
163
164/// the technique used for rendering
165enum RenderTechnique
166{
167        FORWARD,
168        DEFERRED,
169        DEPTH_PASS
170};
171
172
173/// the used render type for this render pass
174enum RenderMethod
175{
176        RENDER_FORWARD,
177        RENDER_DEPTH_PASS,
178        RENDER_DEFERRED,
179        RENDER_DEPTH_PASS_DEFERRED,
180        RENDER_NUM_RENDER_TYPES
181};
182
183/// one of four possible render methods
184int renderMethod = RENDER_FORWARD;
185
186static int winWidth = 1024;
187static int winHeight = 768;
188static float winAspectRatio = 1.0f;
189
190/// these values get scaled with the frame rate
191static float keyForwardMotion = 30.0f;
192static float keyRotation = 1.5f;
193
194/// elapsed time in milliseconds
195double elapsedTime = 1000.0;
196double algTime = 1000.0;
197double accumulatedTime = 1000.0;
198float fps = 1e3f;
199float turbitity = 5.0f;
200
201// ssao parameters
202float ssaoKernelRadius = 1e-8f;
203float ssaoSampleIntensity = .2f;
204float ssaoFilterRadius = 3.0f;
205float ssaoTempCohFactor = 255.0;
206bool sortSamples = true;
207
208int shadowSize = 2048;
209
210/// the hud font
211glfont::GLFont myfont;
212
213// rendertexture
214int texWidth = 1024;
215int texHeight = 768;
216
217int renderedObjects = 0;
218int renderedNodes = 0;
219int renderedTriangles = 0;
220
221int issuedQueries = 0;
222int traversedNodes = 0;
223int frustumCulledNodes = 0;
224int queryCulledNodes = 0;
225int stateChanges = 0;
226int numBatches = 0;
227
228// mouse navigation renderState
229int xEyeBegin = 0;
230int yEyeBegin = 0;
231int yMotionBegin = 0;
232int verticalMotionBegin = 0;
233int horizontalMotionBegin = 0;
234
235bool leftKeyPressed = false;
236bool rightKeyPressed = false;
237bool upKeyPressed = false;
238bool downKeyPressed = false;
239bool descendKeyPressed = false;
240bool ascendKeyPressed = false;
241bool leftStrafeKeyPressed = false;
242bool rightStrafeKeyPressed = false;
243
244bool altKeyPressed = false;
245
246bool showHelp = false;
247bool showStatistics = false;
248bool showOptions = true;
249bool showBoundingVolumes = false;
250bool visMode = false;
251
252bool useOptimization = false;
253bool useTightBounds = true;
254bool useRenderQueue = true;
255bool useMultiQueries = true;
256bool flyMode = true;
257
258bool useGlobIllum = false;
259bool useTemporalCoherence = true;
260bool showAlgorithmTime = false;
261
262bool useFullScreen = false;
263bool useLODs = true;
264bool moveLight = false;
265
266bool useAdvancedShading = false;
267bool showShadowMap = false;
268bool renderLightView = false;
269bool useHDR = true;
270bool useAntiAliasing = true;
271bool useLenseFlare = true;
272
273bool usePvs = false;
274
275
276PerfTimer frameTimer, algTimer;
277/// the performance graph window
278PerformanceGraph *perfGraph = NULL;
279
280int sCurrentMrtSet = 0;
281static Matrix4x4 invTrafo = IdentityMatrix();
282float mouseMotion = 0.2f;
283
284float viewCellsScaleFactor = 1.0f;
285
286float maxConvergence = 2000.0f;
287float spatialWeight = 0.0001f;
288
289
290//////////////
291//-- chc++ algorithm parameters
292
293/// the pixel threshold where a node is still considered invisible
294/// (should be zero for conservative visibility)
295int threshold;
296int assumedVisibleFrames = 10;
297int maxBatchSize = 50;
298int trianglesPerVirtualLeaf = INITIAL_TRIANGLES_PER_VIRTUAL_LEAVES;
299
300
301//////////////
302
303enum {CAMERA_PASS = 0, LIGHT_PASS = 1};
304
305
306//DeferredRenderer::SAMPLING_METHOD samplingMethod = DeferredRenderer::SAMPLING_POISSON;
307DeferredRenderer::SAMPLING_METHOD samplingMethod = DeferredRenderer::SAMPLING_QUADRATIC;
308
309ShadowMap *shadowMap = NULL;
310DirectionalLight *light = NULL;
311DeferredRenderer *deferredShader = NULL;
312
313
314SceneEntity *buddha = NULL;
315SceneEntity *skyDome = NULL;
316SceneEntity *sunBox = NULL;
317
318GLuint sunQuery = 0;
319
320string walkThroughSuffix("frames");
321
322
323////////////////////
324//--- function forward declarations
325
326void InitExtensions();
327void InitGLstate();
328
329void DisplayVisualization();
330/// destroys all allocated resources
331void CleanUp();
332void SetupEyeView();
333void SetupLighting();
334void DisplayStats();
335/// draw the help screen
336void DrawHelpMessage();
337/// render the sky dome
338void RenderSky();
339/// render the objects found visible in the depth pass
340void RenderVisibleObjects();
341
342int TestSunVisible();
343
344void Begin2D();
345void End2D();
346/// the main loop
347void MainLoop();
348
349void KeyBoard(unsigned char c, int x, int y);
350void Special(int c, int x, int y);
351void KeyUp(unsigned char c, int x, int y);
352void SpecialKeyUp(int c, int x, int y);
353void Reshape(int w, int h);
354void Mouse(int button, int renderState, int x, int y);
355void LeftMotion(int x, int y);
356void RightMotion(int x, int y);
357void MiddleMotion(int x, int y);
358void KeyHorizontalMotion(float shift);
359void KeyVerticalMotion(float shift);
360/// returns the string representation of a number with the decimal points
361void CalcDecimalPoint(string &str, int d);
362/// Creates the traversal method (vfc, stopandwait, chc, chc++)
363RenderTraverser *CreateTraverser(PerspectiveCamera *cam);
364/// place the viewer on the floor plane
365void PlaceViewer(const Vector3 &oldPos);
366// initialise the frame buffer objects
367void InitFBO();
368/// changes the sunlight direction
369void RightMotionLight(int x, int y);
370/// render the shader map
371void RenderShadowMap(float newfar);
372/// function that touches each material once in order to accelarate render queue
373void PrepareRenderQueue();
374/// loads the specified model
375int LoadModel(const string &model, SceneEntityContainer &entities);
376
377inline float KeyRotationAngle() { return keyRotation * elapsedTime * 1e-3f; }
378inline float KeyShift() { return keyForwardMotion * elapsedTime * 1e-3f; }
379
380void CreateAnimation(const Vector3 &pos);
381
382SceneQuery *GetOrCreateSceneQuery();
383
384void LoadPvs();
385
386void LoadVisibilitySolution();
387
388void RenderViewCell();
389
390void LoadPompeiiFloor();
391
392void LoadOrUpdatePVSs(const Vector3 &pos);
393
394void CreateNewInstance(SceneEntity *parent, const Vector3 &pos);
395
396
397/////////////
398
399string envFileName = "default.env";
400
401float pvsTotalSamples = .0f;
402float pvsTotalTime = .0f;
403
404
405// new view projection matrix of the camera
406static Matrix4x4 viewProjMat = IdentityMatrix();
407// the old view projection matrix of the camera
408static Matrix4x4 oldViewProjMat = IdentityMatrix();
409
410
411
412static void PrintGLerror(char *msg)
413{
414        GLenum errCode;
415        const GLubyte *errStr;
416       
417        if ((errCode = glGetError()) != GL_NO_ERROR)
418        {
419                errStr = gluErrorString(errCode);
420                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
421        }
422}
423
424
425int main(int argc, char* argv[])
426{
427#ifdef _CRT_SET
428        //Now just call this function at the start of your program and if you're
429        //compiling in debug mode (F5), any leaks will be displayed in the Output
430        //window when the program shuts down. If you're not in debug mode this will
431        //be ignored. Use it as you will!
432        //note: from GDNet Direct [3.8.04 - 3.14.04] void detectMemoryLeaks() {
433
434        _CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF|_CRTDBG_ALLOC_MEM_DF);
435        _CrtSetReportMode(_CRT_ASSERT,_CRTDBG_MODE_FILE);
436        _CrtSetReportFile(_CRT_ASSERT,_CRTDBG_FILE_STDERR);
437#endif
438
439
440        int returnCode = 0;
441
442        Vector3 camPos(.0f, .0f, .0f);
443        Vector3 camDir(.0f, 1.0f, .0f);
444        Vector3 lightDir(-0.8f, 1.0f, -0.7f);
445
446        if (argc > 1) envFileName = argv[1];
447
448        cout << "=== reading environment file " << envFileName << " ===" << endl << endl;
449
450        if (!env.Read(envFileName))
451        {
452                cerr << "loading environment " << envFileName << " failed!" << endl;
453        }
454        else
455        {
456                env.GetIntParam(string("assumedVisibleFrames"), assumedVisibleFrames);
457                env.GetIntParam(string("maxBatchSize"), maxBatchSize);
458                env.GetIntParam(string("trianglesPerVirtualLeaf"), trianglesPerVirtualLeaf);
459                env.GetIntParam(string("winWidth"), winWidth);
460                env.GetIntParam(string("winHeight"), winHeight);
461                env.GetIntParam(string("shadowSize"), shadowSize);
462                env.GetIntParam(string("maxDepthForTestingChildren"), maxDepthForTestingChildren);
463
464                env.GetFloatParam(string("keyForwardMotion"), keyForwardMotion);
465                env.GetFloatParam(string("keyRotation"), keyRotation);
466                env.GetFloatParam(string("mouseMotion"), mouseMotion);
467                env.GetFloatParam(string("tempCohFactor"), ssaoTempCohFactor);
468                env.GetFloatParam(string("turbitity"), turbitity);
469               
470                env.GetVectorParam(string("camPosition"), camPos);
471                env.GetVectorParam(string("camDirection"), camDir);
472                env.GetVectorParam(string("lightDirection"), lightDir);
473                env.GetVectorParam(string("defaultAmbient"), defaultAmbient);
474                env.GetVectorParam(string("defaultDiffuse"), defaultDiffuse);
475
476                env.GetBoolParam(string("useFullScreen"), useFullScreen);
477                env.GetBoolParam(string("useLODs"), useLODs);
478                env.GetBoolParam(string("useHDR"), useHDR);
479                env.GetBoolParam(string("useAA"), useAntiAliasing);
480                env.GetBoolParam(string("useLenseFlare"), useLenseFlare);
481                env.GetBoolParam(string("useAdvancedShading"), useAdvancedShading);
482
483                env.GetIntParam(string("renderMethod"), renderMethod);
484
485                env.GetFloatParam(string("ssaoKernelRadius"), ssaoKernelRadius);
486                env.GetFloatParam(string("ssaoSampleIntensity"), ssaoSampleIntensity);
487                env.GetBoolParam(string("ssaoUseFullResolution"), ssaoUseFullResolution);
488
489                env.GetStringParam(string("recordedFramesSuffix"), recordedFramesSuffix);
490                env.GetStringParam(string("walkThroughSuffix"), walkThroughSuffix);
491                env.GetStringParam(string("statsFilename"), statsFilename);
492                env.GetStringParam(string("filename"), filename);
493                env.GetStringParam(string("bvhname"), bvhname);
494                env.GetStringParam(string("visibilitySolution"), visibilitySolution);
495
496                env.GetBoolParam(string("usePvs"), usePvs);
497                env.GetBoolParam(string("useSkylightForIllum"), useSkylightForIllum);
498                env.GetFloatParam(string("viewCellsScaleFactor"), viewCellsScaleFactor);
499                env.GetFloatParam(string("skyDomeScaleFactor"), skyDomeScaleFactor);
500                env.GetIntParam(string("visibilitySolutionInitialState"), visibilitySolutionInitialState);
501                env.GetIntParam(string("renderMode"), renderMode);
502               
503                //env.GetStringParam(string("modelPath"), model_path);
504                //env.GetIntParam(string("numSssaoSamples"), numSsaoSamples);
505
506                texWidth = winWidth;
507                texHeight = winHeight;
508
509                cout << "assumed visible frames: " << assumedVisibleFrames << endl;
510                cout << "max batch size: " << maxBatchSize << endl;
511                cout << "triangles per virtual leaf: " << trianglesPerVirtualLeaf << endl;
512
513                cout << "static scene filename prefix: " << filename << endl;
514                cout << "bvh filename prefix: " << bvhname << endl;
515
516                cout << "key forward motion: " << keyForwardMotion << endl;
517                cout << "key rotation: " << keyRotation << endl;
518                cout << "win width: " << winWidth << endl;
519                cout << "win height: " << winHeight << endl;
520                cout << "use full screen: " << useFullScreen << endl;
521                cout << "use LODs: " << useLODs << endl;
522                cout << "camera position: " << camPos << endl;
523                cout << "shadow size: " << shadowSize << endl;
524                cout << "render method: " << renderMethod << endl;
525                cout << "use antialiasing: " << useAntiAliasing << endl;
526                cout << "use lense flare: " << useLenseFlare << endl;
527                cout << "use advanced shading: " << useAdvancedShading << endl;
528                cout << "turbitity: " << turbitity << endl;
529                cout << "temporal coherence factor: " << ssaoTempCohFactor << endl;
530                cout << "sample intensity: " << ssaoSampleIntensity << endl;
531                cout << "kernel radius: " << ssaoKernelRadius << endl;
532                cout << "use ssao full resolution: " << ssaoUseFullResolution << endl;
533                cout << "recorded frames suffix: " << recordedFramesSuffix << endl;
534                cout << "walkthrough suffix: " << walkThroughSuffix << endl;
535                cout << "stats filename: " << statsFilename << endl;
536                cout << "use PVSs: " << usePvs << endl;
537                cout << "visibility solution: " << visibilitySolution << endl;
538                cout << "view cells scale factor: " << viewCellsScaleFactor << endl;
539                cout << "use skylight for illumination: " << useSkylightForIllum << endl;
540                cout << "sky dome scale factor: " << skyDomeScaleFactor << endl;
541                cout << "rendermode: " << renderMode << endl;
542
543                //cout << "model path: " << model_path << endl;
544                cout << "==== end parameters ====" << endl << endl;
545        }
546
547        ///////////////////////////
548
549        camera = new PerspectiveCamera(winWidth / winHeight, fov);
550        camera->SetNear(nearDist);
551        camera->SetFar(1e6f);
552
553        camera->SetDirection(camDir);
554        camera->SetPosition(camPos);
555
556        visCamera = new PerspectiveCamera(winWidth / winHeight, fov);
557        visCamera->SetNear(.0f);
558        visCamera->Yaw(.5 * M_PI);
559
560        // create a new light
561        light = new DirectionalLight(lightDir, RgbaColor(1, 1, 1, 1), RgbaColor(1, 1, 1, 1));
562        // the render queue for material sorting
563        renderQueue = new RenderQueue(&renderState);
564
565        glutInitWindowSize(winWidth, winHeight);
566        glutInit(&argc, argv);
567        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_MULTISAMPLE);
568        //glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
569        //glutInitDisplayString("samples=2");
570
571        SceneEntity::SetUseLODs(useLODs);
572
573
574        if (!useFullScreen)
575        {
576                glutCreateWindow("FriendlyCulling");
577        }
578        else
579        {
580                glutGameModeString( "1024x768:32@75" );
581                glutEnterGameMode();
582        }
583
584        glutDisplayFunc(MainLoop);
585        glutKeyboardFunc(KeyBoard);
586        glutSpecialFunc(Special);
587        glutReshapeFunc(Reshape);
588        glutMouseFunc(Mouse);
589        glutIdleFunc(MainLoop);
590        glutKeyboardUpFunc(KeyUp);
591        glutSpecialUpFunc(SpecialKeyUp);
592        glutIgnoreKeyRepeat(true);
593
594        // initialise gl graphics
595        InitExtensions();
596        InitGLstate();
597
598        glEnable(GL_MULTISAMPLE_ARB);
599        glHint(GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);
600
601        LeftMotion(0, 0);
602        MiddleMotion(0, 0);
603
604        perfGraph = new PerformanceGraph(1000);
605
606        resourceManager = ResourceManager::GetSingleton();
607        shaderManager = ShaderManager::GetSingleton();
608
609
610        ///////////
611        //-- load the static scene geometry
612
613        LoadModel(filename + ".dem", staticObjects);
614
615
616        //////////
617        //-- load some dynamic stuff
618
619        //resourceManager->mUseNormalMapping = true;
620        //resourceManager->mUseNormalMapping = false;
621        resourceManager->mUseSpecialColors = true;
622
623        //LoadModel("fisch.dem", dynamicObjects);
624
625        //LoadModel("venusm.dem", dynamicObjects);
626        //LoadModel("camel.dem", dynamicObjects);
627        //LoadModel("toyplane2.dem", dynamicObjects);
628        //LoadModel("elephal.dem", dynamicObjects);
629
630        if (1) LoadPompeiiFloor();
631
632#if 1
633
634#if 0
635        // vienna positions
636        VertexArray positions;
637        positions.push_back(Vector3(478.398f, 268.0f, 181.3));
638        positions.push_back(Vector3(470.461, 268.543, 181.7));
639        positions.push_back(Vector3(499.648, 264.358, 181.7));
640        positions.push_back(Vector3(487.913, 285.162, 181.7));
641
642#else
643
644        // sibenik positions
645        VertexArray positions;
646        //const float factor2 = 1.6f;
647        const float factor2 = 1.5f;
648
649        // for buddha (lowres)
650        positions.push_back(Vector3(6.07307, 8.20723, 6.62 - factor2));
651        positions.push_back(Vector3(-17.1935, 11.1687, 8.8781 - factor2));
652        //positions.push_back(Vector3(1.50032, 31.1943, 19.1f));
653
654        // for happy buddha
655        //positions.push_back(Vector3(6.07307, 8.20723, 4.6f));
656        //positions.push_back(Vector3(-17.1935, 11.1687, 6.8f));
657        //positions.push_back(Vector3(1.50032, 31.1943, 17.6f));
658
659        // for dragon
660        //positions.push_back(Vector3(6.07307, 8.20723, 5.0f));
661        //positions.push_back(Vector3(0, 0, -0.8f));
662
663#endif
664
665        //const Vector3 sceneCenter(470.398f, 240.364f, 180.3);
666        Matrix4x4 transl = TranslationMatrix(positions[0]);
667        //LoadModel("dragon.dem", dynamicObjects);
668
669#if 1
670
671        //LoadModel("hbuddha.dem", dynamicObjects);
672        //LoadModel("horse.dem", dynamicObjects);
673        LoadModel("happy2.dem", dynamicObjects);
674        //LoadModel("torus.dem", dynamicObjects);
675        //LoadModel("venusm.dem", dynamicObjects);
676
677        buddha = dynamicObjects.back();
678        buddha->GetTransform()->SetMatrix(transl);
679
680       
681        for (size_t i = 1; i < positions.size(); ++ i)
682        {
683                CreateNewInstance(buddha, positions[i]);
684        }
685
686
687        const float rotAngle = M_PI / 2.0f;
688        const Matrix4x4 rotMatrix = RotationXMatrix(rotAngle);
689        const Matrix4x4 scaleMatrix = ScaleMatrix(14, 14, 14);
690
691        // hack: second buddha
692        dynamicObjects[0]->GetTransform()->MultMatrix(rotMatrix);
693        //dynamicObjects[0]->GetTransform()->MultMatrix(scaleMatrix);
694
695        /*dynamicObjects[1]->GetTransform()->MultMatrix(rotMatrix);
696        dynamicObjects[1]->GetTransform()->MultMatrix(scaleMatrix);
697
698        dynamicObjects[2]->GetTransform()->MultMatrix(rotMatrix);
699        dynamicObjects[2]->GetTransform()->MultMatrix(scaleMatrix);
700
701        cout << "dynamic objects: " << (int)dynamicObjects.size() << endl;
702        */
703        CreateAnimation(positions[0]);
704
705#endif
706#endif
707        // hack
708        resourceManager->mUseNormalMapping = false;
709        resourceManager->mUseSpecialColors = false;
710
711
712        ///////////
713        //-- load the associated static bvh
714
715        BvhFactory bvhFactory;
716
717        if (bvhname != "")
718        {
719                cout << "loading bvh from disc" << endl;
720                const string bvh_fullpath = string(model_path + bvhname + ".bvh");
721                bvh = bvhFactory.Create(bvh_fullpath, staticObjects, dynamicObjects, maxDepthForTestingChildren);
722
723                if (!bvh)
724                {
725                        cerr << "loading bvh " << bvh_fullpath << " failed" << endl;
726                        CleanUp();
727                        exit(0);
728                }
729        }
730        else
731        {
732                cout << "creating new bvh" << endl;
733                bvh = bvhFactory.Create(staticObjects, dynamicObjects, maxDepthForTestingChildren);
734        }
735
736        /// set the depth of the bvh depending on the triangles per leaf node
737        bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
738
739        // set far plane based on scene extent
740        farDist = 10.0f * Magnitude(bvh->GetBox().Diagonal());
741        //farDist = 1000.0f;
742        camera->SetFar(farDist);
743
744
745        //ObjExporter().Export(model_path + "mytest.obj", bvh);
746        //BvhExporter().Export(model_path + "mytest.bv", bvh);
747
748
749
750        //////////////////
751        //-- setup the skydome model
752
753        LoadModel("sky.dem", staticObjects);
754        skyDome = staticObjects.back();
755
756        /// the turbitity of the sky (from clear to hazy, use <3 for clear sky)
757        preetham = new SkyPreetham(turbitity, skyDome);
758
759
760        //////////////////////////
761        //-- a bounding box representing the sun pos in order to test visibility
762
763        Transform3 *trafo = resourceManager->CreateTransform(IdentityMatrix());
764
765        // make it slightly bigger to simulate sun diameter
766        const float size = 25.0f;
767        AxisAlignedBox3 sbox(Vector3(-size), Vector3(size));
768
769        SceneEntityConverter conv;
770
771
772        //////////////////
773        //-- occlusion query for sun
774
775        Material *mat = resourceManager->CreateMaterial();
776
777        mat->GetTechnique(0)->SetDepthWriteEnabled(false);
778        mat->GetTechnique(0)->SetColorWriteEnabled(false);
779
780        sunBox = conv.ConvertBox(sbox, mat, trafo);
781        resourceManager->AddSceneEntity(sunBox);
782
783        /// create single occlusion query that handles sun visibility
784        glGenQueriesARB(1, &sunQuery);
785
786
787        //////////
788        //-- initialize the traversal algorithm
789
790        traverser = CreateTraverser(camera);
791       
792        // the bird-eye visualization
793        visualization = new Visualization(bvh, camera, NULL, &renderState);
794
795        // this function assign the render queue bucket ids of the materials in beforehand
796        // => probably less overhead for new parts of the scene that are not yet assigned
797        PrepareRenderQueue();
798        /// forward rendering is the default
799        renderState.SetRenderTechnique(FORWARD);
800        // frame time is restarted every frame
801        frameTimer.Start();
802
803        //Halton::TestHalton(7, 2);
804        //HaltonSequence::TestHalton(15, 2);
805        //Halton::TestPrime();
806
807        // the rendering loop
808        glutMainLoop();
809       
810        // clean up
811        CleanUp();
812       
813        return 0;
814}
815
816
817void InitFBO()
818{
819        PrintGLerror("fbo start");
820
821        // this fbo basicly stores the scene information we get from standard rendering of a frame
822        // we store diffuse colors, eye space depth and normals
823        fbo = new FrameBufferObject(texWidth, texHeight, FrameBufferObject::DEPTH_32);
824
825        // the diffuse color buffer
826        fbo->AddColorBuffer(ColorBufferObject::RGBA_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, ColorBufferObject::FILTER_NEAREST);
827        // the normals buffer
828        //fbo->AddColorBuffer(ColorBufferObject::RGB_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST);
829        fbo->AddColorBuffer(ColorBufferObject::RGB_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
830        // a rgb buffer which could hold material properties
831        //fbo->AddColorBuffer(ColorBufferObject::RGB_UBYTE, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_NEAREST);
832        // buffer holding the difference vector to the old frame
833        fbo->AddColorBuffer(ColorBufferObject::RGB_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
834        //fbo->AddColorBuffer(ColorBufferObject::RGB_UBYTE, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
835        // another color buffer
836        fbo->AddColorBuffer(ColorBufferObject::RGBA_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, ColorBufferObject::FILTER_NEAREST);
837
838        for (int i = 0; i < 4; ++ i)
839        {
840                FrameBufferObject::InitBuffer(fbo, i);
841        }
842
843        PrintGLerror("init fbo");
844}
845
846
847bool InitFont(void)
848{
849        glEnable(GL_TEXTURE_2D);
850
851        glGenTextures(1, &fontTex);
852        glBindTexture(GL_TEXTURE_2D, fontTex);
853
854        if (!myfont.Create("data/fonts/verdana.glf", fontTex))
855                return false;
856
857        glDisable(GL_TEXTURE_2D);
858       
859        return true;
860}
861
862
863void InitGLstate()
864{
865        glClearColor(0.4f, 0.4f, 0.4f, 1e20f);
866       
867        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
868        glPixelStorei(GL_PACK_ALIGNMENT,1);
869       
870        glDepthFunc(GL_LESS);
871        glEnable(GL_DEPTH_TEST);
872
873        glColor3f(1.0f, 1.0f, 1.0f);
874        glShadeModel(GL_SMOOTH);
875       
876        glMaterialf(GL_FRONT, GL_SHININESS, 64);
877        glEnable(GL_NORMALIZE);
878               
879        glDisable(GL_ALPHA_TEST);
880        glAlphaFunc(GL_GEQUAL, 0.5f);
881
882        glFrontFace(GL_CCW);
883        glCullFace(GL_BACK);
884        glEnable(GL_CULL_FACE);
885
886        glDisable(GL_TEXTURE_2D);
887
888        GLfloat ambientColor[] = {0.2, 0.2, 0.2, 1.0};
889        GLfloat diffuseColor[] = {1.0, 0.0, 0.0, 1.0};
890        GLfloat specularColor[] = {0.0, 0.0, 0.0, 1.0};
891
892        glMaterialfv(GL_FRONT, GL_AMBIENT, ambientColor);
893        glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor);
894        glMaterialfv(GL_FRONT, GL_SPECULAR, specularColor);
895
896        glDepthFunc(GL_LESS);
897
898        if (!InitFont())
899                cerr << "font creation failed" << endl;
900        else
901                cout << "successfully created font" << endl;
902
903
904        //////////////////////////////
905
906        //GLfloat lmodel_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
907        GLfloat lmodel_ambient[] = {0.7f, 0.7f, 0.8f, 1.0f};
908
909        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
910        //glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
911        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
912        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SINGLE_COLOR_EXT);
913}
914
915
916void DrawHelpMessage()
917{
918        const char *message[] =
919        {
920                "Help information",
921                "",
922                "'F1'           - shows/dismisses this message",
923                "'F2'           - shows/hides bird eye view",
924                "'F3'           - shows/hides bounds (boxes or tight bounds)",
925                "'F4',          - shows/hides parameters",
926                "'F5'           - shows/hides statistics",
927                "'F6',          - toggles between fly/walkmode",
928                "'F7',          - cycles throw render modes",
929                "'F8',          - enables/disables ambient occlusion (only deferred)",
930                "'F9',          - shows pure algorithm render time (using glFinish)",
931                "'SPACE'        - cycles through occlusion culling algorithms",
932                "",
933                "'MOUSE LEFT'        - turn left/right, move forward/backward",
934                "'MOUSE RIGHT'       - turn left/right, move forward/backward",
935                "'MOUSE MIDDLE'      - move up/down, left/right",
936                "'CURSOR UP/DOWN'    - move forward/backward",
937                "'CURSOR LEFT/RIGHT' - turn left/right",
938                "",
939                "'-'/'+'        - decreases/increases max batch size",
940                "'1'/'2'        - downward/upward motion",
941                "'3'/'4'        - decreases/increases triangles per virtual bvh leaf (sets bvh depth)",
942                "'5'/'6'        - decreases/increases assumed visible frames",
943                "",
944                "'R'            - use render queue",
945                "'B'            - use tight bounds",
946                "'M'            - use multiqueries",
947                "'O'            - use CHC optimization (geometry queries for leaves)",
948                0,
949        };
950       
951       
952        glColor4f(0.0f, 1.0f , 0.0f, 0.2f); // 20% green.
953
954        glRecti(30, 30, winWidth - 30, winHeight - 30);
955
956        glEnd();
957
958        glColor3f(1.0f, 1.0f, 1.0f);
959       
960        glEnable(GL_TEXTURE_2D);
961        myfont.Begin();
962
963        int x = 40, y = 30;
964
965        for(int i = 0; message[i] != 0; ++ i)
966        {
967                if(message[i][0] == '\0')
968                {
969                        y += 15;
970                }
971                else
972                {
973                        myfont.DrawString(message[i], x, winHeight - y);
974                        y += 25;
975                }
976        }
977        glDisable(GL_TEXTURE_2D);
978}
979
980
981RenderTraverser *CreateTraverser(PerspectiveCamera *cam)
982{
983        RenderTraverser *tr;
984       
985        switch (renderMode)
986        {
987        case RenderTraverser::CULL_FRUSTUM:
988                tr = new FrustumCullingTraverser();
989                break;
990        case RenderTraverser::STOP_AND_WAIT:
991                tr = new StopAndWaitTraverser();
992                break;
993        case RenderTraverser::CHC:
994                tr = new CHCTraverser();
995                break;
996        case RenderTraverser::CHCPLUSPLUS:
997                tr = new CHCPlusPlusTraverser();
998                break;
999        //case RenderTraverser::CULL_COLLECTOR:
1000        //      tr = new PvsCollectionRenderer();
1001        //      break;
1002        default:
1003                tr = new FrustumCullingTraverser();
1004        }
1005
1006        tr->SetCamera(cam);
1007        tr->SetHierarchy(bvh);
1008        tr->SetRenderQueue(renderQueue);
1009        tr->SetRenderState(&renderState);
1010        tr->SetUseOptimization(useOptimization);
1011        tr->SetUseRenderQueue(useRenderQueue);
1012        tr->SetVisibilityThreshold(threshold);
1013        tr->SetAssumedVisibleFrames(assumedVisibleFrames);
1014        tr->SetMaxBatchSize(maxBatchSize);
1015        tr->SetUseMultiQueries(useMultiQueries);
1016        tr->SetUseTightBounds((renderMode == RenderTraverser::CHCPLUSPLUS) && useTightBounds);
1017        tr->SetUseDepthPass((renderMethod == RENDER_DEPTH_PASS) || (renderMethod == RENDER_DEPTH_PASS_DEFERRED));
1018        tr->SetRenderQueue(renderQueue);
1019        tr->SetShowBounds(showBoundingVolumes);
1020
1021        bvh->ResetNodeClassifications();
1022
1023
1024        return tr;
1025}
1026
1027/** Setup lighting conditions
1028*/
1029void SetupLighting()
1030{
1031        glEnable(GL_LIGHT0);
1032        glDisable(GL_LIGHT1);
1033       
1034        Vector3 lightDir = -light->GetDirection();
1035
1036
1037        ///////////
1038        //-- first light: sunlight
1039
1040        GLfloat ambient[] = {0.25f, 0.25f, 0.3f, 1.0f};
1041        GLfloat diffuse[] = {1.0f, 0.95f, 0.85f, 1.0f};
1042        GLfloat specular[] = {1.0f, 1.0f, 1.0f, 1.0f};
1043       
1044
1045        const bool useHDRValues =
1046                ((renderMethod == RENDER_DEPTH_PASS_DEFERRED) ||
1047                 (renderMethod == RENDER_DEFERRED)) && useHDR;
1048
1049
1050        Vector3 sunAmbient;
1051        Vector3 sunDiffuse;
1052
1053        if (useSkylightForIllum)
1054        {
1055                preetham->ComputeSunColor(lightDir, sunAmbient, sunDiffuse, !useHDRValues);
1056
1057                ambient[0] = sunAmbient.x;
1058                ambient[1] = sunAmbient.y;
1059                ambient[2] = sunAmbient.z;
1060
1061                diffuse[0] = sunDiffuse.x;
1062                diffuse[1] = sunDiffuse.y;
1063                diffuse[2] = sunDiffuse.z;
1064        }
1065        else
1066        {
1067                ambient[0] = defaultAmbient.x;
1068                ambient[1] = defaultAmbient.y;
1069                ambient[2] = defaultAmbient.z;
1070
1071                diffuse[0] = defaultDiffuse.x;
1072                diffuse[1] = defaultDiffuse.y;
1073                diffuse[2] = defaultDiffuse.z;
1074        }
1075
1076        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
1077        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
1078        glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
1079
1080        GLfloat position[] = {lightDir.x, lightDir.y, lightDir.z, 0.0f};
1081        glLightfv(GL_LIGHT0, GL_POSITION, position);
1082}
1083
1084
1085void SetupEyeView()
1086{
1087        // store matrix of last frame
1088        oldViewProjMat = viewProjMat;
1089
1090        camera->SetupViewProjection();
1091
1092
1093        /////////////////
1094        //-- compute view projection matrix and store for later use
1095
1096        Matrix4x4 matViewing, matProjection;
1097
1098        camera->GetModelViewMatrix(matViewing);
1099        camera->GetProjectionMatrix(matProjection);
1100
1101        viewProjMat = matViewing * matProjection;
1102}
1103
1104
1105void KeyHorizontalMotion(float shift)
1106{
1107        Vector3 hvec = -camera->GetDirection();
1108        hvec.z = 0;
1109
1110        Vector3 pos = camera->GetPosition();
1111        pos += hvec * shift;
1112       
1113        camera->SetPosition(pos);
1114}
1115
1116
1117void KeyVerticalMotion(float shift)
1118{
1119        Vector3 uvec = Vector3(0, 0, shift);
1120
1121        Vector3 pos = camera->GetPosition();
1122        pos += uvec;
1123       
1124        camera->SetPosition(pos);
1125}
1126
1127
1128void KeyStrafe(float shift)
1129{
1130        Vector3 viewDir = camera->GetDirection();
1131        Vector3 pos = camera->GetPosition();
1132
1133        // the 90 degree rotated view vector
1134        // z zero so we don't move in the vertical
1135        Vector3 rVec(viewDir[0], viewDir[1], 0);
1136
1137        Matrix4x4 rot = RotationZMatrix(M_PI * 0.5f);
1138        rVec = rot * rVec;
1139        pos += rVec * shift;
1140
1141        camera->SetPosition(pos);
1142}
1143
1144
1145/** Initialize the deferred rendering pass.
1146*/
1147void InitDeferredRendering()
1148{
1149        if (!fbo) InitFBO();
1150        fbo->Bind();
1151
1152        // multisampling does not work with deferred shading
1153        glDisable(GL_MULTISAMPLE_ARB);
1154        renderState.SetRenderTechnique(DEFERRED);
1155
1156
1157        // draw to 3 render targets
1158        if (sCurrentMrtSet == 0)
1159        {
1160                DeferredRenderer::colorBufferIdx = 0;
1161                glDrawBuffers(3, mrt);
1162        }
1163        else
1164        {
1165                DeferredRenderer::colorBufferIdx = 3;
1166                glDrawBuffers(3, mrt2);
1167        }
1168
1169        sCurrentMrtSet = 1 - sCurrentMrtSet;
1170}
1171
1172
1173/** the main rendering loop
1174*/
1175void MainLoop()
1176{       
1177        for (size_t i = 0; i < dynamicObjects.size(); ++ i)
1178                dynamicObjects[i]->GetTransform()->InitFrame();
1179
1180        if (buddha)
1181        {
1182                Matrix4x4 oldTrafo = buddha->GetTransform()->GetMatrix();
1183                Vector3 buddhaPos = motionPath->GetCurrentPosition();
1184                Matrix4x4 trafo = TranslationMatrix(buddhaPos);
1185
1186                buddha->GetTransform()->SetMatrix(trafo);
1187
1188                const float rotAngle3 = M_PI / 2.0f;
1189                const Matrix4x4 rotMatrix3 = RotationZMatrix(rotAngle3);
1190
1191                // hack: second buddha
1192                buddha->GetTransform()->MultMatrix(rotMatrix3);
1193
1194#if TODO // drop objects on ground floor
1195                for (int i = 0; i < 10; ++ i)
1196                {
1197                        SceneEntity *ent = dynamicObjects[i];
1198                        Vector3 newPos = ent->GetWorldCenter();
1199
1200                        if (GetOrCreateSceneQuery()->CalcIntersection(newPos))
1201                        {
1202                                Matrix4x4 mat = TranslationMatrix(newPos - ent->GetCenter());
1203                                ent->GetTransform()->SetMatrix(mat);
1204                        }
1205                }
1206#endif
1207
1208                /////////////////////////
1209                //-- update animations
1210
1211
1212                //const float rotAngle = M_PI * 1e-3f;
1213                //const float rotAngle = 1.5f * M_PI / 180.0f;
1214                const float rotAngle = 0.6f * M_PI / 180.0f;
1215
1216                Matrix4x4 rotMatrix = RotationZMatrix(rotAngle);
1217                // hack: second buddha
1218                dynamicObjects[1]->GetTransform()->MultMatrix(rotMatrix);
1219
1220                // hack: second buddha
1221                const float rotAngle2 = 0.0033f * M_PI;
1222                Matrix4x4 rotMatrix2 = RotationZMatrix(rotAngle);
1223                //dynamicObjects[3]->GetTransform()->MultMatrix(rotMatrix2);
1224
1225                //const float moveSpeed = 5e-3f;
1226                const float moveSpeed = 5e-1f;
1227                motionPath->Move(moveSpeed);
1228        }
1229
1230
1231        /////////////
1232
1233        static Vector3 oldPos = camera->GetPosition();
1234        static Vector3 oldDir = camera->GetDirection();
1235
1236        if (leftKeyPressed)
1237                camera->Pitch(KeyRotationAngle());
1238        if (rightKeyPressed)
1239                camera->Pitch(-KeyRotationAngle());
1240        if (upKeyPressed)
1241                KeyHorizontalMotion(-KeyShift());
1242        if (downKeyPressed)
1243                KeyHorizontalMotion(KeyShift());
1244        if (ascendKeyPressed)
1245                KeyVerticalMotion(KeyShift());
1246        if (descendKeyPressed)
1247                KeyVerticalMotion(-KeyShift());
1248        if (leftStrafeKeyPressed)
1249                KeyStrafe(KeyShift());
1250        if (rightStrafeKeyPressed)
1251                KeyStrafe(-KeyShift());
1252
1253
1254        // place view on ground
1255        if (!flyMode) PlaceViewer(oldPos);
1256
1257        if (showAlgorithmTime)
1258        {
1259                glFinish();
1260                algTimer.Start();
1261        }
1262       
1263        // don't allow replay on record
1264        if (replayPath && !recordPath)
1265        {
1266                if (!walkThroughPlayer)
1267                        walkThroughPlayer = new WalkThroughPlayer(walkThroughSuffix + ".log");
1268               
1269                ++ currentReplayFrame;
1270
1271                // reset if end of walkthrough is reached
1272                if (!walkThroughPlayer->ReadNextFrame(camera))
1273                {
1274                        cout << "reached end of walkthrough" << endl;
1275                        currentReplayFrame = -1;
1276                        replayPath = false;
1277                }
1278        }
1279
1280        if ((!shadowMap || !shadowTraverser) && (showShadowMap || renderLightView))
1281        {
1282                if (!shadowMap)
1283                        shadowMap = new ShadowMap(light, shadowSize, bvh->GetBox(), camera);
1284
1285                if (!shadowTraverser)
1286                        shadowTraverser = CreateTraverser(shadowMap->GetShadowCamera());
1287
1288        }
1289       
1290        // bring eye modelview matrix up-to-date
1291        SetupEyeView();
1292       
1293
1294        // set frame related parameters for GPU programs
1295        GPUProgramParameters::InitFrame(camera, light);
1296
1297        if (recordPath)
1298        {
1299                if (!walkThroughRecorder)
1300                {
1301                        walkThroughRecorder = new WalkThroughRecorder(walkThroughSuffix + ".log");
1302                }
1303
1304                // question: check if player has moved more than a minimum distance?
1305
1306                if (0 ||
1307                        (Distance(oldPos, camera->GetPosition()) > 1e-6f) ||
1308                        (DotProd(oldDir, camera->GetDirection()) < 1.0f - 1e-6f))
1309                {
1310                        walkThroughRecorder->WriteFrame(camera);
1311                }
1312        }
1313
1314        // hack: store current rendering method and restore later
1315        int oldRenderMethod = renderMethod;
1316        // for rendering the light view, we use forward rendering
1317        if (renderLightView) renderMethod = FORWARD;
1318
1319        /// enable vbo vertex array
1320        glEnableClientState(GL_VERTEX_ARRAY);
1321
1322        if (usePvs) LoadOrUpdatePVSs(camera->GetPosition());
1323
1324
1325        // render with the specified method (forward rendering, forward + depth, deferred)
1326        switch (renderMethod)
1327        {
1328        case RENDER_FORWARD:
1329       
1330                glEnable(GL_MULTISAMPLE_ARB);
1331                renderState.SetRenderTechnique(FORWARD);
1332               
1333                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1334                glEnableClientState(GL_NORMAL_ARRAY);
1335                break;
1336
1337        case RENDER_DEPTH_PASS_DEFERRED:
1338
1339                glDisable(GL_MULTISAMPLE_ARB);
1340                renderState.SetUseAlphaToCoverage(false);
1341                renderState.SetRenderTechnique(DEPTH_PASS);
1342
1343                if (!fbo) InitFBO();
1344                fbo->Bind();
1345                // render to single depth texture
1346                glDrawBuffers(1, mrt);
1347                // clear buffer once
1348                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1349
1350                // the scene is rendered withouth any shading
1351                // (should be handled by render renderState)
1352                glShadeModel(GL_FLAT);
1353                break;
1354
1355        case RENDER_DEPTH_PASS:
1356
1357                glEnable(GL_MULTISAMPLE_ARB);
1358                renderState.SetRenderTechnique(DEPTH_PASS);
1359
1360                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1361
1362                // the scene is rendered withouth any shading
1363                // (should be handled by render renderState)
1364                glShadeModel(GL_FLAT);
1365                break;
1366       
1367        case RENDER_DEFERRED:
1368
1369                if (showShadowMap && !renderLightView)
1370                {
1371                        RenderShadowMap(camera->GetFar());
1372                }
1373
1374                //glPushAttrib(GL_VIEWPORT_BIT);
1375                glViewport(0, 0, texWidth, texHeight);
1376
1377                InitDeferredRendering();
1378               
1379                glEnableClientState(GL_NORMAL_ARRAY);
1380                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1381                break;
1382        }
1383
1384        glDepthFunc(GL_LESS);
1385        glDisable(GL_TEXTURE_2D);
1386        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1387               
1388
1389        // set proper lod levels for current frame using current eye point
1390        LODLevel::InitFrame(camera->GetPosition());
1391        // set up sunlight
1392        SetupLighting();
1393
1394
1395        if (renderLightView)
1396        {
1397                // change CHC++ set of renderState variables:
1398                // must be done for each change of camera because otherwise
1399                // the temporal coherency is broken
1400                BvhNode::SetCurrentState(LIGHT_PASS);
1401                shadowMap->RenderShadowView(shadowTraverser, viewProjMat);
1402                BvhNode::SetCurrentState(CAMERA_PASS);
1403        }
1404        else
1405        {
1406                //if (traverser->GetType() == RenderTraverser::CULL_COLLECTOR)
1407                //      ((PvsCollectionRenderer *)traverser)->SetViewCell(usePvs ? viewCell : NULL);
1408
1409                // actually render the scene geometry using the specified algorithm
1410                traverser->RenderScene();
1411        }
1412
1413
1414        /////////
1415        //-- do the rest of the rendering
1416       
1417        // return from depth pass and render visible objects
1418        if ((renderMethod == RENDER_DEPTH_PASS) ||
1419                (renderMethod == RENDER_DEPTH_PASS_DEFERRED))
1420        {
1421                RenderVisibleObjects();
1422        }
1423
1424        const bool useDeferred =
1425                ((renderMethod == RENDER_DEFERRED) || (renderMethod == RENDER_DEPTH_PASS_DEFERRED));
1426
1427        // if no lense flare => just set sun to invisible
1428        const int sunVisiblePixels = useLenseFlare  &&  useDeferred ? TestSunVisible() : 0;
1429
1430       
1431
1432        ///////////////
1433        //-- render sky
1434
1435        // q: should we render sky after deferred shading?
1436        // this would conveniently solves some issues (e.g, skys without shadows)
1437
1438        RenderSky();
1439
1440
1441        //////////////////////////////
1442
1443        if (useDeferred)
1444        {
1445                FrameBufferObject::Release();
1446
1447                if (!deferredShader)
1448                {
1449                        deferredShader =
1450                                new DeferredRenderer(texWidth, texHeight, camera, ssaoUseFullResolution);
1451
1452                        deferredShader->SetKernelRadius(ssaoKernelRadius);
1453                        deferredShader->SetSampleIntensity(ssaoSampleIntensity);
1454                }
1455
1456                DeferredRenderer::SHADING_METHOD shadingMethod;
1457
1458                if (useAdvancedShading)
1459                {
1460                        if (useGlobIllum)
1461                                shadingMethod = DeferredRenderer::GI;
1462                        else
1463                                shadingMethod = DeferredRenderer::SSAO;
1464                }
1465                else
1466                {
1467                        shadingMethod = DeferredRenderer::DEFAULT;
1468                }
1469
1470                static int snapShotIdx = 0;
1471
1472                deferredShader->SetSunVisiblePixels(sunVisiblePixels);
1473                deferredShader->SetShadingMethod(shadingMethod);
1474                deferredShader->SetSamplingMethod(samplingMethod);
1475               
1476                deferredShader->SetUseTemporalCoherence(useTemporalCoherence);
1477                //deferredShader->SetSortSamples(sortSamples);
1478                deferredShader->SetTemporalCoherenceFactorForSsao(ssaoTempCohFactor);
1479                deferredShader->SetUseToneMapping(useHDR);
1480                deferredShader->SetUseAntiAliasing(useAntiAliasing);
1481                deferredShader->SetMaxConvergence(maxConvergence);
1482                deferredShader->SetSpatialWeight(spatialWeight);
1483
1484
1485                if (recordFrames && replayPath)
1486                {
1487                        // record all frames of the walkthrough
1488                        deferredShader->SetSaveFrame(recordedFramesSuffix, currentReplayFrame);
1489                }
1490                else if (makeSnapShot)
1491                {
1492                        // make snap shot
1493                        deferredShader->SetSaveFrame("snap", snapShotIdx ++);
1494                }
1495                else
1496                {
1497                        // do nothing
1498                        deferredShader->SetSaveFrame("", -1);           
1499                }
1500               
1501                static int dummy = 0;
1502                if (makeSnapShot && (dummy ++ == 650)) makeSnapShot = false;
1503
1504                ShadowMap *sm = showShadowMap ? shadowMap : NULL;
1505                deferredShader->Render(fbo, light, sm);
1506        }
1507
1508
1509        renderState.SetRenderTechnique(FORWARD);
1510        renderState.Reset();
1511
1512        glDisableClientState(GL_VERTEX_ARRAY);
1513        glDisableClientState(GL_NORMAL_ARRAY);
1514       
1515        renderMethod = oldRenderMethod;
1516
1517
1518        ///////////
1519
1520
1521        if (showAlgorithmTime)
1522        {
1523                glFinish();
1524
1525                algTime = algTimer.Elapsedms();
1526                perfGraph->AddData(algTime);
1527
1528                perfGraph->Draw();
1529        }
1530        else
1531        {
1532                if (visMode) DisplayVisualization();
1533        }
1534
1535        glFlush();
1536
1537        const bool restart = true;
1538        elapsedTime = frameTimer.Elapsedms(restart);
1539
1540        // statistics
1541        DisplayStats();
1542
1543        glutSwapBuffers();
1544
1545        oldPos = camera->GetPosition();
1546        oldDir = camera->GetDirection();
1547}
1548
1549
1550#pragma warning(disable : 4100)
1551void KeyBoard(unsigned char c, int x, int y)
1552{
1553        switch(c)
1554        {
1555        case 27:
1556                // write out current position on exit
1557                Debug << "camPosition=" << camera->GetPosition().x << " " << camera->GetPosition().y << " " << camera->GetPosition().z << endl;
1558                Debug << "camDirection=" << camera->GetDirection().x << " " << camera->GetDirection().y << " " << camera->GetDirection().z << endl;
1559                Debug << "lightDirection=" << light->GetDirection().x << " " << light->GetDirection().y << " " << light->GetDirection().z << endl;
1560
1561                CleanUp();
1562                exit(0);
1563        case 32: // space
1564                renderMode = (renderMode + 1) % RenderTraverser::NUM_TRAVERSAL_TYPES;
1565                //renderMode = (renderMode + 1) % 4;
1566
1567                DEL_PTR(traverser);
1568                traverser = CreateTraverser(camera);
1569
1570                if (shadowTraverser)
1571                {
1572                        // shadow traverser has to be recomputed
1573                        DEL_PTR(shadowTraverser);
1574                        shadowTraverser = CreateTraverser(shadowMap->GetShadowCamera());
1575                }
1576
1577                break;
1578        case '+':
1579                if (maxBatchSize < 10)
1580                        maxBatchSize = 10;
1581                else
1582                        maxBatchSize += 10;
1583
1584                traverser->SetMaxBatchSize(maxBatchSize);
1585                break;
1586        case '-':
1587                maxBatchSize -= 10;
1588                if (maxBatchSize < 0) maxBatchSize = 1;
1589                traverser->SetMaxBatchSize(maxBatchSize);               
1590                break;
1591        case 'M':
1592        case 'm':
1593                useMultiQueries = !useMultiQueries;
1594                traverser->SetUseMultiQueries(useMultiQueries);
1595                break;
1596        case '1':
1597                descendKeyPressed = true;
1598                break;
1599        case '2':
1600                ascendKeyPressed = true;
1601                break;
1602        case '3':
1603                if (trianglesPerVirtualLeaf >= 100) trianglesPerVirtualLeaf -= 100;
1604                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1605                break;
1606        case '4':
1607                trianglesPerVirtualLeaf += 100;
1608                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1609                break;
1610        case '5':
1611                assumedVisibleFrames -= 1;
1612                if (assumedVisibleFrames < 1) assumedVisibleFrames = 1;
1613                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
1614                break;
1615        case '6':
1616                assumedVisibleFrames += 1;
1617                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);               
1618                break;
1619        case '7':
1620                ssaoTempCohFactor *= 1.0f / 1.2f;
1621                cout << "new temporal coherence factor: " << ssaoTempCohFactor << endl;
1622                break;
1623        case '8':
1624                ssaoTempCohFactor *= 1.2f;
1625                cout << "new temporal coherence factor: " << ssaoTempCohFactor << endl;
1626                break;
1627        case '9':
1628                ssaoKernelRadius *= .8f;
1629                cout << "new ssao kernel radius: " << ssaoKernelRadius << endl;
1630                if (deferredShader) deferredShader->SetKernelRadius(ssaoKernelRadius);
1631                break;
1632        case '0':
1633                ssaoKernelRadius *= 1.0f / .8f;
1634                if (deferredShader) deferredShader->SetKernelRadius(ssaoKernelRadius);
1635                cout << "new ssao kernel radius: " << ssaoKernelRadius << endl;
1636                break;
1637        case 'n':
1638                ssaoSampleIntensity *= .9f;
1639                if (deferredShader) deferredShader->SetSampleIntensity(ssaoSampleIntensity);
1640                cout << "new ssao sample intensity: " << ssaoSampleIntensity << endl;
1641                break;
1642        case 'N':
1643                ssaoSampleIntensity *= 1.0f / .9f;
1644                if (deferredShader) deferredShader->SetSampleIntensity(ssaoSampleIntensity);
1645                cout << "new ssao sample intensity: " << ssaoSampleIntensity << endl;
1646                break;
1647        /*      case 'o':
1648        case 'O':
1649                useOptimization = !useOptimization;
1650                // chc optimization of using the objects instead of
1651                // the bounding boxes for querying previously visible nodes
1652                traverser->SetUseOptimization(useOptimization);
1653                break;*/
1654        case 'o':
1655                        spatialWeight /= 2.0f;
1656                        cout << "spatialWeight: " << spatialWeight << endl;
1657                        break;
1658        case 'O':
1659                        spatialWeight *= 2.0f;
1660                        cout << "spatialWeight: " << spatialWeight << endl;
1661                        break;
1662        /*case 'o':
1663        case 'O':
1664                if (maxConvergence > 100.0f)
1665                        maxConvergence = 1.0f;
1666                else
1667                        maxConvergence = 5000.0f;
1668                cout << "max convergence: " << maxConvergence << endl;
1669        */
1670                break;
1671        case 'l':
1672        case 'L':
1673                useLODs = !useLODs;
1674                SceneEntity::SetUseLODs(useLODs);
1675                cout << "using LODs: " << useLODs << endl;
1676                break;
1677        case 'P':
1678        case 'p':
1679                samplingMethod = DeferredRenderer::SAMPLING_METHOD((samplingMethod + 1) % 3);
1680                cout << "ssao sampling method: " << samplingMethod << endl;
1681                break;
1682        case 'Y':
1683        case 'y':
1684                showShadowMap = !showShadowMap;
1685                break;
1686        case 'g':
1687        case 'G':
1688                useGlobIllum = !useGlobIllum;
1689                break;
1690        case 't':
1691        case 'T':
1692                useTemporalCoherence = !useTemporalCoherence;
1693                cout << "using temporal coherence " << useTemporalCoherence << endl;
1694                break;
1695        case 'a':
1696        case 'A':
1697                leftKeyPressed = true;
1698                break;
1699        case 'd':
1700        case 'D':
1701                rightKeyPressed = true;
1702                break;
1703        case 'w':
1704        case 'W':
1705                upKeyPressed = true;
1706                break;
1707        case 's':
1708        case 'S':
1709                downKeyPressed = true;
1710                break;
1711        case 'j':
1712        case 'J':
1713                leftStrafeKeyPressed = true;
1714                break;
1715        case 'k':
1716        case 'K':
1717                rightStrafeKeyPressed = true;
1718                break;
1719        case 'r':
1720        case 'R':
1721                useRenderQueue = !useRenderQueue;
1722                traverser->SetUseRenderQueue(useRenderQueue);
1723                break;
1724        case 'b':
1725        case 'B':
1726                useTightBounds = !useTightBounds;
1727                traverser->SetUseTightBounds((renderMode == RenderTraverser::CHCPLUSPLUS) && useTightBounds);
1728                break;
1729        case 'v':
1730        case 'V':
1731                renderLightView = !renderLightView;
1732                break;
1733        case 'h':
1734        case 'H':
1735                useHDR = !useHDR;
1736                break;
1737        case 'i':
1738        case 'I':
1739                useAntiAliasing = !useAntiAliasing;
1740                break;
1741        case 'c':
1742        case 'C':
1743                useLenseFlare = !useLenseFlare;
1744                break;
1745        case 'u':
1746        case 'U':
1747                // move light source instead of camera tilt
1748                moveLight = !moveLight;
1749                break;
1750        case '#':
1751                // make a snapshot of the current frame
1752                makeSnapShot = true;
1753                break;
1754        case '.':
1755                // enable / disable view cells
1756                usePvs = !usePvs;
1757                if (!usePvs) SceneEntity::SetCurrentVisibleId(-1);
1758                break;
1759        case ',':
1760                // show / hide FPS
1761                showFPS = !showFPS;
1762                break;
1763       
1764        default:
1765                return;
1766        }
1767
1768        glutPostRedisplay();
1769}
1770
1771
1772void SpecialKeyUp(int c, int x, int y)
1773{
1774        switch (c)
1775        {
1776        case GLUT_KEY_LEFT:
1777                leftKeyPressed = false;
1778                break;
1779        case GLUT_KEY_RIGHT:
1780                rightKeyPressed = false;
1781                break;
1782        case GLUT_KEY_UP:
1783                upKeyPressed = false;
1784                break;
1785        case GLUT_KEY_DOWN:
1786                downKeyPressed = false;
1787                break;
1788        case GLUT_ACTIVE_ALT:
1789                altKeyPressed = false;
1790                break;
1791        default:
1792                return;
1793        }
1794}
1795
1796
1797void KeyUp(unsigned char c, int x, int y)
1798{
1799        switch (c)
1800        {
1801
1802        case 'A':
1803        case 'a':
1804                leftKeyPressed = false;
1805                break;
1806        case 'D':
1807        case 'd':
1808                rightKeyPressed = false;
1809                break;
1810        case 'W':
1811        case 'w':
1812                upKeyPressed = false;
1813                break;
1814        case 'S':
1815        case 's':
1816                downKeyPressed = false;
1817                break;
1818        case '1':
1819                descendKeyPressed = false;
1820                break;
1821        case '2':
1822                ascendKeyPressed = false;
1823                break;
1824        case 'j':
1825        case 'J':
1826                leftStrafeKeyPressed = false;
1827                break;
1828        case 'k':
1829        case 'K':
1830                rightStrafeKeyPressed = false;
1831                break;
1832        default:
1833                return;
1834        }
1835        //glutPostRedisplay();
1836}
1837
1838
1839void Special(int c, int x, int y)
1840{
1841        switch(c)
1842        {
1843        case GLUT_KEY_F1:
1844                showHelp = !showHelp;
1845                break;
1846        case GLUT_KEY_F2:
1847                visMode = !visMode;
1848                break;
1849        case GLUT_KEY_F3:
1850                showBoundingVolumes = !showBoundingVolumes;
1851                traverser->SetShowBounds(showBoundingVolumes);
1852                break;
1853        case GLUT_KEY_F4:
1854                showOptions = !showOptions;
1855                break;
1856        case GLUT_KEY_F5:
1857                showStatistics = !showStatistics;
1858                break;
1859        case GLUT_KEY_F6:
1860                flyMode = !flyMode;
1861                break;
1862        case GLUT_KEY_F7:
1863
1864                renderMethod = (renderMethod + 1) % 4;
1865
1866                traverser->SetUseDepthPass(
1867                        (renderMethod == RENDER_DEPTH_PASS) ||
1868                        (renderMethod == RENDER_DEPTH_PASS_DEFERRED)
1869                        );
1870                break;
1871        case GLUT_KEY_F8:
1872                useAdvancedShading = !useAdvancedShading;
1873                break;
1874        case GLUT_KEY_F9:
1875                showAlgorithmTime = !showAlgorithmTime;
1876                break;
1877        case GLUT_KEY_F10:
1878                replayPath = !replayPath;
1879
1880                if (replayPath)
1881                {
1882                        cout << "replaying path" << endl;
1883                        currentReplayFrame = -1;
1884
1885                        // hack: load pvs on replay (remove later!)
1886                        //usePvs = true;
1887                }
1888                else
1889                {
1890                        cout << "finished replaying path" << endl;
1891                }
1892                break;
1893        case GLUT_KEY_F11:
1894                recordPath = !recordPath;
1895               
1896                if (recordPath)
1897                {
1898                        cout << "recording path" << endl;
1899                }
1900                else
1901                {
1902                        cout << "finished recording path" << endl;
1903                        // start over with new frame recording next time
1904                        DEL_PTR(walkThroughRecorder);
1905                }
1906                break;
1907        case GLUT_KEY_F12:
1908                recordFrames = !recordFrames;
1909
1910                if (recordFrames)
1911                        cout << "recording frames on replaying" << endl;
1912                else
1913                        cout << "not recording frames on replaying" << endl;
1914                break;
1915        case GLUT_KEY_LEFT:
1916                {
1917                        leftKeyPressed = true;
1918                        camera->Pitch(KeyRotationAngle());
1919                }
1920                break;
1921        case GLUT_KEY_RIGHT:
1922                {
1923                        rightKeyPressed = true;
1924                        camera->Pitch(-KeyRotationAngle());
1925                }
1926                break;
1927        case GLUT_KEY_UP:
1928                {
1929                        upKeyPressed = true;
1930                        KeyHorizontalMotion(KeyShift());
1931                }
1932                break;
1933        case GLUT_KEY_DOWN:
1934                {
1935                        downKeyPressed = true;
1936                        KeyHorizontalMotion(-KeyShift());
1937                }
1938                break;
1939        default:
1940                return;
1941
1942        }
1943
1944        glutPostRedisplay();
1945}
1946
1947#pragma warning( default : 4100 )
1948
1949
1950void Reshape(int w, int h)
1951{
1952        winAspectRatio = 1.0f;
1953
1954        glViewport(0, 0, w, h);
1955       
1956        winWidth = w;
1957        winHeight = h;
1958
1959        if (w) winAspectRatio = (float) w / (float) h;
1960
1961        glMatrixMode(GL_PROJECTION);
1962        glLoadIdentity();
1963
1964        gluPerspective(fov, winAspectRatio, nearDist, farDist);
1965
1966        glMatrixMode(GL_MODELVIEW);
1967
1968        glutPostRedisplay();
1969}
1970
1971
1972void Mouse(int button, int renderState, int x, int y)
1973{
1974        if ((button == GLUT_LEFT_BUTTON) && (renderState == GLUT_DOWN))
1975        {
1976                xEyeBegin = x;
1977                yMotionBegin = y;
1978
1979                glutMotionFunc(LeftMotion);
1980        }
1981        else if ((button == GLUT_RIGHT_BUTTON) && (renderState == GLUT_DOWN))
1982        {
1983                xEyeBegin = x;
1984                yEyeBegin = y;
1985                yMotionBegin = y;
1986
1987                if (!moveLight)
1988                        glutMotionFunc(RightMotion);
1989                else
1990                        glutMotionFunc(RightMotionLight);
1991        }
1992        else if ((button == GLUT_MIDDLE_BUTTON) && (renderState == GLUT_DOWN))
1993        {
1994                horizontalMotionBegin = x;
1995                verticalMotionBegin = y;
1996                glutMotionFunc(MiddleMotion);
1997        }
1998
1999        glutPostRedisplay();
2000}
2001
2002
2003/**     rotation for left/right mouse drag
2004        motion for up/down mouse drag
2005*/
2006void LeftMotion(int x, int y)
2007{
2008        Vector3 viewDir = camera->GetDirection();
2009        Vector3 pos = camera->GetPosition();
2010
2011        // don't move in the vertical direction
2012        Vector3 horView(viewDir[0], viewDir[1], 0);
2013       
2014        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
2015
2016        camera->Pitch(eyeXAngle);
2017
2018        pos += horView * (yMotionBegin - y) * mouseMotion;
2019       
2020        camera->SetPosition(pos);
2021       
2022        xEyeBegin = x;
2023        yMotionBegin = y;
2024
2025        glutPostRedisplay();
2026}
2027
2028
2029void RightMotionLight(int x, int y)
2030{
2031        const float theta = .2f * M_PI * (xEyeBegin - x) / 180.0f;
2032        const float phi   = .2f * M_PI * (yMotionBegin - y) / 180.0f;
2033       
2034        Vector3 lightDir = light->GetDirection();
2035
2036        Matrix4x4 roty = RotationYMatrix(theta);
2037        Matrix4x4 rotx = RotationXMatrix(phi);
2038
2039        lightDir = roty * lightDir;
2040        lightDir = rotx * lightDir;
2041
2042        // normalize to avoid accumulating errors
2043        lightDir.Normalize();
2044
2045        light->SetDirection(lightDir);
2046
2047        xEyeBegin = x;
2048        yMotionBegin = y;
2049
2050        glutPostRedisplay();
2051}
2052
2053
2054/**     rotation for left / right mouse drag
2055        motion for up / down mouse drag
2056*/
2057void RightMotion(int x, int y)
2058{
2059        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
2060        float eyeYAngle = -0.2f *  M_PI * (yEyeBegin - y) / 180.0;
2061
2062        camera->Yaw(eyeYAngle);
2063        camera->Pitch(eyeXAngle);
2064
2065        xEyeBegin = x;
2066        yEyeBegin = y;
2067
2068        glutPostRedisplay();
2069}
2070
2071
2072/** strafe
2073*/
2074void MiddleMotion(int x, int y)
2075{
2076        Vector3 viewDir = camera->GetDirection();
2077        Vector3 pos = camera->GetPosition();
2078
2079        // the 90 degree rotated view vector
2080        // y zero so we don't move in the vertical
2081        Vector3 rVec(viewDir[0], viewDir[1], 0);
2082       
2083        Matrix4x4 rot = RotationZMatrix(M_PI * .5f);
2084        rVec = rot * rVec;
2085       
2086        pos    -= rVec * (x - horizontalMotionBegin) * mouseMotion;
2087        pos[2] += (verticalMotionBegin - y) * mouseMotion;
2088
2089        camera->SetPosition(pos);
2090
2091        horizontalMotionBegin = x;
2092        verticalMotionBegin = y;
2093
2094        glutPostRedisplay();
2095}
2096
2097
2098void InitExtensions(void)
2099{
2100        GLenum err = glewInit();
2101
2102        if (GLEW_OK != err)
2103        {
2104                // problem: glewInit failed, something is seriously wrong
2105                fprintf(stderr,"Error: %s\n", glewGetErrorString(err));
2106                exit(1);
2107        }
2108        if  (!GLEW_ARB_occlusion_query)
2109        {
2110                printf("I require the GL_ARB_occlusion_query to work.\n");
2111                exit(1);
2112        }
2113}
2114
2115
2116void Begin2D()
2117{
2118        glDisable(GL_LIGHTING);
2119        glDisable(GL_DEPTH_TEST);
2120
2121        glMatrixMode(GL_PROJECTION);
2122        glPushMatrix();
2123        glLoadIdentity();
2124
2125        gluOrtho2D(0, winWidth, 0, winHeight);
2126
2127        glMatrixMode(GL_MODELVIEW);
2128        glPushMatrix();
2129        glLoadIdentity();
2130}
2131
2132
2133void End2D()
2134{
2135        glMatrixMode(GL_PROJECTION);
2136        glPopMatrix();
2137
2138        glMatrixMode(GL_MODELVIEW);
2139        glPopMatrix();
2140
2141        glEnable(GL_LIGHTING);
2142        glEnable(GL_DEPTH_TEST);
2143}
2144
2145
2146// displays the visualisation of culling algorithm
2147void DisplayVisualization()
2148{
2149        // render current view cell
2150        if (usePvs) RenderViewCell();
2151       
2152        visualization->SetViewCell(usePvs ? viewCell : NULL);
2153        visualization->SetFrameId(traverser->GetCurrentFrameId());
2154       
2155
2156        Begin2D();
2157        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2158        glEnable(GL_BLEND);
2159        glColor4f(0.0f ,0.0f, 0.0f, 0.5f);
2160
2161        glRecti(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth, winHeight);
2162        glDisable(GL_BLEND);
2163        End2D();
2164       
2165       
2166        AxisAlignedBox3 box = bvh->GetBox();
2167
2168        const float offs = box.Size().x * 0.3f;
2169       
2170        Vector3 vizpos = Vector3(box.Min().x, box.Min().y  - box.Size().y * 0.35f, box.Min().z + box.Size().z * 50);
2171       
2172        visCamera->SetPosition(vizpos);
2173        visCamera->ResetPitchAndYaw();
2174       
2175        glPushAttrib(GL_VIEWPORT_BIT);
2176        glViewport(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth / 3, winHeight / 3);
2177
2178        glMatrixMode(GL_PROJECTION);
2179        glPushMatrix();
2180
2181        glLoadIdentity();
2182        glOrtho(-offs, offs, -offs, offs, 0.0f, box.Size().z * 100.0f);
2183
2184        glMatrixMode(GL_MODELVIEW);
2185        glPushMatrix();
2186
2187        visCamera->SetupCameraView();
2188
2189        Matrix4x4 rotZ = RotationZMatrix(-camera->GetPitch());
2190        glMultMatrixf((float *)rotZ.x);
2191
2192        // inverse translation in order to fix current position
2193        Vector3 pos = camera->GetPosition();
2194        glTranslatef(-pos.x, -pos.y, -pos.z);
2195
2196
2197        GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
2198        glLightfv(GL_LIGHT0, GL_POSITION, position);
2199
2200        GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
2201        glLightfv(GL_LIGHT1, GL_POSITION, position1);
2202
2203        glClear(GL_DEPTH_BUFFER_BIT);
2204
2205
2206        ////////////
2207        //-- visualization of the occlusion culling
2208
2209        visualization->Render(showShadowMap);
2210
2211       
2212        // reset previous settings
2213        glPopAttrib();
2214
2215        glMatrixMode(GL_PROJECTION);
2216        glPopMatrix();
2217        glMatrixMode(GL_MODELVIEW);
2218        glPopMatrix();
2219}
2220
2221
2222// cleanup routine after the main loop
2223void CleanUp()
2224{
2225        DEL_PTR(traverser);
2226        DEL_PTR(sceneQuery);
2227        DEL_PTR(bvh);
2228        DEL_PTR(visualization);
2229        DEL_PTR(camera);
2230        DEL_PTR(renderQueue);
2231        DEL_PTR(perfGraph);
2232        DEL_PTR(fbo);
2233        DEL_PTR(deferredShader);
2234        DEL_PTR(light);
2235        DEL_PTR(visCamera);
2236        DEL_PTR(preetham);
2237        DEL_PTR(shadowMap);
2238        DEL_PTR(shadowTraverser);
2239        DEL_PTR(motionPath);
2240        DEL_PTR(walkThroughRecorder);
2241        DEL_PTR(walkThroughPlayer);
2242        DEL_PTR(statsWriter);
2243        DEL_PTR(viewCellsTree);
2244
2245        ResourceManager::DelSingleton();
2246        ShaderManager::DelSingleton();
2247
2248        resourceManager = NULL;
2249        shaderManager = NULL;
2250}
2251
2252
2253// this function inserts a dezimal point after each 1000
2254void CalcDecimalPoint(string &str, int d, int len)
2255{
2256        static vector<int> numbers;
2257        numbers.clear();
2258
2259        static string shortStr;
2260        shortStr.clear();
2261
2262        static char hstr[100];
2263
2264        while (d != 0)
2265        {
2266                numbers.push_back(d % 1000);
2267                d /= 1000;
2268        }
2269
2270        // first element without leading zeros
2271        if (numbers.size() > 0)
2272        {
2273                sprintf(hstr, "%d", numbers.back());
2274                shortStr.append(hstr);
2275        }
2276       
2277        for (int i = (int)numbers.size() - 2; i >= 0; i--)
2278        {
2279                sprintf(hstr, ",%03d", numbers[i]);
2280                shortStr.append(hstr);
2281        }
2282
2283        int dif = len - (int)shortStr.size();
2284
2285        for (int i = 0; i < dif; ++ i)
2286        {
2287                str += " ";
2288        }
2289
2290        str.append(shortStr);
2291}
2292
2293
2294void DisplayStats()
2295{
2296        static char msg[9][300];
2297
2298        static double frameTime = elapsedTime;
2299        static double renderTime = algTime;
2300
2301        const float expFactor = 0.1f;
2302
2303        // if some strange render time spike happened in this frame => don't count
2304        if (elapsedTime < 500) frameTime = elapsedTime * expFactor + (1.0f - expFactor) * elapsedTime;
2305       
2306        static float rTime = 1000.0f;
2307
2308        // the render time is used only for the traversal algorithm using glfinish
2309        if (algTime < 500) renderTime = algTime * expFactor + (1.0f - expFactor) * renderTime;
2310       
2311
2312        accumulatedTime += elapsedTime;
2313
2314        if (accumulatedTime > 500) // update every fraction of a second
2315        {       
2316                accumulatedTime = 0;
2317
2318                if (frameTime) fps = 1e3f / (float)frameTime;
2319                rTime = renderTime;
2320
2321                if (renderLightView && shadowTraverser)
2322                {
2323                        renderedTriangles = shadowTraverser->GetStats().mNumRenderedTriangles;
2324                        renderedObjects = shadowTraverser->GetStats().mNumRenderedGeometry;
2325                        renderedNodes = shadowTraverser->GetStats().mNumRenderedNodes;
2326                }
2327                else if (showShadowMap && shadowTraverser)
2328                {
2329                        renderedNodes = traverser->GetStats().mNumRenderedNodes + shadowTraverser->GetStats().mNumRenderedNodes;
2330                        renderedObjects = traverser->GetStats().mNumRenderedGeometry + shadowTraverser->GetStats().mNumRenderedGeometry;
2331                        renderedTriangles = traverser->GetStats().mNumRenderedTriangles + shadowTraverser->GetStats().mNumRenderedTriangles;
2332                }
2333                else
2334                {
2335                        renderedTriangles = traverser->GetStats().mNumRenderedTriangles;
2336                        renderedObjects = traverser->GetStats().mNumRenderedGeometry;
2337                        renderedNodes = traverser->GetStats().mNumRenderedNodes;
2338                }
2339
2340                traversedNodes = traverser->GetStats().mNumTraversedNodes;
2341                frustumCulledNodes = traverser->GetStats().mNumFrustumCulledNodes;
2342                queryCulledNodes = traverser->GetStats().mNumQueryCulledNodes;
2343                issuedQueries = traverser->GetStats().mNumIssuedQueries;
2344                stateChanges = traverser->GetStats().mNumStateChanges;
2345                numBatches = traverser->GetStats().mNumBatches;
2346        }
2347
2348
2349        ////////////////
2350        //-- record stats on walkthrough
2351
2352        static float accTime = .0f;
2353        static float averageTime = .0f;
2354
2355        if (currentReplayFrame > -1)
2356        {
2357                accTime += frameTime;
2358                averageTime = accTime / (currentReplayFrame + 1);
2359
2360                if (!statsWriter)
2361                        statsWriter = new StatsWriter(statsFilename + ".log");
2362                       
2363                FrameStats frameStats;
2364                frameStats.mFrame = currentReplayFrame;
2365                frameStats.mFPS = 1e3f / (float)frameTime;
2366                frameStats.mTime = frameTime;
2367                frameStats.mNodes = renderedNodes;
2368                frameStats.mObjects = renderedObjects;
2369                frameStats.mTriangles = renderedTriangles;
2370
2371                statsWriter->WriteFrameStats(frameStats);
2372        }
2373        else if (statsWriter)
2374        {
2375                Debug << "average frame time " << averageTime << " for traversal algorithm " << renderMode << endl;
2376
2377                // reset average frame time
2378                averageTime = accTime = .0f;
2379
2380                DEL_PTR(statsWriter);
2381        }
2382
2383
2384        Begin2D();
2385
2386        glEnable(GL_BLEND);
2387        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2388
2389        if (showHelp)
2390        {       
2391                DrawHelpMessage();
2392        }
2393        else
2394        {
2395                if (showOptions)
2396                {
2397                        glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
2398                        glRecti(5, winHeight - 95, winWidth * 2 / 3 - 5, winHeight - 5);
2399                }
2400
2401                if (showStatistics)
2402                {
2403                        glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
2404                        glRecti(5, winHeight - 165, winWidth * 2 / 3 - 5, winHeight - 100);
2405                }
2406
2407                glEnable(GL_TEXTURE_2D);
2408                myfont.Begin();
2409
2410                if (showOptions)
2411                {
2412                        glColor3f(0.0f, 1.0f, 0.0f);
2413                        int i = 0;
2414
2415                        static char *renderMethodStr[] =
2416                                {"forward", "depth pass + forward", "deferred shading", "depth pass + deferred"};
2417                        sprintf(msg[i ++], "multiqueries: %d, tight bounds: %d, render queue: %d",
2418                                        useMultiQueries, (renderMode == RenderTraverser::CHCPLUSPLUS) && useTightBounds, useRenderQueue);
2419                        sprintf(msg[i ++], "render technique: %s, use pvss: %d", renderMethodStr[renderMethod], usePvs);
2420                        sprintf(msg[i ++], "triangles per virtual leaf: %5d", trianglesPerVirtualLeaf);
2421                        sprintf(msg[i ++], "assumed visible frames: %4d, max batch size: %4d",
2422                                assumedVisibleFrames, maxBatchSize);
2423
2424                        for (int j = 0; j < 4; ++ j)
2425                                myfont.DrawString(msg[j], 10.0f, winHeight - 5 - j * 20);
2426                }
2427
2428                if (showStatistics)
2429                {
2430                        glColor3f(1.0f, 1.0f, 0.0f);
2431
2432                        string objStr, totalObjStr;
2433                        string triStr, totalTriStr;
2434
2435                        int len = 10;
2436                        CalcDecimalPoint(objStr, renderedObjects, len);
2437                        CalcDecimalPoint(totalObjStr, (int)resourceManager->GetNumEntities(), len);
2438
2439                        CalcDecimalPoint(triStr, renderedTriangles, len);
2440                        CalcDecimalPoint(totalTriStr, bvh->GetBvhStats().mTriangles, len);
2441
2442                        int i = 4;
2443
2444                        if (0) // q: show rendered objects or nodes (no space for both)
2445                        {
2446                                sprintf(msg[i ++], "rendered: %s of %s objects, %s of %s triangles",
2447                                        objStr.c_str(), totalObjStr.c_str(), triStr.c_str(), totalTriStr.c_str());
2448                        }
2449                        else
2450                        {
2451                                sprintf(msg[i ++], "rendered: %6d of %6d nodes, %s of %s triangles",
2452                                        renderedNodes, bvh->GetNumVirtualNodes(), triStr.c_str(), totalTriStr.c_str());
2453                        }
2454
2455                        sprintf(msg[i ++], "traversed: %5d, frustum culled: %5d, query culled: %5d nodes",
2456                                traversedNodes, frustumCulledNodes, queryCulledNodes);
2457                        sprintf(msg[i ++], "issued queries: %5d, state changes: %5d, render batches: %5d",
2458                                issuedQueries, stateChanges, numBatches);
2459
2460                        for (int j = 4; j < 7; ++ j)
2461                                myfont.DrawString(msg[j], 10.0f, winHeight - (j + 1) * 20);
2462                }
2463
2464                glColor3f(0.0f, 1.0f, 0.0f);
2465
2466                static char *alg_str[] = {
2467                        "Frustum Cull"
2468                        , "Stop and Wait"
2469                        , "CHC"
2470                        , "CHC ++"
2471            //, "Collector"
2472                };
2473       
2474                if (!showAlgorithmTime)
2475                {
2476                        if (showFPS)
2477                        {                       
2478                                sprintf(msg[7], "%s:  %6.1f fps", alg_str[renderMode], fps);           
2479                                myfont.DrawString(msg[7], 1.3f, winWidth - 330, winHeight - 10.0f);
2480
2481                                //int mrays = (int)shotRays / 1000000;
2482                                //sprintf(msg[7], "%s:  %04d M rays", alg_str[renderMode], mrays);     
2483                                //myfont.DrawString(msg[7], 1.3f, winWidth - 330, winHeight - 60.0f);           
2484                        }
2485                }
2486                else
2487                {
2488                        sprintf(msg[7], "%s:  %6.1f ms", alg_str[renderMode], rTime);
2489                        myfont.DrawString(msg[7], 1.3f, winWidth - 330, winHeight - 10.0f);
2490                }
2491
2492                glColor3f(1.0f, 1.0f, 1.0f);
2493        }
2494
2495        glColor3f(1, 1, 1);
2496        glDisable(GL_BLEND);
2497        glDisable(GL_TEXTURE_2D);
2498
2499        End2D();
2500}       
2501
2502
2503void RenderSky()
2504{
2505        if ((renderMethod == RENDER_DEFERRED) || (renderMethod == RENDER_DEPTH_PASS_DEFERRED))
2506                renderState.SetRenderTechnique(DEFERRED);
2507
2508        const bool useToneMapping =
2509                ((renderMethod == RENDER_DEPTH_PASS_DEFERRED) ||
2510                 (renderMethod == RENDER_DEFERRED)) && useHDR;
2511       
2512        preetham->RenderSkyDome(-light->GetDirection(), camera, &renderState, !useToneMapping, skyDomeScaleFactor);
2513
2514        /// once again reset the renderState just to make sure
2515        renderState.Reset();
2516}
2517
2518
2519// render visible object from depth pass
2520void RenderVisibleObjects()
2521{
2522        if (renderMethod == RENDER_DEPTH_PASS_DEFERRED)
2523        {
2524                if (showShadowMap && !renderLightView)
2525                {
2526                        // usethe maximal visible distance to focus shadow map
2527                        const float newFar = min(camera->GetFar(), traverser->GetMaxVisibleDistance());
2528                        RenderShadowMap(newFar);
2529                }
2530
2531                // initialize deferred rendering
2532                InitDeferredRendering();
2533        }
2534        else
2535        {
2536                renderState.SetRenderTechnique(FORWARD);
2537        }
2538
2539
2540        /////////////////
2541        //-- reset gl renderState before the final visible objects pass
2542
2543        renderState.Reset();
2544
2545        glEnableClientState(GL_NORMAL_ARRAY);
2546        /// switch back to smooth shading
2547        glShadeModel(GL_SMOOTH);
2548        /// reset alpha to coverage flag
2549        renderState.SetUseAlphaToCoverage(true);
2550        // clear color
2551        glClear(GL_COLOR_BUFFER_BIT);
2552       
2553        // draw only objects having exactly the same depth as the current sample
2554        glDepthFunc(GL_EQUAL);
2555
2556        //cout << "visible: " << (int)traverser->GetVisibleObjects().size() << endl;
2557
2558        SceneEntityContainer::const_iterator sit,
2559                sit_end = traverser->GetVisibleObjects().end();
2560
2561        for (sit = traverser->GetVisibleObjects().begin(); sit != sit_end; ++ sit)
2562        {
2563                renderQueue->Enqueue(*sit);
2564        }
2565
2566        /// now render out everything in one giant pass
2567        renderQueue->Apply();
2568
2569        // switch back to standard depth func
2570        glDepthFunc(GL_LESS);
2571        renderState.Reset();
2572
2573        PrintGLerror("visible objects");
2574}
2575
2576
2577SceneQuery *GetOrCreateSceneQuery()
2578{
2579        if (!sceneQuery)
2580        {
2581                sceneQuery = new SceneQuery(bvh->GetBox(), traverser, &renderState);
2582        }
2583
2584        return sceneQuery;
2585}
2586
2587
2588void PlaceViewer(const Vector3 &oldPos)
2589{
2590        Vector3 playerPos = camera->GetPosition();
2591        bool validIntersect = GetOrCreateSceneQuery()->CalcIntersection(playerPos);
2592
2593        if (validIntersect)
2594                //&& ((playerPos.z - oldPos.z) < bvh->GetBox().Size(2) * 1e-1f))
2595        {
2596                camera->SetPosition(playerPos);
2597        }
2598}
2599
2600
2601void RenderShadowMap(float newfar)
2602{
2603        glDisableClientState(GL_NORMAL_ARRAY);
2604        renderState.SetRenderTechnique(DEPTH_PASS);
2605       
2606        // hack: disable cull face because of alpha textured balconies
2607        glDisable(GL_CULL_FACE);
2608        renderState.LockCullFaceEnabled(true);
2609
2610        /// don't use alpha to coverage for the depth map (problems with fbo rendering)
2611        renderState.SetUseAlphaToCoverage(false);
2612
2613        const Vector3 lightPos = light->GetDirection() * -1e3f;
2614        if (usePvs) LoadOrUpdatePVSs(lightPos);
2615
2616
2617        // change CHC++ set of renderState variables
2618        // this must be done for each change of camera because
2619        // otherwise the temporal coherency is broken
2620        BvhNode::SetCurrentState(LIGHT_PASS);
2621        // hack: temporarily change camera far plane
2622        camera->SetFar(newfar);
2623        // the scene is rendered withouth any shading   
2624        shadowMap->ComputeShadowMap(shadowTraverser, viewProjMat);
2625
2626        camera->SetFar(farDist);
2627
2628        renderState.SetUseAlphaToCoverage(true);
2629        renderState.LockCullFaceEnabled(false);
2630        glEnable(GL_CULL_FACE);
2631
2632        glEnableClientState(GL_NORMAL_ARRAY);
2633        // change back renderState
2634        BvhNode::SetCurrentState(CAMERA_PASS);
2635}
2636
2637
2638/** Touch each material once in order to preload the render queue
2639        bucket id of each material
2640*/
2641void PrepareRenderQueue()
2642{
2643        for (int i = 0; i < 3; ++ i)
2644        {
2645                renderState.SetRenderTechnique(i);
2646
2647                // fill all shapes into the render queue        once so we can establish the buckets
2648                ShapeContainer::const_iterator sit, sit_end = (*resourceManager->GetShapes()).end();
2649
2650                for (sit = (*resourceManager->GetShapes()).begin(); sit != sit_end; ++ sit)
2651                {
2652                        static Transform3 dummy(IdentityMatrix());
2653                        renderQueue->Enqueue(*sit, NULL);
2654                }
2655       
2656                // just clear queue again
2657                renderQueue->Clear();
2658        }
2659}
2660
2661
2662int LoadModel(const string &model, SceneEntityContainer &entities)
2663{
2664        const string filename = string(model_path + model);
2665        int numEntities = 0;
2666
2667        cout << "\nloading model " << filename << endl;
2668
2669        if (numEntities = resourceManager->Load(filename, entities))
2670        {
2671                cout << "model " << filename << " successfully loaded" << endl;
2672        }
2673        else
2674        {
2675                cerr << "loading model " << filename << " failed" << endl;
2676
2677                CleanUp();
2678                exit(0);
2679        }
2680
2681        return numEntities;
2682}
2683
2684
2685void CreateAnimation(const Vector3 &pos)
2686{
2687        //const float b = 5.0f; const float a = 1.5f;
2688        const float a = 5.0f; const float b = 1.5f;
2689
2690        VertexArray vertices;
2691
2692        for (int i = 0; i < 360; ++ i)
2693        {
2694                const float angle = (float)i * M_PI / 180.0f;
2695
2696                Vector3 offs = Vector3(cos(angle) * a, sin(angle) * b, 0);
2697                vertices.push_back(pos + offs);
2698        }
2699
2700        /*for (int i = 0; i < 5; ++ i)
2701        {
2702                Vector3 offs = Vector3(i, 0, 0);
2703                vertices.push_back(center + offs);
2704        }
2705       
2706        for (int i = 0; i < 5; ++ i)
2707        {
2708                Vector3 offs = Vector3(4 - i, 0, 0);
2709                vertices.push_back(center + offs);
2710        }*/
2711
2712        motionPath = new MotionPath(vertices);
2713}
2714
2715
2716/** This function returns the number of visible pixels of a
2717        bounding box representing the sun.
2718*/
2719int TestSunVisible()
2720{
2721        // assume sun is at a far away point along the light vector
2722        Vector3 sunPos = light->GetDirection() * -1e3f;
2723        sunPos += camera->GetPosition();
2724
2725        sunBox->GetTransform()->SetMatrix(TranslationMatrix(sunPos));
2726
2727        glBeginQueryARB(GL_SAMPLES_PASSED_ARB, sunQuery);
2728
2729        sunBox->Render(&renderState);
2730
2731        glEndQueryARB(GL_SAMPLES_PASSED_ARB);
2732
2733        GLuint sampleCount;
2734
2735        glGetQueryObjectuivARB(sunQuery, GL_QUERY_RESULT_ARB, &sampleCount);
2736
2737        return sampleCount;
2738}
2739
2740
2741static Technique GetVizTechnique()
2742{
2743        Technique tech;
2744        tech.Init();
2745
2746        tech.SetEmmisive(RgbaColor(1.0f, 1.0f, 1.0f, 1.0f));
2747        tech.SetDiffuse(RgbaColor(1.0f, 1.0f, 1.0f, 1.0f));
2748        tech.SetAmbient(RgbaColor(1.0f, 1.0f, 1.0f, 1.0f));
2749
2750        return tech;
2751}
2752
2753
2754void UpdatePvs(const Vector3 &pos)
2755{
2756        viewCell = viewCellsTree->GetViewCell(camera->GetPosition());
2757
2758        const float elapsedAlgorithmTime = applicationTimer.Elapsedms(false);
2759
2760        // assume 60 FPS, total time is in secs
2761        const float raysPerMs = 2.0f * pvsTotalSamples / (pvsTotalTime * 1000.0f);
2762        //shotRays = visibilitySolutionInitialState + elapsedAlgorithmTime * raysPerMs;
2763        //shotRays += 1000 * raysPerMs / 60.0f;
2764
2765        //cout << "totalt: " << pvsTotalTime << endl;
2766        //cout << "rays per ms: " << raysPerMs << endl;
2767
2768        SceneEntity::SetCurrentVisibleId(globalVisibleId);
2769
2770        for (int i = 0; i < viewCell->mPvs.GetSize(); ++ i)
2771        {
2772                PvsEntry entry = viewCell->mPvs.GetEntry(i);
2773#ifdef USE_TIMESTAMPS
2774                if (!((entry.mTimeStamp < 0.0f) || (entry.mTimeStamp <= shotRays)))
2775                        continue;
2776#endif
2777                entry.mEntity->SetVisibleId(globalVisibleId);
2778                //numTriangles += entry.mEntity->CountNumTriangles();
2779        }
2780
2781        ++ globalVisibleId;
2782}
2783
2784
2785void LoadVisibilitySolution()
2786{
2787        ///////////
2788        //-- load the visibility solution
2789
2790        const string vis_filename =
2791                string(model_path + visibilitySolution + ".vis");
2792
2793        VisibilitySolutionLoader visLoader;
2794
2795        viewCellsTree = visLoader.Load(vis_filename,
2796                                           bvh,
2797                                                                   pvsTotalSamples,
2798                                                                   pvsTotalTime,
2799                                                                   viewCellsScaleFactor);
2800
2801        if (!viewCellsTree)
2802        {
2803                cerr << "loading pvs failed" << endl;
2804                CleanUp();
2805                exit(0);
2806        }
2807}
2808
2809
2810void RenderViewCell()
2811{
2812        // render current view cell
2813        static Technique vcTechnique = GetVizTechnique();
2814
2815        vcTechnique.Render(&renderState);
2816        Visualization::RenderBoxForViz(viewCell->GetBox());
2817}
2818
2819
2820void LoadPompeiiFloor()
2821{
2822        AxisAlignedBox3 pompeiiBox =
2823                SceneEntity::ComputeBoundingBox(staticObjects);
2824
2825        // todo: dispose texture
2826        Texture *floorTex = new Texture(model_path + "stairs.c.01.tif");
2827
2828        floorTex->SetBoundaryModeS(Texture::REPEAT);
2829        floorTex->SetBoundaryModeT(Texture::REPEAT);
2830
2831        floorTex->Create();
2832        Material *mymat = resourceManager->CreateMaterial();
2833
2834        Technique *tech = mymat->GetDefaultTechnique();
2835        tech->SetDiffuse(RgbaColor(1, 1, 1, 1));
2836        tech->SetTexture(floorTex);
2837
2838        Technique *depthPass = new Technique(*tech);
2839        Technique *deferred = new Technique(*tech);
2840
2841        depthPass->SetColorWriteEnabled(false);
2842        depthPass->SetLightingEnabled(false);
2843
2844        ShaderProgram *defaultFragmentTexProgramMrt =
2845                ShaderManager::GetSingleton()->GetShaderProgram("defaultFragmentTexMrt");
2846        ShaderProgram *defaultVertexProgramMrt =
2847                ShaderManager::GetSingleton()->GetShaderProgram("defaultVertexMrt");
2848
2849        deferred->SetFragmentProgram(defaultFragmentTexProgramMrt);
2850        deferred->SetVertexProgram(defaultVertexProgramMrt);
2851
2852        deferred->GetFragmentProgramParameters()->SetViewMatrixParam(0);
2853        deferred->GetVertexProgramParameters()->SetModelMatrixParam(1);
2854        deferred->GetVertexProgramParameters()->SetOldModelMatrixParam(2);
2855
2856        deferred->SetTexture(floorTex);
2857       
2858        mymat->AddTechnique(deferred);
2859        mymat->AddTechnique(depthPass);
2860
2861
2862        //const Vector3 offs(1300.0f, -2500.0f, .0f);
2863        const Vector3 offs(pompeiiBox.Center(0), pompeiiBox.Center(1), 0);
2864        Matrix4x4 moffs = TranslationMatrix(offs);
2865
2866        Plane3 plane;
2867        Transform3 *mytrafo = resourceManager->CreateTransform(moffs);
2868
2869        SceneEntity *myplane =
2870                SceneEntityConverter().ConvertPlane(plane,
2871                                                    pompeiiBox.Size(0),
2872                                                                                        pompeiiBox.Size(1),
2873                                                                                        5,
2874                                                                                        5,
2875                                                                                        mymat,
2876                                                                                        mytrafo);
2877
2878        resourceManager->AddSceneEntity(myplane);
2879        staticObjects.push_back(myplane);
2880}
2881
2882
2883void LoadOrUpdatePVSs(const Vector3 &pos)
2884{
2885        if (!viewCellsTree)     
2886        {
2887                LoadVisibilitySolution();
2888                applicationTimer.Start();
2889                shotRays = visibilitySolutionInitialState;
2890        }
2891
2892        if (viewCellsTree) UpdatePvs(pos);
2893}
2894
2895
2896void CreateNewInstance(SceneEntity *parent, const Vector3 &pos)
2897{
2898        SceneEntity *ent = new SceneEntity(*parent);
2899        resourceManager->AddSceneEntity(ent);
2900
2901        Matrix4x4 transl = TranslationMatrix(pos);
2902        Transform3 *transform = resourceManager->CreateTransform(transl);
2903
2904        ent->SetTransform(transform);
2905        dynamicObjects.push_back(ent);
2906        //Debug << "positions: " << newPos << endl;
2907}
Note: See TracBrowser for help on using the repository browser.