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

Revision 3215, 55.3 KB checked in by mattausch, 16 years ago (diff)

worked on lense flare, cleaned up code a little bit

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