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

Revision 2957, 48.3 KB checked in by mattausch, 16 years ago (diff)

preetham working

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