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

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