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

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