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

Revision 3285, 68.6 KB checked in by mattausch, 15 years ago (diff)

working on viz for submission

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