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

Revision 3146, 51.9 KB checked in by mattausch, 16 years ago (diff)

normal mapping hack not working yet. found problems with ssao if the geometry is not tesselated enough (especially with smoothed
normals: one can see the underlying tesselation!

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