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

Revision 2840, 57.2 KB checked in by mattausch, 16 years ago (diff)
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.5f);
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        // actually render the scene geometry using one of the specified algorithms
1198        traverser->RenderScene();
1199
1200
1201
1202        /////////
1203        //-- do the rest of the rendering
1204
1205        glEnableClientState(GL_VERTEX_ARRAY);
1206        glEnableClientState(GL_NORMAL_ARRAY);
1207
1208
1209        // reset depth pass and render visible objects
1210        if (renderType == RenderState::DEPTH_PASS)
1211        {
1212                glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1213                RenderVisibleObjects();
1214        }
1215       
1216
1217        ///////////////
1218        //-- render sky
1219
1220        RenderSky();
1221
1222        state.Reset();
1223
1224        glDisableClientState(GL_VERTEX_ARRAY);
1225        glDisableClientState(GL_NORMAL_ARRAY);
1226
1227        if (renderType == RenderState::DEFERRED)
1228        {
1229                glPopAttrib();
1230                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1231
1232                cgGLDisableProfile(RenderState::sCgVertexProfile);
1233                cgGLDisableProfile(RenderState::sCgFragmentProfile);
1234
1235                glDrawBuffers(1, mrt);
1236
1237                DisplayRenderTexture();
1238        }
1239
1240       
1241        ///////////
1242
1243        state.SetRenderType(RenderState::FIXED);
1244
1245        if (showAlgorithmTime)
1246        {
1247                glFinish();
1248
1249                algTime = algTimer.Elapsedms();
1250                perfGraph->AddData(algTime);
1251
1252                perfGraph->Draw();
1253        }
1254        else
1255        {
1256                if (visMode) DisplayVisualization();
1257        }
1258
1259        DisplayStats();
1260
1261        isFirstTexture = !isFirstTexture;
1262
1263        glutSwapBuffers();
1264}
1265
1266
1267#pragma warning( disable : 4100 )
1268void KeyBoard(unsigned char c, int x, int y)
1269{
1270        switch(c)
1271        {
1272        case 27:
1273                CleanUp();
1274                exit(0);
1275                break;
1276        case 32: //space
1277                renderMode = (renderMode + 1) % RenderTraverser::NUM_TRAVERSAL_TYPES;
1278                ResetTraverser();
1279                break;
1280        case 'h':
1281        case 'H':
1282                showHelp = !showHelp;
1283                break;
1284        case '+':
1285                maxBatchSize += 10;
1286                traverser->SetMaxBatchSize(maxBatchSize);
1287                break;
1288        case '-':
1289                maxBatchSize -= 10;
1290                if (maxBatchSize < 0) maxBatchSize = 1;
1291                traverser->SetMaxBatchSize(maxBatchSize);               
1292                break;
1293        case 'M':
1294        case 'm':
1295                useMultiQueries = !useMultiQueries;
1296                traverser->SetUseMultiQueries(useMultiQueries);
1297                break;
1298        case '1':
1299                descendKeyPressed = true;
1300                break;
1301        case '2':
1302                ascendKeyPressed = true;
1303                break;
1304        case '3':
1305                if (trianglesPerVirtualLeaf >= 100)
1306                        trianglesPerVirtualLeaf -= 100;
1307                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1308                break;
1309        case '4':
1310                trianglesPerVirtualLeaf += 100;
1311                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1312                break;
1313        case '5':
1314                assumedVisibleFrames -= 1;
1315                if (assumedVisibleFrames < 1) assumedVisibleFrames = 1;
1316                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
1317                break;
1318        case '6':
1319                assumedVisibleFrames += 1;
1320                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);               
1321                break;
1322        case '7':
1323                expFactor *= 0.5f;
1324                break;
1325        case '8':
1326                expFactor *= 2.0f;
1327                if (expFactor > 1.0f) expFactor = 1.0f;
1328                break;
1329        case 'o':
1330        case 'O':
1331                useOptimization = !useOptimization;
1332                traverser->SetUseOptimization(useOptimization);
1333                break;
1334        case 'a':
1335        case 'A':
1336                        leftKeyPressed = true;
1337                break;
1338        case 'd':
1339        case 'D':
1340                        rightKeyPressed = true;
1341                break;
1342        case 'w':
1343        case 'W':
1344                        upKeyPressed = true;
1345                break;
1346        case 's':
1347        case 'S':
1348                        downKeyPressed = true;
1349                break;
1350        case 'r':
1351        case 'R':
1352                {
1353                        useRenderQueue = !useRenderQueue;
1354                        traverser->SetUseRenderQueue(useRenderQueue);
1355                }
1356                break;
1357        case 'b':
1358        case 'B':
1359                {
1360                        useTightBounds = !useTightBounds;
1361                        traverser->SetUseTightBounds(useTightBounds);
1362                }
1363                break;
1364        default:
1365                return;
1366        }
1367
1368        glutPostRedisplay();
1369}
1370
1371
1372void SpecialKeyUp(int c, int x, int y)
1373{
1374        switch (c)
1375        {
1376        case GLUT_KEY_LEFT:
1377                leftKeyPressed = false;
1378                break;
1379        case GLUT_KEY_RIGHT:
1380                rightKeyPressed = false;
1381                break;
1382        case GLUT_KEY_UP:
1383                upKeyPressed = false;
1384                break;
1385        case GLUT_KEY_DOWN:
1386                downKeyPressed = false;
1387                break;
1388        default:
1389                return;
1390        }
1391        //glutPostRedisplay();
1392}
1393
1394
1395void KeyUp(unsigned char c, int x, int y)
1396{
1397        switch (c)
1398        {
1399        case 'A':
1400        case 'a':
1401                leftKeyPressed = false;
1402                break;
1403        case 'D':
1404        case 'd':
1405                rightKeyPressed = false;
1406                break;
1407        case 'W':
1408        case 'w':
1409                upKeyPressed = false;
1410                break;
1411        case 'S':
1412        case 's':
1413                downKeyPressed = false;
1414                break;
1415        case '1':
1416                descendKeyPressed = false;
1417                break;
1418        case '2':
1419                ascendKeyPressed = false;
1420                break;
1421       
1422        default:
1423                return;
1424        }
1425        //glutPostRedisplay();
1426}
1427
1428
1429void Special(int c, int x, int y)
1430{
1431        switch(c)
1432        {
1433        case GLUT_KEY_F1:
1434                showHelp = !showHelp;
1435                break;
1436        case GLUT_KEY_F2:
1437                visMode = !visMode;
1438                break;
1439        case GLUT_KEY_F3:
1440                showBoundingVolumes = !showBoundingVolumes;
1441                traverser->SetShowBounds(showBoundingVolumes);
1442                break;
1443        case GLUT_KEY_F4:
1444                showOptions = !showOptions;
1445                break;
1446        case GLUT_KEY_F5:
1447                showStatistics = !showStatistics;
1448                break;
1449        case GLUT_KEY_F6:
1450                flyMode = !flyMode;
1451                break;
1452        case GLUT_KEY_F7:
1453
1454                renderType = (renderType + 1) % 3;
1455                traverser->SetUseDepthPass(renderType == RenderState::DEPTH_PASS);
1456               
1457                break;
1458        case GLUT_KEY_F8:
1459                useSsao = !useSsao;
1460                break;
1461        case GLUT_KEY_F9:
1462                showAlgorithmTime = !showAlgorithmTime;
1463                break;
1464
1465        case GLUT_KEY_LEFT:
1466                {
1467                        leftKeyPressed = true;
1468                        camera->Pitch(KeyRotationAngle());
1469                }
1470                break;
1471        case GLUT_KEY_RIGHT:
1472                {
1473                        rightKeyPressed = true;
1474                        camera->Pitch(-KeyRotationAngle());
1475                }
1476                break;
1477        case GLUT_KEY_UP:
1478                {
1479                        upKeyPressed = true;
1480                        KeyHorizontalMotion(KeyShift());
1481                }
1482                break;
1483        case GLUT_KEY_DOWN:
1484                {
1485                        downKeyPressed = true;
1486                        KeyHorizontalMotion(-KeyShift());
1487                }
1488                break;
1489        default:
1490                return;
1491
1492        }
1493
1494        glutPostRedisplay();
1495}
1496
1497#pragma warning( default : 4100 )
1498
1499
1500void Reshape(int w, int h)
1501{
1502        winAspectRatio = 1.0f;
1503
1504        glViewport(0, 0, w, h);
1505       
1506        winWidth = w;
1507        winHeight = h;
1508
1509        if (w) winAspectRatio = (float) w / (float) h;
1510
1511        glMatrixMode(GL_PROJECTION);
1512        glLoadIdentity();
1513
1514        gluPerspective(fov, winAspectRatio, nearDist, myfar);
1515
1516        glMatrixMode(GL_MODELVIEW);
1517
1518        glutPostRedisplay();
1519}
1520
1521
1522void Mouse(int button, int state, int x, int y)
1523{
1524        if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
1525        {
1526                xEyeBegin = x;
1527                yMotionBegin = y;
1528
1529                glutMotionFunc(LeftMotion);
1530        }
1531        else if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN))
1532        {
1533                xEyeBegin = x;
1534                yEyeBegin = y;
1535                yMotionBegin = y;
1536
1537                glutMotionFunc(RightMotion);
1538        }
1539        else if ((button == GLUT_MIDDLE_BUTTON) && (state == GLUT_DOWN))
1540        {
1541                horizontalMotionBegin = x;
1542                verticalMotionBegin = y;
1543                glutMotionFunc(MiddleMotion);
1544        }
1545
1546        glutPostRedisplay();
1547}
1548
1549
1550/**     rotation for left/right mouse drag
1551        motion for up/down mouse drag
1552*/
1553void LeftMotion(int x, int y)
1554{
1555        Vector3 viewDir = camera->GetDirection();
1556        Vector3 pos = camera->GetPosition();
1557
1558        // don't move in the vertical direction
1559        Vector3 horView(viewDir[0], viewDir[1], 0);
1560       
1561        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
1562
1563        camera->Pitch(eyeXAngle);
1564
1565        pos += horView * (yMotionBegin - y) * 0.2f;
1566       
1567        camera->SetPosition(pos);
1568       
1569        xEyeBegin = x;
1570        yMotionBegin = y;
1571
1572        glutPostRedisplay();
1573}
1574
1575
1576/**     rotation for left / right mouse drag
1577        motion for up / down mouse drag
1578*/
1579void RightMotion(int x, int y)
1580{
1581        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
1582        float eyeYAngle = -0.2f *  M_PI * (yEyeBegin - y) / 180.0;
1583
1584        camera->Yaw(eyeYAngle);
1585        camera->Pitch(eyeXAngle);
1586
1587        xEyeBegin = x;
1588        yEyeBegin = y;
1589
1590        glutPostRedisplay();
1591}
1592
1593
1594// strafe
1595void MiddleMotion(int x, int y)
1596{
1597        Vector3 viewDir = camera->GetDirection();
1598        Vector3 pos = camera->GetPosition();
1599
1600        // the 90 degree rotated view vector
1601        // y zero so we don't move in the vertical
1602        Vector3 rVec(viewDir[0], viewDir[1], 0);
1603       
1604        Matrix4x4 rot = RotationZMatrix(M_PI * 0.5f);
1605        rVec = rot * rVec;
1606       
1607        pos -= rVec * (x - horizontalMotionBegin) * 0.1f;
1608        pos[2] += (verticalMotionBegin - y) * 0.1f;
1609
1610        camera->SetPosition(pos);
1611
1612        horizontalMotionBegin = x;
1613        verticalMotionBegin = y;
1614
1615        glutPostRedisplay();
1616}
1617
1618
1619void InitExtensions(void)
1620{
1621        GLenum err = glewInit();
1622
1623        if (GLEW_OK != err)
1624        {
1625                // problem: glewInit failed, something is seriously wrong
1626                fprintf(stderr,"Error: %s\n", glewGetErrorString(err));
1627                exit(1);
1628        }
1629        if  (!GLEW_ARB_occlusion_query)
1630        {
1631                printf("I require the GL_ARB_occlusion_query to work.\n");
1632                exit(1);
1633        }
1634}
1635
1636
1637void Begin2D()
1638{
1639        glDisable(GL_LIGHTING);
1640        glDisable(GL_DEPTH_TEST);
1641
1642        glMatrixMode(GL_PROJECTION);
1643        glPushMatrix();
1644        glLoadIdentity();
1645
1646        gluOrtho2D(0, winWidth, 0, winHeight);
1647
1648        glMatrixMode(GL_MODELVIEW);
1649        glPushMatrix();
1650        glLoadIdentity();
1651}
1652
1653
1654void End2D()
1655{
1656        glMatrixMode(GL_PROJECTION);
1657        glPopMatrix();
1658
1659        glMatrixMode(GL_MODELVIEW);
1660        glPopMatrix();
1661
1662        glEnable(GL_LIGHTING);
1663        glEnable(GL_DEPTH_TEST);
1664}
1665
1666
1667// displays the visualisation of culling algorithm
1668void DisplayVisualization()
1669{
1670        visualization->SetFrameId(traverser->GetCurrentFrameId());
1671       
1672        Begin2D();
1673        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1674        glEnable(GL_BLEND);
1675        glColor4f(0.0f ,0.0f, 0.0f, 0.5f);
1676
1677        glRecti(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth, winHeight);
1678        glDisable(GL_BLEND);
1679        End2D();
1680       
1681       
1682        AxisAlignedBox3 box = bvh->GetBox();
1683
1684        // hack: set far plane for viz
1685        camera->SetFar(0.35f * Magnitude(box.Diagonal()));
1686
1687        const float offs = box.Size().x * 0.3f;
1688       
1689        //Vector3 vizpos = Vector3(box.Min().x, box.Min().y + box.Size().y * 0.5f, box.Min().z + box.Size().z * 50);
1690        Vector3 vizpos = Vector3(box.Min().x, box.Min().y  - box.Size().y * 0.35f, box.Min().z + box.Size().z * 50);
1691       
1692        visCamera->SetPosition(vizpos);
1693        visCamera->ResetPitchAndYaw();
1694        //visCamera->Pitch(M_PI);
1695
1696        glPushAttrib(GL_VIEWPORT_BIT);
1697        glViewport(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth / 3, winHeight / 3);
1698
1699        glMatrixMode(GL_PROJECTION);
1700        glPushMatrix();
1701
1702        glLoadIdentity();
1703       
1704        glOrtho(-offs, offs, -offs, offs, 0.0f, box.Size().z * 100.0f);
1705
1706        glMatrixMode(GL_MODELVIEW);
1707        glPushMatrix();
1708
1709        visCamera->SetupCameraView();
1710
1711        //Matrix4x4 rotX = RotationXMatrix(camera->GetYaw());
1712        //glMultMatrixf((float *)rotX.x);
1713        Matrix4x4 rotZ = RotationZMatrix(-camera->GetPitch());
1714        glMultMatrixf((float *)rotZ.x);
1715
1716        Vector3 pos = camera->GetPosition();
1717        glTranslatef(-pos.x, -pos.y, -pos.z);
1718
1719
1720        GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
1721        glLightfv(GL_LIGHT0, GL_POSITION, position);
1722
1723        GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
1724        glLightfv(GL_LIGHT1, GL_POSITION, position1);
1725
1726        glClear(GL_DEPTH_BUFFER_BIT);
1727
1728
1729        ////////////
1730        //-- visualization of the occlusion culling
1731
1732        visualization->Render();
1733       
1734       
1735        // reset previous settings
1736        glPopAttrib();
1737
1738        glMatrixMode(GL_PROJECTION);
1739        glPopMatrix();
1740        glMatrixMode(GL_MODELVIEW);
1741        glPopMatrix();
1742}
1743
1744
1745// cleanup routine after the main loop
1746void CleanUp()
1747{
1748        DEL_PTR(traverser);
1749        DEL_PTR(sceneQuery);
1750        DEL_PTR(bvh);
1751        DEL_PTR(visualization);
1752        DEL_PTR(camera);
1753        DEL_PTR(loader);
1754        DEL_PTR(renderQueue);
1755        DEL_PTR(perfGraph);
1756
1757        if (sCgMrtVertexProgram)
1758                cgDestroyProgram(sCgMrtVertexProgram);
1759        if (RenderState::sCgMrtFragmentProgram)
1760                cgDestroyProgram(RenderState::sCgMrtFragmentProgram);
1761        if (RenderState::sCgMrtFragmentTexProgram)
1762                cgDestroyProgram(RenderState::sCgMrtFragmentTexProgram);
1763        if (sCgSsaoProgram)
1764                cgDestroyProgram(sCgSsaoProgram);
1765        if (sCgDeferredProgram)
1766                cgDestroyProgram(sCgDeferredProgram);
1767        if (sCgContext)
1768                cgDestroyContext(sCgContext);
1769
1770        glDeleteFramebuffersEXT(1, &fbo);
1771        glDeleteRenderbuffersEXT(1, &depthBuffer);
1772        glDeleteRenderbuffersEXT(1, &colorsBuffer);
1773        glDeleteRenderbuffersEXT(1, &normalsBuffer);
1774        glDeleteRenderbuffersEXT(1, &positionsBuffer);
1775
1776        glDeleteTextures(1, &colorsTex);
1777        glDeleteTextures(1, &normalsTex);
1778        glDeleteTextures(1, &positionsTex);
1779        glDeleteTextures(1, &noiseTex);
1780        glDeleteTextures(1, &fontTex);
1781}
1782
1783
1784// this function inserts a dezimal point after each 1000
1785void CalcDecimalPoint(string &str, int d, int len)
1786{
1787        static vector<int> numbers;
1788        numbers.clear();
1789
1790        static string shortStr;
1791        shortStr.clear();
1792
1793        static char hstr[100];
1794
1795        while (d != 0)
1796        {
1797                numbers.push_back(d % 1000);
1798                d /= 1000;
1799        }
1800
1801        // first element without leading zeros
1802        if (numbers.size() > 0)
1803        {
1804                sprintf(hstr, "%d", numbers.back());
1805                shortStr.append(hstr);
1806        }
1807       
1808        for (int i = (int)numbers.size() - 2; i >= 0; i--)
1809        {
1810                sprintf(hstr, ",%03d", numbers[i]);
1811                shortStr.append(hstr);
1812        }
1813
1814        int dif = len - (int)shortStr.size();
1815
1816        for (int i = 0; i < dif; ++ i)
1817        {
1818                str += " ";
1819        }
1820
1821        str.append(shortStr);
1822}
1823
1824
1825void DisplayStats()
1826{
1827        static char msg[9][300];
1828
1829        static double frameTime = elapsedTime;
1830        static double renderTime = algTime;
1831
1832        const float expFactor = 0.1f;
1833
1834        // if some strange render time spike happened in this frame => don't count
1835        if (elapsedTime < 500) frameTime = elapsedTime * expFactor + (1.0f - expFactor) * elapsedTime;
1836       
1837        static float rTime = 1000.0f;
1838
1839        if (showAlgorithmTime)
1840        {
1841                if (algTime < 500) renderTime = algTime * expFactor + (1.0f - expFactor) * renderTime;
1842        }
1843
1844        accumulatedTime += elapsedTime;
1845
1846        if (accumulatedTime > 500) // update every fraction of a second
1847        {       
1848                accumulatedTime = 0;
1849
1850                if (frameTime) fps = 1e3f / (float)frameTime;
1851
1852                rTime = renderTime;
1853                renderedObjects = traverser->GetStats().mNumRenderedGeometry;
1854                renderedNodes = traverser->GetStats().mNumRenderedNodes;
1855                renderedTriangles = traverser->GetStats().mNumRenderedTriangles;
1856
1857                traversedNodes = traverser->GetStats().mNumTraversedNodes;
1858                frustumCulledNodes = traverser->GetStats().mNumFrustumCulledNodes;
1859                queryCulledNodes = traverser->GetStats().mNumQueryCulledNodes;
1860                issuedQueries = traverser->GetStats().mNumIssuedQueries;
1861                stateChanges = traverser->GetStats().mNumStateChanges;
1862                numBatches = traverser->GetStats().mNumBatches;
1863        }
1864
1865
1866        Begin2D();
1867
1868        glEnable(GL_BLEND);
1869        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1870
1871        if (showHelp)
1872        {       
1873                DrawHelpMessage();
1874        }
1875        else
1876        {
1877                if (showOptions)
1878                {
1879                        glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
1880                        glRecti(5, winHeight - 95, winWidth * 2 / 3 - 5, winHeight - 5);
1881                }
1882
1883                if (showStatistics)
1884                {
1885                        glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
1886                        glRecti(5, winHeight - 165, winWidth * 2 / 3 - 5, winHeight - 100);
1887                }
1888
1889                glEnable(GL_TEXTURE_2D);
1890
1891                myfont.Begin();
1892
1893                if (showOptions)
1894                {
1895                        glColor3f(0.0f, 1.0f, 0.0f);
1896
1897                        int i = 0;
1898
1899                        static char *renderTypeStr[] = {"fixed function", "fixed function + depth pass", "deferred shading"};
1900       
1901                        sprintf(msg[i ++], "multiqueries: %d, tight bounds: %d, render queue: %d",
1902                                                        useMultiQueries, useTightBounds, useRenderQueue);
1903
1904                        sprintf(msg[i ++], "render technique: %s, SSAO: %d", renderTypeStr[renderType], useSsao);
1905
1906                        sprintf(msg[i ++], "triangles per virtual leaf: %5d", trianglesPerVirtualLeaf);
1907
1908                        sprintf(msg[i ++], "assumed visible frames: %4d, max batch size: %4d",
1909                                assumedVisibleFrames, maxBatchSize);
1910
1911                        for (int j = 0; j < 4; ++ j)
1912                                myfont.DrawString(msg[j], 10.0f, winHeight - 5 - j * 20);
1913                }
1914
1915                if (showStatistics)
1916                {
1917                        glColor3f(1.0f, 1.0f, 0.0f);
1918
1919                        string str;
1920                        string str2;
1921
1922                        int len = 10;
1923                        CalcDecimalPoint(str, renderedTriangles, len);
1924                        CalcDecimalPoint(str2, bvh->GetBvhStats().mTriangles, len);
1925
1926                        int i = 4;
1927
1928                        sprintf(msg[i ++], "rendered: %6d of %6d nodes, %s of %s triangles",
1929                                renderedNodes, bvh->GetNumVirtualNodes(), str.c_str(), str2.c_str());
1930
1931                        sprintf(msg[i ++], "traversed: %5d, frustum culled: %5d, query culled: %5d",
1932                                traversedNodes, frustumCulledNodes, queryCulledNodes);
1933
1934                        sprintf(msg[i ++], "issued queries: %5d, state changes: %5d, render batches: %5d",
1935                                issuedQueries, stateChanges, numBatches);
1936
1937                        for (int j = 4; j < 7; ++ j)
1938                                myfont.DrawString(msg[j], 10.0f, winHeight - (j + 1) * 20);
1939                }
1940
1941                glColor3f(1.0f, 1.0f, 1.0f);
1942                static char *alg_str[] = {"Frustum Cull", "Stop and Wait", "CHC", "CHC ++"};
1943               
1944                if (!showAlgorithmTime)
1945                {
1946                        sprintf(msg[7], "%s:  %6.1f fps", alg_str[renderMode], fps);
1947                }
1948                else
1949                {
1950                        sprintf(msg[7], "%s:  %6.1f ms", alg_str[renderMode], rTime);
1951                }
1952
1953                myfont.DrawString(msg[7], 1.3f, 690.0f, 760.0f);//, top_color, bottom_color);
1954               
1955                //sprintf(msg[8], "algorithm time: %6.1f ms", rTime);
1956                //myfont.DrawString(msg[8], 720.0f, 730.0f);           
1957        }
1958
1959        glDisable(GL_BLEND);
1960        glDisable(GL_TEXTURE_2D);
1961
1962        End2D();
1963}       
1964
1965
1966void RenderSky()
1967{
1968        SceneEntityContainer::const_iterator sit, sit_end = skyGeometry.end();
1969
1970        for (sit = skyGeometry.begin(); sit != sit_end; ++ sit)
1971                (*sit)->Render(&state);
1972}
1973
1974
1975void RenderVisibleObjects()
1976{
1977        state.SetRenderType(RenderState::FIXED);
1978        state.Reset();
1979
1980        glEnable(GL_LIGHTING);
1981        glDepthFunc(GL_LEQUAL);
1982
1983        //cout << "visible: " << (int)traverser->GetVisibleObjects().size() << endl;
1984
1985        SceneEntityContainer::const_iterator sit,
1986                sit_end = traverser->GetVisibleObjects().end();
1987
1988        for (sit = traverser->GetVisibleObjects().begin(); sit != sit_end; ++ sit)
1989                renderQueue->Enqueue(*sit);
1990               
1991        renderQueue->Apply();
1992
1993        glDepthFunc(GL_LESS);
1994}
1995
1996
1997void PlaceViewer(const Vector3 &oldPos)
1998{
1999        Vector3 playerPos = camera->GetPosition();
2000
2001        bool validIntersect = false;//sceneQuery->CalcIntersection(playerPos);
2002
2003        if (validIntersect &&
2004                (( playerPos.z - oldPos.z) < bvh->GetBox().Size(2) * 1e-1f))
2005        {
2006                camera->SetPosition(playerPos);
2007        }
2008}
2009
2010
2011void DisplayRenderTexture3()
2012{
2013        glEnable(GL_TEXTURE_2D);
2014
2015        if (isFirstTexture)
2016                glBindTexture(GL_TEXTURE_2D, colorsTex1);
2017        else
2018                glBindTexture(GL_TEXTURE_2D, colorsTex2);
2019
2020        glDisable(GL_LIGHTING);
2021       
2022        glMatrixMode(GL_PROJECTION);
2023        glPushMatrix();
2024        glLoadIdentity();
2025
2026        glMatrixMode(GL_MODELVIEW);
2027        glPushMatrix();
2028        glLoadIdentity();
2029
2030        const float offs = 0.5f;
2031        glOrtho(-offs, offs, -offs, offs, 0, 1);
2032       
2033        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2034
2035        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
2036        glBegin(GL_QUADS);
2037
2038        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
2039        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
2040        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
2041        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
2042
2043        glEnd();
2044
2045        glEnable(GL_LIGHTING);
2046        glDisable(GL_TEXTURE_2D);
2047       
2048        glMatrixMode(GL_PROJECTION);
2049        glPopMatrix();
2050
2051        glMatrixMode(GL_MODELVIEW);
2052        glPopMatrix();
2053
2054        PrintGLerror("displaytexture3");
2055}
2056
2057
2058void DisplayRenderTexture()
2059{
2060        GLuint oldTex;
2061
2062        if (isFirstTexture)
2063        {
2064                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo1);
2065                oldTex = colorsTex2;
2066        }
2067        else
2068        {
2069                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
2070                oldTex = colorsTex1;
2071        }
2072
2073        glPushAttrib(GL_VIEWPORT_BIT);
2074        glViewport(0, 0, texWidth, texHeight);
2075
2076        glDrawBuffers(1, mrt);
2077
2078        glDisable(GL_ALPHA_TEST);
2079        glDisable(GL_TEXTURE_2D);
2080        glDisable(GL_LIGHTING);
2081       
2082        glMatrixMode(GL_PROJECTION);
2083        glPushMatrix();
2084        glLoadIdentity();
2085
2086        glMatrixMode(GL_MODELVIEW);
2087        glPushMatrix();
2088        glLoadIdentity();
2089
2090        const float offs = 0.5f;
2091       
2092        glOrtho(-offs, offs, -offs, offs, 0, 1);
2093       
2094        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2095
2096        cgGLEnableProfile(RenderState::sCgFragmentProfile);
2097
2098        if (useSsao)
2099        {
2100                cgGLBindProgram(sCgSsaoProgram);
2101               
2102                cgGLSetTextureParameter(sPositionsTexParamSsao, positionsTex);
2103                cgGLEnableTextureParameter(sPositionsTexParamSsao);
2104
2105                cgGLSetTextureParameter(sColorsTexParamSsao, colorsTex);
2106                cgGLEnableTextureParameter(sColorsTexParamSsao);
2107
2108                cgGLSetTextureParameter(sNormalsTexParamSsao, normalsTex);
2109                cgGLEnableTextureParameter(sNormalsTexParamSsao);
2110
2111                cgGLSetTextureParameter(sNoiseTexParamSsao, noiseTex);
2112                cgGLEnableTextureParameter(sNoiseTexParamSsao);
2113
2114                cgGLSetTextureParameter(sOldTexParamSsao, oldTex);
2115                cgGLEnableTextureParameter(sOldTexParamSsao);
2116
2117                cgGLSetParameter1f(sNoiseMultiplierParam, RandomValue(3.0f, 17.0f));
2118                cgGLSetParameter1f(sExpFactorParamSsao, expFactor);
2119
2120                GenerateSamples(); cgGLSetParameterArray2f(sSamplesParamSsao, 0, NUM_SAMPLES, (const float *)samples);
2121        }
2122        else
2123        {
2124                cgGLBindProgram(sCgDeferredProgram);
2125
2126                cgGLSetTextureParameter(sPositionsTexParam, positionsTex);
2127                cgGLEnableTextureParameter(sPositionsTexParam);
2128
2129                cgGLSetTextureParameter(sColorsTexParam, colorsTex);
2130                cgGLEnableTextureParameter(sColorsTexParam);
2131
2132                cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
2133                cgGLEnableTextureParameter(sNormalsTexParam);
2134        }
2135
2136        Vector3 tl, tr, bl, br;
2137        ComputeViewVectors(tl, tr, bl, br);
2138
2139        glColor3f(1.0f, 1.0f, 1.0f);
2140
2141        glBegin(GL_QUADS);
2142
2143        // note: slightly larger texture hides ambient occlusion error on border but costs resolution
2144        //float offs2 = 0.55f;
2145        float offs2 = 0.5f;
2146
2147        glColor3f(bl.x, bl.y, bl.z); glTexCoord2f(0, 0); glVertex3f(-offs2, -offs2, -0.5f);
2148        glColor3f(br.x, br.y, br.z); glTexCoord2f(1, 0); glVertex3f( offs2, -offs2, -0.5f);
2149        glColor3f(tr.x, tr.y, tr.z); glTexCoord2f(1, 1); glVertex3f( offs2,  offs2, -0.5f);
2150        glColor3f(tl.x, tl.y, tl.z); glTexCoord2f(0, 1); glVertex3f(-offs2,  offs2, -0.5f);
2151
2152        glEnd();
2153
2154       
2155        if (useSsao)
2156        {
2157                cgGLDisableTextureParameter(sColorsTexParamSsao);
2158                cgGLDisableTextureParameter(sPositionsTexParamSsao);
2159                cgGLDisableTextureParameter(sNormalsTexParamSsao);
2160                cgGLDisableTextureParameter(sNoiseTexParamSsao);
2161                cgGLDisableTextureParameter(sOldTexParamSsao);
2162        }
2163        else
2164        {
2165                cgGLDisableTextureParameter(sColorsTexParam);
2166                cgGLDisableTextureParameter(sPositionsTexParam);
2167                cgGLDisableTextureParameter(sNormalsTexParam);
2168        }
2169
2170        cgGLDisableProfile(RenderState::sCgFragmentProfile);
2171       
2172        glEnable(GL_LIGHTING);
2173        glDisable(GL_TEXTURE_2D);
2174       
2175        glMatrixMode(GL_PROJECTION);
2176        glPopMatrix();
2177
2178        glMatrixMode(GL_MODELVIEW);
2179        glPopMatrix();
2180
2181        glPopAttrib();
2182
2183        PrintGLerror("displaytexture");
2184
2185        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
2186
2187        DisplayRenderTexture3();
2188}
2189
2190#if 0
2191// kustls magic sample positions
2192void GenerateSamples()
2193{
2194        static const float mysamples[] =
2195        {
2196                -0.326212f, -0.405805f,
2197                -0.840144f, -0.07358f,
2198                -0.695914f, 0.457137f,
2199                -0.203345f, 0.620716,
2200                0.96234f, -0.194983f,
2201                0.473434f, -0.480026f,
2202                0.519456, 0.767022f,
2203                0.185461f, -0.893124f,
2204                0.507431f, 0.064425f,
2205                0.89642f, 0.412458f,
2206                -0.32194f, -0.932615f,
2207                -0.791559f, -0.597705f,
2208                0.326212f, 0.405805f,
2209                0.840144f, 0.07358f,
2210                0.695914f, -0.457137f,
2211                0.203345f, -0.620716,
2212                -0.96234f, 0.194983f,
2213                -0.473434f, 0.480026f,
2214                -0.519456, -0.767022f,
2215                -0.185461f, 0.893124f,
2216                -0.507431f, -0.064425f,
2217                -0.89642f, -0.412458f,
2218                0.32194f, 0.932615f,
2219                0.791559f, 0.597705f
2220        };
2221
2222        for (int i = 0; i < NUM_SAMPLES; ++ i)
2223        {
2224                samples[i] = mysamples[i];
2225        }
2226}
2227
2228#else
2229
2230
2231void GenerateSamples()
2232{
2233        static HaltonSequence halton;
2234
2235        float r[2];
2236
2237        // generates poisson distribution on disc
2238        float minDist = 2.0f / sqrt((float)NUM_SAMPLES);
2239
2240        //cout << "minDist before= " << minDist << endl;
2241
2242        for (int i = 0; i < NUM_SAMPLES * 2; i += 2)
2243        {
2244                int tries = 0, totalTries = 0;
2245
2246                // repeat until valid sample was found
2247                while (1)
2248                {
2249                        ++ tries;
2250                        ++ totalTries;
2251
2252                        halton.GetNext(2, r);
2253
2254                        //const float rx = RandomValue(-1, 1);
2255                        //const float ry = RandomValue(-1, 1);
2256
2257                        const float rx = r[0] * 2.0f - 1.0f;
2258                        const float ry = r[1] * 2.0f - 1.0f;
2259
2260                        // check if in disk, else exit early
2261                        if (rx * rx + ry * ry > 1)
2262                                continue;
2263
2264                        bool sampleValid = true;
2265
2266                        // check poisson property
2267                        for (int j = 0; ((j < i) && sampleValid); j += 2)
2268                        {
2269                                const float dist =
2270                                        sqrt((samples[j] - rx) * (samples[j] - rx) +
2271                                             (samples[j + 1] - ry) * (samples[j + 1] - ry));
2272                       
2273                                if (dist < minDist)
2274                                        sampleValid = false;
2275                        }
2276
2277                        if (sampleValid)
2278                        {
2279                                samples[i] = rx;
2280                                samples[i + 1]= ry;
2281                                break;
2282                        }
2283
2284                        if (tries > 2000)
2285                        {
2286                                minDist *= 0.9f;
2287                                tries = 0;
2288                        }
2289                }
2290                //cout << "sample: " << samples[i] << " " << i / 2 << " " << samples[i + 1] << " r: " << sqrt(samples[i] * samples[i]  + samples[i + 1] * samples[i + 1]) << " tries: " << totalTries << endl;
2291        }
2292
2293        //cout << "minDist after= " << minDist << endl;
2294}
2295
2296
2297#endif
2298
2299
2300void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
2301{
2302        float myfov = fov * M_PI / 180.0f;
2303
2304        const float w_far = 2.0f * tan(myfov / 2.0f);
2305        const float aspect = texWidth / texHeight;
2306
2307        const float h_far = w_far / aspect;
2308
2309        float t1 = h_far * 0.5f;
2310        float t2 = w_far * 0.5f;
2311
2312#if 0
2313        bl = Normalize(-Vector3(-t1, -t2, 1.0f));
2314        br = Normalize(-Vector3( t1, -t2, 1.0f));
2315        tl = Normalize(-Vector3(-t1,  t2, 1.0f));
2316        tr = Normalize(-Vector3( t1,  t2, 1.0f));
2317#else
2318        bl = -Normalize(camera->GetDirection());
2319        br = -Normalize(camera->GetDirection());
2320        tl = -Normalize(camera->GetDirection());
2321        tr = -Normalize(camera->GetDirection());
2322#endif
2323        // normalize to 0 .. 1
2324        bl = bl * 0.5f + 0.5f;
2325        br = br * 0.5f + 0.5f;
2326        tl = tl * 0.5f + 0.5f;
2327        tr = tr * 0.5f + 0.5f;
2328}
2329
2330
2331void CreateNoiseTex2D()
2332{
2333        randomNormals = new GLubyte[texWidth * texHeight * 3];
2334
2335        for (int i = 0; i < texWidth * texHeight * 3; i += 3)
2336        {
2337                // create random samples over sphere
2338                const float rx = RandomValue(0, 1);
2339                const float theta = 2.0f * acos(sqrt(1.0f - rx));
2340
2341                randomNormals[i + 0] = (GLubyte)((cos(theta) * 0.5f + 0.5f) * 255.0f);
2342                randomNormals[i + 1] = (GLubyte)((sin(theta) * 0.5f + 0.5f) * 255.0f);
2343                randomNormals[i + 2] = 0;
2344        }
2345
2346        glEnable(GL_TEXTURE_2D);
2347        glGenTextures(1, &noiseTex);
2348        glBindTexture(GL_TEXTURE_2D, noiseTex);
2349               
2350        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2351        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2352        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2353        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2354
2355        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, randomNormals);
2356        //gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, texWidth, texHeight, GL_RGB, GL_UNSIGNED_BYTE, randomNormals);
2357
2358        glBindTexture(GL_TEXTURE_2D, 0);
2359        glDisable(GL_TEXTURE_2D);
2360
2361        cout << "created noise texture" << endl;
2362        PrintGLerror("noisetexture");
2363}
Note: See TracBrowser for help on using the repository browser.