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

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