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

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