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

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