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

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