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

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