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

Revision 3057, 46.3 KB checked in by mattausch, 16 years ago (diff)

added a shader manager

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