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

Revision 3367, 72.7 KB checked in by mattausch, 15 years ago (diff)

working nicely but still artifacts where high convergence regions come on low convergence ones

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