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

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