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

Revision 3212, 53.4 KB checked in by mattausch, 16 years ago (diff)

made ssao parameters more flexible
started to implement lense flare

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