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

Revision 3237, 60.7 KB checked in by mattausch, 15 years ago (diff)

debug version

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