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

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