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

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