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

Revision 2844, 57.5 KB checked in by mattausch, 16 years ago (diff)

lod starting to work

Line 
1// occquery.cpp : Defines the entry point for the console application.
2//
3#include "glInterface.h"
4#include <math.h>
5#include <time.h>
6#include "common.h"
7#include "RenderTraverser.h"
8#include "SceneEntity.h"
9#include "Vector3.h"
10#include "Matrix4x4.h"
11#include "ResourceManager.h"
12#include "Bvh.h"
13#include "Camera.h"
14#include "Geometry.h"
15#include "BvhLoader.h"
16#include "FrustumCullingTraverser.h"
17#include "StopAndWaitTraverser.h"
18#include "CHCTraverser.h"
19#include "CHCPlusPlusTraverser.h"
20#include "Visualization.h"
21#include "RenderState.h"
22#include "Timer/PerfTimer.h"
23#include "SceneQuery.h"
24#include "RenderQueue.h"
25#include "Material.h"
26#include <Cg/cg.h>
27#include <Cg/cgGL.h>
28#include "glfont2.h"
29#include "PerformanceGraph.h"
30#include "Environment.h"
31#include "Halton.h"
32#include "Transform3.h"
33
34
35using namespace std;
36using namespace CHCDemoEngine;
37
38
39static Environment env;
40
41
42/////////////
43//-- fbos
44
45GLuint fbo;
46GLuint fbo1;
47GLuint fbo2;
48
49bool isFirstTexture = true;
50
51/////////////
52//-- renderbuffers
53
54
55GLuint depthBuffer;
56
57GLuint positionsBuffer;
58GLuint colorsBuffer;
59GLuint colorsBuffer1;
60GLuint colorsBuffer2;
61GLuint normalsBuffer;
62
63
64/////////////
65//-- textures
66
67
68GLuint positionsTex;
69GLuint colorsTex;
70GLuint colorsTex1;
71GLuint colorsTex2;
72
73GLuint normalsTex;
74
75GLuint noiseTex;
76
77GLuint fontTex;
78
79/// the renderable scene geometry
80SceneEntityContainer sceneEntities;
81// traverses and renders the hierarchy
82RenderTraverser *traverser = NULL;
83/// the hierarchy
84Bvh *bvh = NULL;
85/// handles scene loading
86ResourceManager *loader = NULL;
87/// the scene camera
88Camera *camera = NULL;
89/// the scene camera
90Camera *visCamera = NULL;
91/// the visualization
92Visualization *visualization = NULL;
93/// the current render state
94RenderState state;
95/// the rendering algorithm
96int renderMode = RenderTraverser::CHCPLUSPLUS;
97// eye near plane distance
98float nearDist = 0.2f;
99/// the pixel threshold where a node is still considered invisible
100int threshold;
101
102float fov = 50.0f;
103
104int assumedVisibleFrames = 10;
105int maxBatchSize = 50;
106
107int trianglesPerVirtualLeaf = INITIAL_TRIANGLES_PER_VIRTUAL_LEAVES;
108
109SceneQuery *sceneQuery = NULL;
110RenderQueue *renderQueue = NULL;
111
112/// these values get scaled with the frame rate
113static float keyForwardMotion = 30.0f;
114static float keyRotation = 1.5f;
115
116/// elapsed time in milliseconds
117double elapsedTime = 1000.0f;
118double algTime = 1000.0f;
119
120static int winWidth = 1024;
121static int winHeight = 768;
122static float winAspectRatio = 1.0f;
123
124double accumulatedTime = 1000;
125float fps = 1e3f;
126
127float myfar = 0;
128
129glfont::GLFont myfont;
130
131// rendertexture
132static int texWidth = 1024;
133static int texHeight = 768;
134//static int texWidth = 2048;
135//static int texHeight = 2048;
136
137int renderedObjects = 0;
138int renderedNodes = 0;
139int renderedTriangles = 0;
140
141int issuedQueries = 0;
142int traversedNodes = 0;
143int frustumCulledNodes = 0;
144int queryCulledNodes = 0;
145int stateChanges = 0;
146int numBatches = 0;
147
148bool showHelp = false;
149bool showStatistics = false;
150bool showOptions = false;
151bool showBoundingVolumes = false;
152bool visMode = false;
153
154// mouse navigation state
155int xEyeBegin = 0;
156int yEyeBegin = 0;
157int yMotionBegin = 0;
158int verticalMotionBegin = 0;
159int horizontalMotionBegin = 0;
160
161bool useOptimization = false;
162bool useTightBounds = true;
163bool useRenderQueue = true;
164bool useMultiQueries = true;
165bool flyMode = true;
166
167SceneEntityContainer skyGeometry;
168
169bool leftKeyPressed = false;
170bool rightKeyPressed = false;
171bool upKeyPressed = false;
172bool downKeyPressed = false;
173bool descendKeyPressed = false;
174bool ascendKeyPressed = false;
175
176bool useSsao = false;
177
178bool showAlgorithmTime = false;
179
180GLubyte *randomNormals = NULL;
181
182PerfTimer frameTimer, algTimer;
183
184int renderType = RenderState::FIXED;
185
186PerformanceGraph *perfGraph = NULL;
187
188bool useFullScreen = false;
189
190float expFactor = 0.1f;
191
192// ssao number of samples
193//#define NUM_SAMPLES 8
194#define NUM_SAMPLES 16
195
196// ssao random spherical samples
197static float samples[NUM_SAMPLES * 2];
198
199static Matrix4x4 matProjectionView = IdentityMatrix();
200
201
202// function forward declarations
203void InitExtensions();
204void DisplayVisualization();
205void InitGLstate();
206void InitRenderTexture();
207void InitCg();
208void CleanUp();
209void SetupEyeView();
210void UpdateEyeMtx();
211void SetupLighting();
212void DisplayStats();
213void Output(int x, int y, const char *string);
214void DrawHelpMessage();
215void RenderSky();
216void RenderVisibleObjects();
217
218void Begin2D();
219void End2D();
220void KeyBoard(unsigned char c, int x, int y);
221void DrawStatistics();
222void Display();
223void Special(int c, int x, int y);
224void KeyUp(unsigned char c, int x, int y);
225void SpecialKeyUp(int c, int x, int y);
226void Reshape(int w, int h);
227void Mouse(int button, int state, int x, int y);
228void LeftMotion(int x, int y);
229void RightMotion(int x, int y);
230void MiddleMotion(int x, int y);
231void CalcDecimalPoint(string &str, int d);
232void ResetTraverser();
233
234void KeyHorizontalMotion(float shift);
235void KeyVerticalMotion(float shift);
236
237void PlaceViewer(const Vector3 &oldPos);
238void DisplayRenderTexture();
239
240
241inline float KeyRotationAngle() { return keyRotation * elapsedTime * 1e-3f; }
242inline float KeyShift() { return keyForwardMotion * elapsedTime * 1e-3f; }
243
244void InitFBO();
245
246void CreateNoiseTex2D();
247
248void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br);
249
250void GenerateSamples();
251
252
253GLenum mrt[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT};
254
255
256/////////
257//-- cg stuff
258
259static CGcontext sCgContext = NULL;
260static CGprogram sCgMrtVertexProgram = NULL;
261static CGprogram sCgSsaoProgram = NULL;
262static CGprogram sCgDeferredProgram = NULL;
263
264static CGparameter sColorsTexParam;
265static CGparameter sPositionsTexParam;
266static CGparameter sNormalsTexParam;
267
268static CGparameter sColorsTexParamSsao;
269static CGparameter sPositionsTexParamSsao;
270static CGparameter sNormalsTexParamSsao;
271static CGparameter sNoiseTexParamSsao;
272
273static CGparameter sModelViewProjMatrixParam;
274static CGparameter sOldModelViewProjMatrixParam;
275static CGparameter sMaxDepthParam;
276static CGparameter sMaxDepthParamSsao;
277static CGparameter sMaxDepthParamTex;
278
279static CGparameter sSamplesParamSsao;
280static CGparameter sOldTexParamSsao;
281static CGparameter sNoiseMultiplierParam;
282static CGparameter sExpFactorParamSsao;
283
284
285static void cgErrorCallback()
286{
287        CGerror lastError = cgGetError();
288
289        if(lastError)
290        {
291                printf("%s\n\n", cgGetErrorString(lastError));
292                printf("%s\n", cgGetLastListing(sCgContext));
293                printf("Cg error, exiting...\n");
294
295                exit(0);
296        }
297}
298
299
300static void PrintGLerror(char *msg)
301{
302        GLenum errCode;
303        const GLubyte *errStr;
304       
305        if ((errCode = glGetError()) != GL_NO_ERROR)
306        {
307                errStr = gluErrorString(errCode);
308                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
309        }
310}
311
312
313int main(int argc, char* argv[])
314{
315        int returnCode = 0;
316
317        Vector3 camPos(.0f, .0f, .0f);
318        Vector3 camDir(.0f, 1.0f, .0f);
319
320        cout << "=== reading environment file === " << endl;
321
322        string envFileName = "default.env";
323        if (!env.Read(envFileName))
324        {
325                cerr << "loading environment " << envFileName << " failed!" << endl;
326        }
327        else
328        {
329                env.GetIntParam(string("assumedVisibleFrames"), assumedVisibleFrames);
330                env.GetIntParam(string("maxBatchSize"), maxBatchSize);
331                env.GetIntParam(string("trianglesPerVirtualLeaf"), trianglesPerVirtualLeaf);
332
333                env.GetFloatParam(string("keyForwardMotion"), keyForwardMotion);
334                env.GetFloatParam(string("keyRotation"), keyRotation);
335
336                env.GetIntParam(string("winWidth"), winWidth);
337                env.GetIntParam(string("winHeight"), winHeight);
338
339                env.GetBoolParam(string("useFullScreen"), useFullScreen);
340                env.GetFloatParam(string("expFactor"), expFactor);
341                env.GetVectorParam(string("camPosition"), camPos);
342                env.GetVectorParam(string("camDirection"), camDir);
343
344                //env.GetIntParam(string("numSssaoSamples"), numSsaoSamples);
345
346                cout << "assumedVisibleFrames: " << assumedVisibleFrames << endl;
347                cout << "maxBatchSize: " << maxBatchSize << endl;
348                cout << "trianglesPerVirtualLeaf: " << trianglesPerVirtualLeaf << endl;
349
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;
355                cout << "camPosition: " << camPos << endl;
356                cout << "expFactor: " << expFactor << endl;
357        }
358
359        ///////////////////////////
360
361        camera = new Camera(winWidth, winHeight, fov);
362        camera->SetNear(nearDist);
363       
364        camera->SetDirection(camDir);
365        camera->SetPosition(camPos);
366
367        visCamera = new Camera(winWidth, winHeight, fov);
368
369        visCamera->SetNear(0.0f);
370        visCamera->Yaw(.5 * M_PI);
371
372        renderQueue = new RenderQueue(&state, camera);
373
374        glutInitWindowSize(winWidth, winHeight);
375        glutInit(&argc, argv);
376        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
377
378        if (!useFullScreen)
379                glutCreateWindow("FriendlyCulling");
380        else
381        {
382                glutGameModeString( "1024x768:32@75" );
383                glutEnterGameMode();
384        }
385
386        glutDisplayFunc(Display);
387        glutKeyboardFunc(KeyBoard);
388        glutSpecialFunc(Special);
389        glutReshapeFunc(Reshape);
390        glutMouseFunc(Mouse);
391        glutIdleFunc(Display);
392        glutKeyboardUpFunc(KeyUp);
393        glutSpecialUpFunc(SpecialKeyUp);
394        glutIgnoreKeyRepeat(true);
395
396        // initialise gl graphics
397
398        InitExtensions();
399        InitGLstate();
400       
401        InitFBO();
402       
403        LeftMotion(0, 0);
404        MiddleMotion(0, 0);
405
406        perfGraph = new PerformanceGraph(1000);
407
408        loader = new ResourceManager();
409
410        //const string filename("data/city/model/city.dem");
411        const string filename = string(model_path + "city.dem");
412
413        if (loader->Load(filename, sceneEntities))
414                cout << "scene " << filename << " loaded" << endl;
415        else
416        {
417                cerr << "loading scene " << filename << " failed" << endl;
418                CleanUp();
419                exit(0);
420        }
421
422        SceneEntityContainer dummy;
423
424        const string envname = string(model_path + "env.dem");
425
426        if (loader->Load(envname, skyGeometry))
427                cout << "sky box " << filename << " loaded" << endl;
428        else
429        {
430                cerr << "loading sky box " << filename << " failed" << endl;
431                CleanUp();
432                exit(0);
433        }
434
435        const string bvh_filename = string(model_path + "city.bvh");
436        BvhLoader bvhLoader;
437        bvh = bvhLoader.Load(bvh_filename, sceneEntities);
438
439        if (!bvh)
440        {
441                cerr << "loading bvh " << bvh_filename << " failed" << endl;
442                CleanUp();
443                exit(0);
444        }
445
446        // set far plane based on scene extent
447        myfar = 10.0f * Magnitude(bvh->GetBox().Diagonal());
448        bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
449
450        bvh->SetCamera(camera);
451       
452        InitCg();
453
454        // create noise texture for ssao
455        CreateNoiseTex2D();
456        // init render traverser
457        ResetTraverser();
458
459
460        visualization = new Visualization(bvh, camera, NULL, &state);
461
462        sceneQuery = new SceneQuery(bvh->GetBox(), traverser);
463
464
465        glutMainLoop();
466
467        // clean up
468        CleanUp();
469
470        return 0;
471}
472
473
474void InitCg(void)
475{
476        // Setup Cg
477        cgSetErrorCallback(cgErrorCallback);
478
479        // Create cgContext.
480        sCgContext = cgCreateContext();
481
482        // get the best profile for this hardware
483        RenderState::sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
484        //assert(sCgFragmentProfile != CG_PROFILE_UNKNOWN);
485        cgGLSetOptimalOptions(RenderState::sCgFragmentProfile);
486
487        RenderState::sCgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
488        cgGLSetOptimalOptions(RenderState::sCgVertexProfile);
489
490        sCgMrtVertexProgram =
491                cgCreateProgramFromFile(sCgContext,
492                                                                CG_SOURCE,
493                                                                "src/shaders/mrt.cg",
494                                                                RenderState::sCgVertexProfile,
495                                                                "vtx",
496                                                                NULL);
497
498        if (sCgMrtVertexProgram != NULL)
499        {
500                cgGLLoadProgram(sCgMrtVertexProgram);
501
502                Transform3::sModelMatrixParam = cgGetNamedParameter(sCgMrtVertexProgram, "ModelMatrix");
503                sModelViewProjMatrixParam = cgGetNamedParameter(sCgMrtVertexProgram, "ModelViewProj");
504        }
505
506        RenderState::sCgMrtFragmentTexProgram =
507                cgCreateProgramFromFile(sCgContext,
508                                                                CG_SOURCE,
509                                                                "src/shaders/mrt.cg",
510                                                                RenderState::sCgFragmentProfile,
511                                                                "fragtex",
512                                                                NULL);
513
514        if (RenderState::sCgMrtFragmentTexProgram != NULL)
515        {
516                cgGLLoadProgram(RenderState::sCgMrtFragmentTexProgram);
517
518                sMaxDepthParamTex = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "maxDepth");
519                Material::sDiffuseTexParam = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "diffuse");
520                Material::sAmbientTexParam = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "ambient");
521
522                cgGLSetParameter1f(sMaxDepthParamTex, 10.0f / myfar);
523                Debug << "maxdepth: " << 10.0f / myfar << endl;
524        }
525        else
526                cerr << "fragment tex program failed to load" << endl;
527
528        RenderState::sCgMrtFragmentProgram =
529                cgCreateProgramFromFile(sCgContext,
530                                                                CG_SOURCE,
531                                                                "src/shaders/mrt.cg",
532                                                                RenderState::sCgFragmentProfile,
533                                                                "frag",
534                                                                NULL);
535
536        if (RenderState::sCgMrtFragmentProgram != NULL)
537        {
538                cgGLLoadProgram(RenderState::sCgMrtFragmentProgram);
539
540                sMaxDepthParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "maxDepth");
541                Material::sDiffuseParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "diffuse");
542                Material::sAmbientParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "ambient");
543
544                cgGLSetParameter1f(sMaxDepthParam, 10.0f / myfar);
545        }
546        else
547                cerr << "fragment program failed to load" << endl;
548
549        PrintGLerror("test");
550
551
552        ///////////////
553
554        sCgSsaoProgram =
555                cgCreateProgramFromFile(sCgContext,
556                                                                CG_SOURCE,
557                                                                "src/shaders/deferred.cg",
558                                                                RenderState::sCgFragmentProfile,
559                                                                "main_ssao",
560                                                                NULL);
561
562        if (sCgSsaoProgram != NULL)
563        {
564                cgGLLoadProgram(sCgSsaoProgram);
565
566                // we need size of texture for scaling
567                sPositionsTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "positions"); 
568                sColorsTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "colors"); 
569                sNormalsTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "normals"); 
570                sNoiseTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "noiseTexture");
571                sNoiseMultiplierParam = cgGetNamedParameter(sCgSsaoProgram, "noiseMultiplier");
572                sOldModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "oldModelViewProj");
573                sMaxDepthParamSsao = cgGetNamedParameter(sCgSsaoProgram, "maxDepth");
574                sExpFactorParamSsao = cgGetNamedParameter(sCgSsaoProgram, "expFactor");
575
576                cgGLSetParameter1f(sMaxDepthParamSsao, myfar / 10.0f);
577                cgGLSetParameter1f(sExpFactorParamSsao, expFactor);
578
579                sSamplesParamSsao = cgGetNamedParameter(sCgSsaoProgram, "samples");
580                sOldTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "oldTex"); 
581
582                GenerateSamples(); cgGLSetParameterArray2f(sSamplesParamSsao, 0, NUM_SAMPLES, (const float *)samples);
583        }
584        else
585                cerr << "ssao program failed to load" << endl;
586
587       
588        sCgDeferredProgram =
589                cgCreateProgramFromFile(sCgContext,
590                                                                CG_SOURCE,
591                                                                "src/shaders/deferred.cg",
592                                                                RenderState::sCgFragmentProfile,
593                                                                "main",
594                                                                NULL);
595
596        if (sCgDeferredProgram != NULL)
597        {
598                cgGLLoadProgram(sCgDeferredProgram);
599
600                // we need size of texture for scaling
601                sPositionsTexParam = cgGetNamedParameter(sCgDeferredProgram, "positions"); 
602                sColorsTexParam = cgGetNamedParameter(sCgDeferredProgram, "colors"); 
603                sNormalsTexParam = cgGetNamedParameter(sCgDeferredProgram, "normals");
604        }
605        else
606                cerr << "deferred program failed to load" << endl;
607
608
609        PrintGLerror("init");
610
611        cout << "cg initialization successful" << endl;
612}
613
614
615void PrintFBOStatus(GLenum status)
616{
617        switch(status)
618        {
619        case GL_FRAMEBUFFER_COMPLETE_EXT:
620                cout << "frame buffer object created successfully" << endl;
621                break;
622        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
623                cerr << "incomplete attachment" << endl;
624                break;
625        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
626                cerr << "missing attachment" << endl;
627                break;
628        case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
629                cerr << "incomplete dimensions" << endl;
630                break;
631        case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
632                cerr << "incomplete formats" << endl;
633                break;
634        case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
635                cerr << "incomplete draw buffer" << endl;
636                break;
637        case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
638                cerr << "incomplete read buffer" << endl;
639                break;
640        case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
641                cerr << "framebuffer unsupported" << endl;
642                break;
643        default:
644                cerr << "unknown status code " << status << endl;
645        }
646}
647
648
649void InitFBO()
650{
651        glGenFramebuffersEXT(1, &fbo);
652        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
653
654       
655        ////////////
656        //-- colors buffer
657
658        glGenRenderbuffersEXT(1, &colorsBuffer);
659        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorsBuffer);
660       
661        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, texWidth, texHeight);
662        int samples = 8;
663        //glEnable(GL_MULTISAMPLE_ARB);
664        //glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_RGBA8, texWidth, texHeight);
665        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorsBuffer);
666       
667        glGenTextures(1, &colorsTex);
668        glBindTexture(GL_TEXTURE_2D, colorsTex);
669
670        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
671        //glGenerateMipmapEXT(GL_TEXTURE_2D);
672        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorsTex, 0);
673
674        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
675        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
676
677        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
678        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
679
680
681        //////////
682        //-- positions buffer
683
684        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
685        glGenRenderbuffersEXT(1, &positionsBuffer);
686        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, positionsBuffer);
687        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, texWidth, texHeight);
688
689        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER_EXT, positionsBuffer);
690
691        glGenTextures(1, &positionsTex);
692        glBindTexture(GL_TEXTURE_2D, positionsTex);
693        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
694        //glGenerateMipmapEXT(GL_TEXTURE_2D);
695        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, positionsTex, 0);
696
697        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
698        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
699
700        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
701        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
702
703        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
704       
705       
706        ////////
707        //-- normals buffer
708
709        glGenRenderbuffersEXT(1, &normalsBuffer);
710        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, normalsBuffer);
711        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, texWidth, texHeight);
712       
713        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_RENDERBUFFER_EXT, normalsBuffer);
714
715        glGenTextures(1, &normalsTex);
716        glBindTexture(GL_TEXTURE_2D, normalsTex);
717        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
718        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, normalsTex, 0);
719
720        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
721        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
722
723        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
724        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
725
726        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
727
728
729        ///////////
730        //-- create depth buffer
731
732        glGenRenderbuffersEXT(1, &depthBuffer);
733        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
734        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, texWidth, texHeight);
735        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
736
737       
738        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
739       
740       
741
742        //////////////////////////////////
743
744
745
746        glGenFramebuffersEXT(1, &fbo1);
747        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo1);
748
749       
750        ////////////
751        //-- colors buffer
752
753        glGenRenderbuffersEXT(1, &colorsBuffer1);
754        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorsBuffer1);
755       
756        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, texWidth, texHeight);
757        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorsBuffer1);
758       
759        glGenTextures(1, &colorsTex1);
760        glBindTexture(GL_TEXTURE_2D, colorsTex1);
761
762        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
763        //glGenerateMipmapEXT(GL_TEXTURE_2D);
764        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorsTex1, 0);
765
766        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
767        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
768
769        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
770        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
771
772        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
773        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
774
775        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
776
777
778
779        /////////////////////////
780
781        glGenFramebuffersEXT(1, &fbo2);
782        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
783
784       
785        ////////////
786        //-- colors buffer
787
788        glGenRenderbuffersEXT(1, &colorsBuffer2);
789        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorsBuffer2);
790       
791        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, texWidth, texHeight);
792        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorsBuffer2);
793       
794        glGenTextures(1, &colorsTex2);
795        glBindTexture(GL_TEXTURE_2D, colorsTex2);
796
797        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
798        //glGenerateMipmapEXT(GL_TEXTURE_2D);
799        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorsTex2, 0);
800
801        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
802        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
803
804        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
805        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
806
807        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
808        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
809
810        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
811        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
812
813        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
814
815        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
816
817        PrintGLerror("fbo");
818}
819
820
821bool InitFont(void)
822{
823        glEnable(GL_TEXTURE_2D);
824
825        glGenTextures(1, &fontTex);
826        glBindTexture(GL_TEXTURE_2D, fontTex);
827        if (!myfont.Create("data/fonts/verdana.glf", fontTex))
828                return false;
829
830        glDisable(GL_TEXTURE_2D);
831       
832        return true;
833}
834
835
836void InitGLstate()
837{
838        glClearColor(0.5f, 0.5f, 0.8f, 0.0f);
839       
840        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
841        glPixelStorei(GL_PACK_ALIGNMENT,1);
842       
843        glDepthFunc(GL_LESS);
844        glEnable(GL_DEPTH_TEST);
845
846        SetupLighting();
847
848        glColor3f(1.0f, 1.0f, 1.0f);
849        glShadeModel(GL_SMOOTH);
850       
851        glMaterialf(GL_FRONT, GL_SHININESS, 64);
852        glEnable(GL_NORMALIZE);
853               
854        //glEnable(GL_ALPHA_TEST);
855        glDisable(GL_ALPHA_TEST);
856        glAlphaFunc(GL_GEQUAL, 0.8f);
857
858        glFrontFace(GL_CCW);
859        glCullFace(GL_BACK);
860        glEnable(GL_CULL_FACE);
861        //glDisable(GL_CULL_FACE);
862        glDisable(GL_TEXTURE_2D);
863
864        GLfloat ambientColor[] = {0.5, 0.5, 0.5, 1.0};
865        GLfloat diffuseColor[] = {1.0, 0.0, 0.0, 1.0};
866        GLfloat specularColor[] = {0.0, 0.0, 0.0, 1.0};
867
868        glMaterialfv(GL_FRONT, GL_AMBIENT, ambientColor);
869        glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor);
870        glMaterialfv(GL_FRONT, GL_SPECULAR, specularColor);
871
872        glDepthFunc(GL_LESS);
873
874        if (!InitFont())
875                cerr << "font creation failed" << endl;
876        else
877                cout << "successfully created font" << endl;
878}
879
880
881void DrawHelpMessage()
882{
883        const char *message[] =
884        {
885                "Help information",
886                "",
887                "'F1'           - shows/dismisses this message",
888                "'F2'           - shows/hides bird eye view",
889                "'F3'           - shows/hides bounds (boxes or tight bounds)",
890                "'F4',          - shows/hides parameters",
891                "'F5'           - shows/hides statistics",
892                "'F6',          - toggles between fly/walkmode",
893                "'F7',          - cycles throw render modes",
894                "'F8',          - enables/disables ambient occlusion (only deferred)",
895                "'F9',          - shows pure algorithm render time (using glFinish)",
896                "'SPACE'        - cycles through occlusion culling algorithms",
897                "",
898                "'MOUSE LEFT'        - turn left/right, move forward/backward",
899                "'MOUSE RIGHT'       - turn left/right, move forward/backward",
900                "'MOUSE MIDDLE'      - move up/down, left/right",
901                "'CURSOR UP/DOWN'    - move forward/backward",
902                "'CURSOR LEFT/RIGHT' - turn left/right",
903                "",
904                "'-'/'+'        - decreases/increases max batch size",
905                "'1'/'2'        - downward/upward motion",
906                "'3'/'4'        - decreases/increases triangles per virtual bvh leaf (sets bvh depth)",
907                "'5'/'6'        - decreases/increases assumed visible frames",
908                "",
909                "'R'            - use render queue",
910                "'B'            - use tight bounds",
911                "'M'            - use multiqueries",
912                "'O'            - use CHC optimization (geometry queries for leaves)",
913                0,
914        };
915       
916       
917        glColor4f(0.0f, 1.0f , 0.0f, 0.2f); // 20% green.
918
919        glRecti(30, 30, winWidth - 30, winHeight - 30);
920
921        glEnd();
922
923        glColor3f(1.0f, 1.0f, 1.0f);
924       
925        glEnable(GL_TEXTURE_2D);
926        myfont.Begin();
927
928        int x = 40, y = 30;
929
930        for(int i = 0; message[i] != 0; ++ i)
931        {
932                if(message[i][0] == '\0')
933                {
934                        y += 15;
935                }
936                else
937                {
938                        myfont.DrawString(message[i], x, winHeight - y);
939                        y += 25;
940                }
941        }
942        glDisable(GL_TEXTURE_2D);
943}
944
945
946void ResetTraverser()
947{
948        DEL_PTR(traverser);
949
950        bvh->ResetNodeClassifications();
951
952        switch (renderMode)
953        {
954        case RenderTraverser::CULL_FRUSTUM:
955                traverser = new FrustumCullingTraverser();
956                break;
957        case RenderTraverser::STOP_AND_WAIT:
958                traverser = new StopAndWaitTraverser();
959                break;
960        case RenderTraverser::CHC:
961                traverser = new CHCTraverser();
962                break;
963        case RenderTraverser::CHCPLUSPLUS:
964                traverser = new CHCPlusPlusTraverser();
965                break;
966       
967        default:
968                traverser = new FrustumCullingTraverser();
969        }
970
971        traverser->SetCamera(camera);
972        traverser->SetHierarchy(bvh);
973        traverser->SetRenderQueue(renderQueue);
974        traverser->SetRenderState(&state);
975        traverser->SetUseOptimization(useOptimization);
976        traverser->SetUseRenderQueue(useRenderQueue);
977        traverser->SetVisibilityThreshold(threshold);
978        traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
979        traverser->SetMaxBatchSize(maxBatchSize);
980        traverser->SetUseMultiQueries(useMultiQueries);
981        traverser->SetUseTightBounds(useTightBounds);
982        traverser->SetUseDepthPass(renderType == RenderState::DEPTH_PASS);
983        traverser->SetRenderQueue(renderQueue);
984}
985
986
987void SetupLighting()
988{
989        glEnable(GL_LIGHTING);
990        glEnable(GL_LIGHT0);
991        glEnable(GL_LIGHT1);
992       
993        GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
994        GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0};
995        GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
996           
997        GLfloat lmodel_ambient[] = {0.3f, 0.3f, 0.3f, 1.0f};
998
999        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
1000        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
1001        glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
1002
1003
1004        ////////////
1005        //-- second light
1006
1007        GLfloat ambient1[] = {0.2, 0.2, 0.2, 1.0};
1008        GLfloat diffuse1[] = {1.0, 1.0, 1.0, 1.0};
1009        //GLfloat diffuse1[] = {0.5, 0.5, 0.5, 1.0};
1010        GLfloat specular1[] = {0.0, 0.0, 0.0, 1.0};
1011
1012        glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1);
1013        glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1);
1014        glLightfv(GL_LIGHT1, GL_SPECULAR, specular1);
1015
1016       
1017        //////////////////////////////
1018
1019        GLfloat position[] = {0.8f, -1.0f, 0.7f, 0.0f};
1020        glLightfv(GL_LIGHT0, GL_POSITION, position);
1021
1022        GLfloat position1[] = {-0.5f, 0.5f, 0.4f, 0.0f};
1023        glLightfv(GL_LIGHT1, GL_POSITION, position1);
1024
1025        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
1026        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1027        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SINGLE_COLOR_EXT);
1028}
1029
1030
1031void SetupEyeView()
1032{
1033        Matrix4x4 matViewing, matProjection;
1034
1035        if (renderType == RenderState::DEFERRED)
1036        {
1037                cgGLSetMatrixParameterfc(sOldModelViewProjMatrixParam, (const float *)matProjectionView.x);
1038        }
1039
1040        glMatrixMode(GL_PROJECTION);
1041        glLoadIdentity();
1042
1043        gluPerspective(fov, winAspectRatio, nearDist, myfar);
1044
1045        glMatrixMode(GL_MODELVIEW);
1046        glLoadIdentity();
1047        camera->SetupCameraView();
1048
1049        GLfloat position[] = {0.8f, -1.0f, 0.7f, 0.0f};
1050        glLightfv(GL_LIGHT0, GL_POSITION, position);
1051
1052        GLfloat position1[] = {-0.5f, 0.5f, 0.4f, 0.0f};
1053        glLightfv(GL_LIGHT1, GL_POSITION, position1);
1054
1055       
1056        camera->GetModelViewMatrix(matViewing);
1057        camera->GetProjectionMatrix(matProjection);
1058
1059        matProjectionView = matViewing * matProjection;
1060       
1061        if (renderType == RenderState::DEFERRED)
1062        {
1063                // set modelview matrix for shaders
1064                cgGLSetStateMatrixParameter(sModelViewProjMatrixParam,
1065                                                                        CG_GL_MODELVIEW_PROJECTION_MATRIX,
1066                                                                        CG_GL_MATRIX_IDENTITY);
1067
1068                static Matrix4x4 identity = IdentityMatrix();
1069                cgGLSetMatrixParameterfc(Transform3::sModelMatrixParam, (const float *)identity.x);
1070        }               
1071}
1072
1073
1074void KeyHorizontalMotion(float shift)
1075{
1076        Vector3 hvec = camera->GetDirection();
1077        hvec.z = 0;
1078
1079        Vector3 pos = camera->GetPosition();
1080        pos += hvec * shift;
1081       
1082        camera->SetPosition(pos);
1083}
1084
1085
1086void KeyVerticalMotion(float shift)
1087{
1088        Vector3 uvec = Vector3(0, 0, shift);
1089
1090        Vector3 pos = camera->GetPosition();
1091        pos += uvec;
1092       
1093        camera->SetPosition(pos);
1094}
1095
1096
1097void Display()
1098{       
1099        glFlush();
1100        elapsedTime = frameTimer.Elapsedms();
1101
1102        // take time from last frame
1103        frameTimer.Start();
1104
1105        Vector3 oldPos = camera->GetPosition();
1106
1107        if (leftKeyPressed)
1108                camera->Pitch(KeyRotationAngle());
1109        if (rightKeyPressed)
1110                camera->Pitch(-KeyRotationAngle());
1111        if (upKeyPressed)
1112                KeyHorizontalMotion(KeyShift());
1113        if (downKeyPressed)
1114                KeyHorizontalMotion(-KeyShift());
1115        if (ascendKeyPressed)
1116                KeyVerticalMotion(KeyShift());
1117        if (descendKeyPressed)
1118                KeyVerticalMotion(-KeyShift());
1119
1120        // place view on ground
1121        if (!flyMode) PlaceViewer(oldPos);
1122
1123        if (showAlgorithmTime)
1124        {
1125                glFinish();
1126                algTimer.Start();
1127        }
1128       
1129        // render without shading
1130        switch (renderType)
1131        {
1132        case RenderState::FIXED:
1133       
1134                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1135
1136                state.SetRenderType(RenderState::FIXED);
1137                glEnable(GL_LIGHTING);
1138
1139                cgGLDisableProfile(RenderState::sCgFragmentProfile);
1140                cgGLDisableProfile(RenderState::sCgVertexProfile);
1141
1142                glDrawBuffers(1, mrt);
1143
1144                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1145
1146                break;
1147
1148        case RenderState::DEPTH_PASS:
1149                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1150
1151                state.SetRenderType(RenderState::DEPTH_PASS);
1152                glDisable(GL_LIGHTING);
1153
1154                cgGLDisableProfile(RenderState::sCgFragmentProfile);
1155                cgGLDisableProfile(RenderState::sCgVertexProfile);
1156       
1157                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1158
1159                glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1160
1161                glDrawBuffers(1, mrt);
1162
1163                break;
1164       
1165        case RenderState::DEFERRED:
1166                state.SetRenderType(RenderState::DEFERRED);
1167
1168                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
1169       
1170                glPushAttrib(GL_VIEWPORT_BIT);
1171                glViewport(0, 0, texWidth, texHeight);
1172
1173                cgGLEnableProfile(RenderState::sCgFragmentProfile);
1174                cgGLBindProgram(RenderState::sCgMrtFragmentProgram);
1175
1176                cgGLEnableProfile(RenderState::sCgVertexProfile);
1177                cgGLBindProgram(sCgMrtVertexProgram);
1178
1179                glDrawBuffers(3, mrt);
1180
1181                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1182
1183                break;
1184        }
1185
1186
1187        glDepthFunc(GL_LESS);
1188
1189        glDisable(GL_TEXTURE_2D);
1190        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1191               
1192
1193        // bring eye modelview matrix up-to-date
1194        SetupEyeView();
1195
1196
1197        /*state.Reset();
1198        state.SetState(RenderState::RENDER);
1199       
1200        glEnableClientState(GL_VERTEX_ARRAY);
1201        glEnableClientState(GL_NORMAL_ARRAY);
1202
1203        for (int i = 0; i < loader->mSceneEntities.size(); ++ i)
1204        {
1205                SceneEntity *ent = loader->mSceneEntities[i];
1206
1207                ent->UpdateLODs(camera);
1208                ent->Render(&state);
1209        }*/
1210
1211        // actually render the scene geometry using one of the specified algorithms
1212        traverser->RenderScene();
1213
1214
1215
1216        /////////
1217        //-- do the rest of the rendering
1218
1219        glEnableClientState(GL_VERTEX_ARRAY);
1220        glEnableClientState(GL_NORMAL_ARRAY);
1221
1222
1223        // reset depth pass and render visible objects
1224        if (renderType == RenderState::DEPTH_PASS)
1225        {
1226                glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1227                RenderVisibleObjects();
1228        }
1229       
1230
1231        ///////////////
1232        //-- render sky
1233
1234        RenderSky();
1235
1236        state.Reset();
1237
1238        glDisableClientState(GL_VERTEX_ARRAY);
1239        glDisableClientState(GL_NORMAL_ARRAY);
1240
1241        if (renderType == RenderState::DEFERRED)
1242        {
1243                glPopAttrib();
1244                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1245
1246                cgGLDisableProfile(RenderState::sCgVertexProfile);
1247                cgGLDisableProfile(RenderState::sCgFragmentProfile);
1248
1249                glDrawBuffers(1, mrt);
1250
1251                DisplayRenderTexture();
1252        }
1253
1254       
1255        ///////////
1256
1257        state.SetRenderType(RenderState::FIXED);
1258
1259        if (showAlgorithmTime)
1260        {
1261                glFinish();
1262
1263                algTime = algTimer.Elapsedms();
1264                perfGraph->AddData(algTime);
1265
1266                perfGraph->Draw();
1267        }
1268        else
1269        {
1270                if (visMode) DisplayVisualization();
1271        }
1272
1273        DisplayStats();
1274
1275        isFirstTexture = !isFirstTexture;
1276
1277        glutSwapBuffers();
1278}
1279
1280
1281#pragma warning( disable : 4100 )
1282void KeyBoard(unsigned char c, int x, int y)
1283{
1284        switch(c)
1285        {
1286        case 27:
1287                CleanUp();
1288                exit(0);
1289                break;
1290        case 32: //space
1291                renderMode = (renderMode + 1) % RenderTraverser::NUM_TRAVERSAL_TYPES;
1292                ResetTraverser();
1293                break;
1294        case 'h':
1295        case 'H':
1296                showHelp = !showHelp;
1297                break;
1298        case '+':
1299                maxBatchSize += 10;
1300                traverser->SetMaxBatchSize(maxBatchSize);
1301                break;
1302        case '-':
1303                maxBatchSize -= 10;
1304                if (maxBatchSize < 0) maxBatchSize = 1;
1305                traverser->SetMaxBatchSize(maxBatchSize);               
1306                break;
1307        case 'M':
1308        case 'm':
1309                useMultiQueries = !useMultiQueries;
1310                traverser->SetUseMultiQueries(useMultiQueries);
1311                break;
1312        case '1':
1313                descendKeyPressed = true;
1314                break;
1315        case '2':
1316                ascendKeyPressed = true;
1317                break;
1318        case '3':
1319                if (trianglesPerVirtualLeaf >= 100)
1320                        trianglesPerVirtualLeaf -= 100;
1321                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1322                break;
1323        case '4':
1324                trianglesPerVirtualLeaf += 100;
1325                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1326                break;
1327        case '5':
1328                assumedVisibleFrames -= 1;
1329                if (assumedVisibleFrames < 1) assumedVisibleFrames = 1;
1330                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
1331                break;
1332        case '6':
1333                assumedVisibleFrames += 1;
1334                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);               
1335                break;
1336        case '7':
1337                expFactor *= 0.5f;
1338                break;
1339        case '8':
1340                expFactor *= 2.0f;
1341                if (expFactor > 1.0f) expFactor = 1.0f;
1342                break;
1343        case 'o':
1344        case 'O':
1345                useOptimization = !useOptimization;
1346                traverser->SetUseOptimization(useOptimization);
1347                break;
1348        case 'a':
1349        case 'A':
1350                        leftKeyPressed = true;
1351                break;
1352        case 'd':
1353        case 'D':
1354                        rightKeyPressed = true;
1355                break;
1356        case 'w':
1357        case 'W':
1358                        upKeyPressed = true;
1359                break;
1360        case 's':
1361        case 'S':
1362                        downKeyPressed = true;
1363                break;
1364        case 'r':
1365        case 'R':
1366                {
1367                        useRenderQueue = !useRenderQueue;
1368                        traverser->SetUseRenderQueue(useRenderQueue);
1369                }
1370                break;
1371        case 'b':
1372        case 'B':
1373                {
1374                        useTightBounds = !useTightBounds;
1375                        traverser->SetUseTightBounds(useTightBounds);
1376                }
1377                break;
1378        default:
1379                return;
1380        }
1381
1382        glutPostRedisplay();
1383}
1384
1385
1386void SpecialKeyUp(int c, int x, int y)
1387{
1388        switch (c)
1389        {
1390        case GLUT_KEY_LEFT:
1391                leftKeyPressed = false;
1392                break;
1393        case GLUT_KEY_RIGHT:
1394                rightKeyPressed = false;
1395                break;
1396        case GLUT_KEY_UP:
1397                upKeyPressed = false;
1398                break;
1399        case GLUT_KEY_DOWN:
1400                downKeyPressed = false;
1401                break;
1402        default:
1403                return;
1404        }
1405        //glutPostRedisplay();
1406}
1407
1408
1409void KeyUp(unsigned char c, int x, int y)
1410{
1411        switch (c)
1412        {
1413        case 'A':
1414        case 'a':
1415                leftKeyPressed = false;
1416                break;
1417        case 'D':
1418        case 'd':
1419                rightKeyPressed = false;
1420                break;
1421        case 'W':
1422        case 'w':
1423                upKeyPressed = false;
1424                break;
1425        case 'S':
1426        case 's':
1427                downKeyPressed = false;
1428                break;
1429        case '1':
1430                descendKeyPressed = false;
1431                break;
1432        case '2':
1433                ascendKeyPressed = false;
1434                break;
1435       
1436        default:
1437                return;
1438        }
1439        //glutPostRedisplay();
1440}
1441
1442
1443void Special(int c, int x, int y)
1444{
1445        switch(c)
1446        {
1447        case GLUT_KEY_F1:
1448                showHelp = !showHelp;
1449                break;
1450        case GLUT_KEY_F2:
1451                visMode = !visMode;
1452                break;
1453        case GLUT_KEY_F3:
1454                showBoundingVolumes = !showBoundingVolumes;
1455                traverser->SetShowBounds(showBoundingVolumes);
1456                break;
1457        case GLUT_KEY_F4:
1458                showOptions = !showOptions;
1459                break;
1460        case GLUT_KEY_F5:
1461                showStatistics = !showStatistics;
1462                break;
1463        case GLUT_KEY_F6:
1464                flyMode = !flyMode;
1465                break;
1466        case GLUT_KEY_F7:
1467
1468                renderType = (renderType + 1) % 3;
1469                traverser->SetUseDepthPass(renderType == RenderState::DEPTH_PASS);
1470               
1471                break;
1472        case GLUT_KEY_F8:
1473                useSsao = !useSsao;
1474                break;
1475        case GLUT_KEY_F9:
1476                showAlgorithmTime = !showAlgorithmTime;
1477                break;
1478
1479        case GLUT_KEY_LEFT:
1480                {
1481                        leftKeyPressed = true;
1482                        camera->Pitch(KeyRotationAngle());
1483                }
1484                break;
1485        case GLUT_KEY_RIGHT:
1486                {
1487                        rightKeyPressed = true;
1488                        camera->Pitch(-KeyRotationAngle());
1489                }
1490                break;
1491        case GLUT_KEY_UP:
1492                {
1493                        upKeyPressed = true;
1494                        KeyHorizontalMotion(KeyShift());
1495                }
1496                break;
1497        case GLUT_KEY_DOWN:
1498                {
1499                        downKeyPressed = true;
1500                        KeyHorizontalMotion(-KeyShift());
1501                }
1502                break;
1503        default:
1504                return;
1505
1506        }
1507
1508        glutPostRedisplay();
1509}
1510
1511#pragma warning( default : 4100 )
1512
1513
1514void Reshape(int w, int h)
1515{
1516        winAspectRatio = 1.0f;
1517
1518        glViewport(0, 0, w, h);
1519       
1520        winWidth = w;
1521        winHeight = h;
1522
1523        if (w) winAspectRatio = (float) w / (float) h;
1524
1525        glMatrixMode(GL_PROJECTION);
1526        glLoadIdentity();
1527
1528        gluPerspective(fov, winAspectRatio, nearDist, myfar);
1529
1530        glMatrixMode(GL_MODELVIEW);
1531
1532        glutPostRedisplay();
1533}
1534
1535
1536void Mouse(int button, int state, int x, int y)
1537{
1538        if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
1539        {
1540                xEyeBegin = x;
1541                yMotionBegin = y;
1542
1543                glutMotionFunc(LeftMotion);
1544        }
1545        else if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN))
1546        {
1547                xEyeBegin = x;
1548                yEyeBegin = y;
1549                yMotionBegin = y;
1550
1551                glutMotionFunc(RightMotion);
1552        }
1553        else if ((button == GLUT_MIDDLE_BUTTON) && (state == GLUT_DOWN))
1554        {
1555                horizontalMotionBegin = x;
1556                verticalMotionBegin = y;
1557                glutMotionFunc(MiddleMotion);
1558        }
1559
1560        glutPostRedisplay();
1561}
1562
1563
1564/**     rotation for left/right mouse drag
1565        motion for up/down mouse drag
1566*/
1567void LeftMotion(int x, int y)
1568{
1569        Vector3 viewDir = camera->GetDirection();
1570        Vector3 pos = camera->GetPosition();
1571
1572        // don't move in the vertical direction
1573        Vector3 horView(viewDir[0], viewDir[1], 0);
1574       
1575        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
1576
1577        camera->Pitch(eyeXAngle);
1578
1579        pos += horView * (yMotionBegin - y) * 0.2f;
1580       
1581        camera->SetPosition(pos);
1582       
1583        xEyeBegin = x;
1584        yMotionBegin = y;
1585
1586        glutPostRedisplay();
1587}
1588
1589
1590/**     rotation for left / right mouse drag
1591        motion for up / down mouse drag
1592*/
1593void RightMotion(int x, int y)
1594{
1595        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
1596        float eyeYAngle = -0.2f *  M_PI * (yEyeBegin - y) / 180.0;
1597
1598        camera->Yaw(eyeYAngle);
1599        camera->Pitch(eyeXAngle);
1600
1601        xEyeBegin = x;
1602        yEyeBegin = y;
1603
1604        glutPostRedisplay();
1605}
1606
1607
1608// strafe
1609void MiddleMotion(int x, int y)
1610{
1611        Vector3 viewDir = camera->GetDirection();
1612        Vector3 pos = camera->GetPosition();
1613
1614        // the 90 degree rotated view vector
1615        // y zero so we don't move in the vertical
1616        Vector3 rVec(viewDir[0], viewDir[1], 0);
1617       
1618        Matrix4x4 rot = RotationZMatrix(M_PI * 0.5f);
1619        rVec = rot * rVec;
1620       
1621        pos -= rVec * (x - horizontalMotionBegin) * 0.1f;
1622        pos[2] += (verticalMotionBegin - y) * 0.1f;
1623
1624        camera->SetPosition(pos);
1625
1626        horizontalMotionBegin = x;
1627        verticalMotionBegin = y;
1628
1629        glutPostRedisplay();
1630}
1631
1632
1633void InitExtensions(void)
1634{
1635        GLenum err = glewInit();
1636
1637        if (GLEW_OK != err)
1638        {
1639                // problem: glewInit failed, something is seriously wrong
1640                fprintf(stderr,"Error: %s\n", glewGetErrorString(err));
1641                exit(1);
1642        }
1643        if  (!GLEW_ARB_occlusion_query)
1644        {
1645                printf("I require the GL_ARB_occlusion_query to work.\n");
1646                exit(1);
1647        }
1648}
1649
1650
1651void Begin2D()
1652{
1653        glDisable(GL_LIGHTING);
1654        glDisable(GL_DEPTH_TEST);
1655
1656        glMatrixMode(GL_PROJECTION);
1657        glPushMatrix();
1658        glLoadIdentity();
1659
1660        gluOrtho2D(0, winWidth, 0, winHeight);
1661
1662        glMatrixMode(GL_MODELVIEW);
1663        glPushMatrix();
1664        glLoadIdentity();
1665}
1666
1667
1668void End2D()
1669{
1670        glMatrixMode(GL_PROJECTION);
1671        glPopMatrix();
1672
1673        glMatrixMode(GL_MODELVIEW);
1674        glPopMatrix();
1675
1676        glEnable(GL_LIGHTING);
1677        glEnable(GL_DEPTH_TEST);
1678}
1679
1680
1681// displays the visualisation of culling algorithm
1682void DisplayVisualization()
1683{
1684        visualization->SetFrameId(traverser->GetCurrentFrameId());
1685       
1686        Begin2D();
1687        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1688        glEnable(GL_BLEND);
1689        glColor4f(0.0f ,0.0f, 0.0f, 0.5f);
1690
1691        glRecti(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth, winHeight);
1692        glDisable(GL_BLEND);
1693        End2D();
1694       
1695       
1696        AxisAlignedBox3 box = bvh->GetBox();
1697
1698        // hack: set far plane for viz
1699        camera->SetFar(0.35f * Magnitude(box.Diagonal()));
1700
1701        const float offs = box.Size().x * 0.3f;
1702       
1703        //Vector3 vizpos = Vector3(box.Min().x, box.Min().y + box.Size().y * 0.5f, box.Min().z + box.Size().z * 50);
1704        Vector3 vizpos = Vector3(box.Min().x, box.Min().y  - box.Size().y * 0.35f, box.Min().z + box.Size().z * 50);
1705       
1706        visCamera->SetPosition(vizpos);
1707        visCamera->ResetPitchAndYaw();
1708        //visCamera->Pitch(M_PI);
1709
1710        glPushAttrib(GL_VIEWPORT_BIT);
1711        glViewport(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth / 3, winHeight / 3);
1712
1713        glMatrixMode(GL_PROJECTION);
1714        glPushMatrix();
1715
1716        glLoadIdentity();
1717       
1718        glOrtho(-offs, offs, -offs, offs, 0.0f, box.Size().z * 100.0f);
1719
1720        glMatrixMode(GL_MODELVIEW);
1721        glPushMatrix();
1722
1723        visCamera->SetupCameraView();
1724
1725        //Matrix4x4 rotX = RotationXMatrix(camera->GetYaw());
1726        //glMultMatrixf((float *)rotX.x);
1727        Matrix4x4 rotZ = RotationZMatrix(-camera->GetPitch());
1728        glMultMatrixf((float *)rotZ.x);
1729
1730        Vector3 pos = camera->GetPosition();
1731        glTranslatef(-pos.x, -pos.y, -pos.z);
1732
1733
1734        GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
1735        glLightfv(GL_LIGHT0, GL_POSITION, position);
1736
1737        GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
1738        glLightfv(GL_LIGHT1, GL_POSITION, position1);
1739
1740        glClear(GL_DEPTH_BUFFER_BIT);
1741
1742
1743        ////////////
1744        //-- visualization of the occlusion culling
1745
1746        visualization->Render();
1747       
1748       
1749        // reset previous settings
1750        glPopAttrib();
1751
1752        glMatrixMode(GL_PROJECTION);
1753        glPopMatrix();
1754        glMatrixMode(GL_MODELVIEW);
1755        glPopMatrix();
1756}
1757
1758
1759// cleanup routine after the main loop
1760void CleanUp()
1761{
1762        DEL_PTR(traverser);
1763        DEL_PTR(sceneQuery);
1764        DEL_PTR(bvh);
1765        DEL_PTR(visualization);
1766        DEL_PTR(camera);
1767        DEL_PTR(loader);
1768        DEL_PTR(renderQueue);
1769        DEL_PTR(perfGraph);
1770
1771        if (sCgMrtVertexProgram)
1772                cgDestroyProgram(sCgMrtVertexProgram);
1773        if (RenderState::sCgMrtFragmentProgram)
1774                cgDestroyProgram(RenderState::sCgMrtFragmentProgram);
1775        if (RenderState::sCgMrtFragmentTexProgram)
1776                cgDestroyProgram(RenderState::sCgMrtFragmentTexProgram);
1777        if (sCgSsaoProgram)
1778                cgDestroyProgram(sCgSsaoProgram);
1779        if (sCgDeferredProgram)
1780                cgDestroyProgram(sCgDeferredProgram);
1781        if (sCgContext)
1782                cgDestroyContext(sCgContext);
1783
1784        glDeleteFramebuffersEXT(1, &fbo);
1785        glDeleteRenderbuffersEXT(1, &depthBuffer);
1786        glDeleteRenderbuffersEXT(1, &colorsBuffer);
1787        glDeleteRenderbuffersEXT(1, &normalsBuffer);
1788        glDeleteRenderbuffersEXT(1, &positionsBuffer);
1789
1790        glDeleteTextures(1, &colorsTex);
1791        glDeleteTextures(1, &normalsTex);
1792        glDeleteTextures(1, &positionsTex);
1793        glDeleteTextures(1, &noiseTex);
1794        glDeleteTextures(1, &fontTex);
1795}
1796
1797
1798// this function inserts a dezimal point after each 1000
1799void CalcDecimalPoint(string &str, int d, int len)
1800{
1801        static vector<int> numbers;
1802        numbers.clear();
1803
1804        static string shortStr;
1805        shortStr.clear();
1806
1807        static char hstr[100];
1808
1809        while (d != 0)
1810        {
1811                numbers.push_back(d % 1000);
1812                d /= 1000;
1813        }
1814
1815        // first element without leading zeros
1816        if (numbers.size() > 0)
1817        {
1818                sprintf(hstr, "%d", numbers.back());
1819                shortStr.append(hstr);
1820        }
1821       
1822        for (int i = (int)numbers.size() - 2; i >= 0; i--)
1823        {
1824                sprintf(hstr, ",%03d", numbers[i]);
1825                shortStr.append(hstr);
1826        }
1827
1828        int dif = len - (int)shortStr.size();
1829
1830        for (int i = 0; i < dif; ++ i)
1831        {
1832                str += " ";
1833        }
1834
1835        str.append(shortStr);
1836}
1837
1838
1839void DisplayStats()
1840{
1841        static char msg[9][300];
1842
1843        static double frameTime = elapsedTime;
1844        static double renderTime = algTime;
1845
1846        const float expFactor = 0.1f;
1847
1848        // if some strange render time spike happened in this frame => don't count
1849        if (elapsedTime < 500) frameTime = elapsedTime * expFactor + (1.0f - expFactor) * elapsedTime;
1850       
1851        static float rTime = 1000.0f;
1852
1853        if (showAlgorithmTime)
1854        {
1855                if (algTime < 500) renderTime = algTime * expFactor + (1.0f - expFactor) * renderTime;
1856        }
1857
1858        accumulatedTime += elapsedTime;
1859
1860        if (accumulatedTime > 500) // update every fraction of a second
1861        {       
1862                accumulatedTime = 0;
1863
1864                if (frameTime) fps = 1e3f / (float)frameTime;
1865
1866                rTime = renderTime;
1867                renderedObjects = traverser->GetStats().mNumRenderedGeometry;
1868                renderedNodes = traverser->GetStats().mNumRenderedNodes;
1869                renderedTriangles = traverser->GetStats().mNumRenderedTriangles;
1870
1871                traversedNodes = traverser->GetStats().mNumTraversedNodes;
1872                frustumCulledNodes = traverser->GetStats().mNumFrustumCulledNodes;
1873                queryCulledNodes = traverser->GetStats().mNumQueryCulledNodes;
1874                issuedQueries = traverser->GetStats().mNumIssuedQueries;
1875                stateChanges = traverser->GetStats().mNumStateChanges;
1876                numBatches = traverser->GetStats().mNumBatches;
1877        }
1878
1879
1880        Begin2D();
1881
1882        glEnable(GL_BLEND);
1883        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1884
1885        if (showHelp)
1886        {       
1887                DrawHelpMessage();
1888        }
1889        else
1890        {
1891                if (showOptions)
1892                {
1893                        glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
1894                        glRecti(5, winHeight - 95, winWidth * 2 / 3 - 5, winHeight - 5);
1895                }
1896
1897                if (showStatistics)
1898                {
1899                        glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
1900                        glRecti(5, winHeight - 165, winWidth * 2 / 3 - 5, winHeight - 100);
1901                }
1902
1903                glEnable(GL_TEXTURE_2D);
1904
1905                myfont.Begin();
1906
1907                if (showOptions)
1908                {
1909                        glColor3f(0.0f, 1.0f, 0.0f);
1910
1911                        int i = 0;
1912
1913                        static char *renderTypeStr[] = {"fixed function", "fixed function + depth pass", "deferred shading"};
1914       
1915                        sprintf(msg[i ++], "multiqueries: %d, tight bounds: %d, render queue: %d",
1916                                                        useMultiQueries, useTightBounds, useRenderQueue);
1917
1918                        sprintf(msg[i ++], "render technique: %s, SSAO: %d", renderTypeStr[renderType], useSsao);
1919
1920                        sprintf(msg[i ++], "triangles per virtual leaf: %5d", trianglesPerVirtualLeaf);
1921
1922                        sprintf(msg[i ++], "assumed visible frames: %4d, max batch size: %4d",
1923                                assumedVisibleFrames, maxBatchSize);
1924
1925                        for (int j = 0; j < 4; ++ j)
1926                                myfont.DrawString(msg[j], 10.0f, winHeight - 5 - j * 20);
1927                }
1928
1929                if (showStatistics)
1930                {
1931                        glColor3f(1.0f, 1.0f, 0.0f);
1932
1933                        string str;
1934                        string str2;
1935
1936                        int len = 10;
1937                        CalcDecimalPoint(str, renderedTriangles, len);
1938                        CalcDecimalPoint(str2, bvh->GetBvhStats().mTriangles, len);
1939
1940                        int i = 4;
1941
1942                        sprintf(msg[i ++], "rendered: %6d of %6d nodes, %s of %s triangles",
1943                                renderedNodes, bvh->GetNumVirtualNodes(), str.c_str(), str2.c_str());
1944
1945                        sprintf(msg[i ++], "traversed: %5d, frustum culled: %5d, query culled: %5d",
1946                                traversedNodes, frustumCulledNodes, queryCulledNodes);
1947
1948                        sprintf(msg[i ++], "issued queries: %5d, state changes: %5d, render batches: %5d",
1949                                issuedQueries, stateChanges, numBatches);
1950
1951                        for (int j = 4; j < 7; ++ j)
1952                                myfont.DrawString(msg[j], 10.0f, winHeight - (j + 1) * 20);
1953                }
1954
1955                glColor3f(1.0f, 1.0f, 1.0f);
1956                static char *alg_str[] = {"Frustum Cull", "Stop and Wait", "CHC", "CHC ++"};
1957               
1958                if (!showAlgorithmTime)
1959                {
1960                        sprintf(msg[7], "%s:  %6.1f fps", alg_str[renderMode], fps);
1961                }
1962                else
1963                {
1964                        sprintf(msg[7], "%s:  %6.1f ms", alg_str[renderMode], rTime);
1965                }
1966
1967                myfont.DrawString(msg[7], 1.3f, 690.0f, 760.0f);//, top_color, bottom_color);
1968               
1969                //sprintf(msg[8], "algorithm time: %6.1f ms", rTime);
1970                //myfont.DrawString(msg[8], 720.0f, 730.0f);           
1971        }
1972
1973        glDisable(GL_BLEND);
1974        glDisable(GL_TEXTURE_2D);
1975
1976        End2D();
1977}       
1978
1979
1980void RenderSky()
1981{
1982        SceneEntityContainer::const_iterator sit, sit_end = skyGeometry.end();
1983
1984        for (sit = skyGeometry.begin(); sit != sit_end; ++ sit)
1985                (*sit)->Render(&state);
1986}
1987
1988
1989void RenderVisibleObjects()
1990{
1991        state.SetRenderType(RenderState::FIXED);
1992        state.Reset();
1993
1994        glEnable(GL_LIGHTING);
1995        glDepthFunc(GL_LEQUAL);
1996
1997        //cout << "visible: " << (int)traverser->GetVisibleObjects().size() << endl;
1998
1999        SceneEntityContainer::const_iterator sit,
2000                sit_end = traverser->GetVisibleObjects().end();
2001
2002        for (sit = traverser->GetVisibleObjects().begin(); sit != sit_end; ++ sit)
2003                renderQueue->Enqueue(*sit);
2004               
2005        renderQueue->Apply();
2006
2007        glDepthFunc(GL_LESS);
2008}
2009
2010
2011void PlaceViewer(const Vector3 &oldPos)
2012{
2013        Vector3 playerPos = camera->GetPosition();
2014
2015        bool validIntersect = sceneQuery->CalcIntersection(playerPos);
2016
2017        if (validIntersect &&
2018                (( playerPos.z - oldPos.z) < bvh->GetBox().Size(2) * 1e-1f))
2019        {
2020                camera->SetPosition(playerPos);
2021        }
2022}
2023
2024
2025void DisplayRenderTexture3()
2026{
2027        glEnable(GL_TEXTURE_2D);
2028
2029        if (isFirstTexture)
2030                glBindTexture(GL_TEXTURE_2D, colorsTex1);
2031        else
2032                glBindTexture(GL_TEXTURE_2D, colorsTex2);
2033
2034        glDisable(GL_LIGHTING);
2035       
2036        glMatrixMode(GL_PROJECTION);
2037        glPushMatrix();
2038        glLoadIdentity();
2039
2040        glMatrixMode(GL_MODELVIEW);
2041        glPushMatrix();
2042        glLoadIdentity();
2043
2044        const float offs = 0.5f;
2045        glOrtho(-offs, offs, -offs, offs, 0, 1);
2046       
2047        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2048
2049        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
2050        glBegin(GL_QUADS);
2051
2052        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
2053        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
2054        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
2055        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
2056
2057        glEnd();
2058
2059        glEnable(GL_LIGHTING);
2060        glDisable(GL_TEXTURE_2D);
2061       
2062        glMatrixMode(GL_PROJECTION);
2063        glPopMatrix();
2064
2065        glMatrixMode(GL_MODELVIEW);
2066        glPopMatrix();
2067
2068        PrintGLerror("displaytexture3");
2069}
2070
2071
2072void DisplayRenderTexture()
2073{
2074        GLuint oldTex;
2075
2076        if (isFirstTexture)
2077        {
2078                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo1);
2079                oldTex = colorsTex2;
2080        }
2081        else
2082        {
2083                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
2084                oldTex = colorsTex1;
2085        }
2086
2087        glPushAttrib(GL_VIEWPORT_BIT);
2088        glViewport(0, 0, texWidth, texHeight);
2089
2090        glDrawBuffers(1, mrt);
2091
2092        glDisable(GL_ALPHA_TEST);
2093        glDisable(GL_TEXTURE_2D);
2094        glDisable(GL_LIGHTING);
2095       
2096        glMatrixMode(GL_PROJECTION);
2097        glPushMatrix();
2098        glLoadIdentity();
2099
2100        glMatrixMode(GL_MODELVIEW);
2101        glPushMatrix();
2102        glLoadIdentity();
2103
2104        const float offs = 0.5f;
2105       
2106        glOrtho(-offs, offs, -offs, offs, 0, 1);
2107       
2108        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2109
2110        cgGLEnableProfile(RenderState::sCgFragmentProfile);
2111
2112        if (useSsao)
2113        {
2114                cgGLBindProgram(sCgSsaoProgram);
2115               
2116                cgGLSetTextureParameter(sPositionsTexParamSsao, positionsTex);
2117                cgGLEnableTextureParameter(sPositionsTexParamSsao);
2118
2119                cgGLSetTextureParameter(sColorsTexParamSsao, colorsTex);
2120                cgGLEnableTextureParameter(sColorsTexParamSsao);
2121
2122                cgGLSetTextureParameter(sNormalsTexParamSsao, normalsTex);
2123                cgGLEnableTextureParameter(sNormalsTexParamSsao);
2124
2125                cgGLSetTextureParameter(sNoiseTexParamSsao, noiseTex);
2126                cgGLEnableTextureParameter(sNoiseTexParamSsao);
2127
2128                cgGLSetTextureParameter(sOldTexParamSsao, oldTex);
2129                cgGLEnableTextureParameter(sOldTexParamSsao);
2130
2131                cgGLSetParameter1f(sNoiseMultiplierParam, RandomValue(3.0f, 17.0f));
2132                cgGLSetParameter1f(sExpFactorParamSsao, expFactor);
2133
2134                GenerateSamples(); cgGLSetParameterArray2f(sSamplesParamSsao, 0, NUM_SAMPLES, (const float *)samples);
2135        }
2136        else
2137        {
2138                cgGLBindProgram(sCgDeferredProgram);
2139
2140                cgGLSetTextureParameter(sPositionsTexParam, positionsTex);
2141                cgGLEnableTextureParameter(sPositionsTexParam);
2142
2143                cgGLSetTextureParameter(sColorsTexParam, colorsTex);
2144                cgGLEnableTextureParameter(sColorsTexParam);
2145
2146                cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
2147                cgGLEnableTextureParameter(sNormalsTexParam);
2148        }
2149
2150        Vector3 tl, tr, bl, br;
2151        ComputeViewVectors(tl, tr, bl, br);
2152
2153        glColor3f(1.0f, 1.0f, 1.0f);
2154
2155        glBegin(GL_QUADS);
2156
2157        // note: slightly larger texture hides ambient occlusion error on border but costs resolution
2158        //float offs2 = 0.55f;
2159        float offs2 = 0.5f;
2160
2161        glColor3f(bl.x, bl.y, bl.z); glTexCoord2f(0, 0); glVertex3f(-offs2, -offs2, -0.5f);
2162        glColor3f(br.x, br.y, br.z); glTexCoord2f(1, 0); glVertex3f( offs2, -offs2, -0.5f);
2163        glColor3f(tr.x, tr.y, tr.z); glTexCoord2f(1, 1); glVertex3f( offs2,  offs2, -0.5f);
2164        glColor3f(tl.x, tl.y, tl.z); glTexCoord2f(0, 1); glVertex3f(-offs2,  offs2, -0.5f);
2165
2166        glEnd();
2167
2168       
2169        if (useSsao)
2170        {
2171                cgGLDisableTextureParameter(sColorsTexParamSsao);
2172                cgGLDisableTextureParameter(sPositionsTexParamSsao);
2173                cgGLDisableTextureParameter(sNormalsTexParamSsao);
2174                cgGLDisableTextureParameter(sNoiseTexParamSsao);
2175                cgGLDisableTextureParameter(sOldTexParamSsao);
2176        }
2177        else
2178        {
2179                cgGLDisableTextureParameter(sColorsTexParam);
2180                cgGLDisableTextureParameter(sPositionsTexParam);
2181                cgGLDisableTextureParameter(sNormalsTexParam);
2182        }
2183
2184        cgGLDisableProfile(RenderState::sCgFragmentProfile);
2185       
2186        glEnable(GL_LIGHTING);
2187        glDisable(GL_TEXTURE_2D);
2188       
2189        glMatrixMode(GL_PROJECTION);
2190        glPopMatrix();
2191
2192        glMatrixMode(GL_MODELVIEW);
2193        glPopMatrix();
2194
2195        glPopAttrib();
2196
2197        PrintGLerror("displaytexture");
2198
2199        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
2200
2201        DisplayRenderTexture3();
2202}
2203
2204#if 0
2205// kustls magic sample positions
2206void GenerateSamples()
2207{
2208        static const float mysamples[] =
2209        {
2210                -0.326212f, -0.405805f,
2211                -0.840144f, -0.07358f,
2212                -0.695914f, 0.457137f,
2213                -0.203345f, 0.620716,
2214                0.96234f, -0.194983f,
2215                0.473434f, -0.480026f,
2216                0.519456, 0.767022f,
2217                0.185461f, -0.893124f,
2218                0.507431f, 0.064425f,
2219                0.89642f, 0.412458f,
2220                -0.32194f, -0.932615f,
2221                -0.791559f, -0.597705f,
2222                0.326212f, 0.405805f,
2223                0.840144f, 0.07358f,
2224                0.695914f, -0.457137f,
2225                0.203345f, -0.620716,
2226                -0.96234f, 0.194983f,
2227                -0.473434f, 0.480026f,
2228                -0.519456, -0.767022f,
2229                -0.185461f, 0.893124f,
2230                -0.507431f, -0.064425f,
2231                -0.89642f, -0.412458f,
2232                0.32194f, 0.932615f,
2233                0.791559f, 0.597705f
2234        };
2235
2236        for (int i = 0; i < NUM_SAMPLES; ++ i)
2237        {
2238                samples[i] = mysamples[i];
2239        }
2240}
2241
2242#else
2243
2244
2245void GenerateSamples()
2246{
2247        static HaltonSequence halton;
2248
2249        float r[2];
2250
2251        // generates poisson distribution on disc
2252        float minDist = 2.0f / sqrt((float)NUM_SAMPLES);
2253
2254        //cout << "minDist before= " << minDist << endl;
2255
2256        for (int i = 0; i < NUM_SAMPLES * 2; i += 2)
2257        {
2258                int tries = 0, totalTries = 0;
2259
2260                // repeat until valid sample was found
2261                while (1)
2262                {
2263                        ++ tries;
2264                        ++ totalTries;
2265
2266                        halton.GetNext(2, r);
2267
2268                        //const float rx = RandomValue(-1, 1);
2269                        //const float ry = RandomValue(-1, 1);
2270
2271                        const float rx = r[0] * 2.0f - 1.0f;
2272                        const float ry = r[1] * 2.0f - 1.0f;
2273
2274                        // check if in disk, else exit early
2275                        if (rx * rx + ry * ry > 1)
2276                                continue;
2277
2278                        bool sampleValid = true;
2279
2280                        // check poisson property
2281                        for (int j = 0; ((j < i) && sampleValid); j += 2)
2282                        {
2283                                const float dist =
2284                                        sqrt((samples[j] - rx) * (samples[j] - rx) +
2285                                             (samples[j + 1] - ry) * (samples[j + 1] - ry));
2286                       
2287                                if (dist < minDist)
2288                                        sampleValid = false;
2289                        }
2290
2291                        if (sampleValid)
2292                        {
2293                                samples[i] = rx;
2294                                samples[i + 1]= ry;
2295                                break;
2296                        }
2297
2298                        if (tries > 2000)
2299                        {
2300                                minDist *= 0.9f;
2301                                tries = 0;
2302                        }
2303                }
2304                //cout << "sample: " << samples[i] << " " << i / 2 << " " << samples[i + 1] << " r: " << sqrt(samples[i] * samples[i]  + samples[i + 1] * samples[i + 1]) << " tries: " << totalTries << endl;
2305        }
2306
2307        //cout << "minDist after= " << minDist << endl;
2308}
2309
2310
2311#endif
2312
2313
2314void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
2315{
2316        float myfov = fov * M_PI / 180.0f;
2317
2318        const float w_far = 2.0f * tan(myfov / 2.0f);
2319        const float aspect = texWidth / texHeight;
2320
2321        const float h_far = w_far / aspect;
2322
2323        float t1 = h_far * 0.5f;
2324        float t2 = w_far * 0.5f;
2325
2326#if 0
2327        bl = Normalize(-Vector3(-t1, -t2, 1.0f));
2328        br = Normalize(-Vector3( t1, -t2, 1.0f));
2329        tl = Normalize(-Vector3(-t1,  t2, 1.0f));
2330        tr = Normalize(-Vector3( t1,  t2, 1.0f));
2331#else
2332        bl = -Normalize(camera->GetDirection());
2333        br = -Normalize(camera->GetDirection());
2334        tl = -Normalize(camera->GetDirection());
2335        tr = -Normalize(camera->GetDirection());
2336#endif
2337        // normalize to 0 .. 1
2338        bl = bl * 0.5f + 0.5f;
2339        br = br * 0.5f + 0.5f;
2340        tl = tl * 0.5f + 0.5f;
2341        tr = tr * 0.5f + 0.5f;
2342}
2343
2344
2345void CreateNoiseTex2D()
2346{
2347        randomNormals = new GLubyte[texWidth * texHeight * 3];
2348
2349        for (int i = 0; i < texWidth * texHeight * 3; i += 3)
2350        {
2351                // create random samples over sphere
2352                const float rx = RandomValue(0, 1);
2353                const float theta = 2.0f * acos(sqrt(1.0f - rx));
2354
2355                randomNormals[i + 0] = (GLubyte)((cos(theta) * 0.5f + 0.5f) * 255.0f);
2356                randomNormals[i + 1] = (GLubyte)((sin(theta) * 0.5f + 0.5f) * 255.0f);
2357                randomNormals[i + 2] = 0;
2358        }
2359
2360        glEnable(GL_TEXTURE_2D);
2361        glGenTextures(1, &noiseTex);
2362        glBindTexture(GL_TEXTURE_2D, noiseTex);
2363               
2364        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2365        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2366        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2367        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2368
2369        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, randomNormals);
2370        //gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, texWidth, texHeight, GL_RGB, GL_UNSIGNED_BYTE, randomNormals);
2371
2372        glBindTexture(GL_TEXTURE_2D, 0);
2373        glDisable(GL_TEXTURE_2D);
2374
2375        cout << "created noise texture" << endl;
2376        PrintGLerror("noisetexture");
2377}
Note: See TracBrowser for help on using the repository browser.