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

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