source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/irradiance.cpp @ 3020

Revision 3020, 51.2 KB checked in by mattausch, 16 years ago (diff)

removed most leaks

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