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

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