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

Revision 2834, 55.7 KB checked in by mattausch, 16 years ago (diff)

research version: implemented temporal smoothing and color bleeding

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