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

Revision 2965, 48.9 KB checked in by mattausch, 16 years ago (diff)

removed dirttexture stuff. started tonemapping stuff

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