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

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