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

Revision 3120, 51.2 KB checked in by mattausch, 16 years ago (diff)

worked on filtering now trying to reduce flickering (have to reorder ssao function quite much

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