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

Revision 3353, 71.2 KB checked in by mattausch, 15 years ago (diff)

something strange happening in sibenik: reprojection not working!!

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