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

Revision 2857, 59.0 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        myfbo = new FrameBufferObject(texWidth, texHeight, true, FrameBufferObject::DEPTH_24);
671
672
673        ColorBufferObject *diffuseBuffer =
674                myfbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32,
675                                      ColorBufferObject::WRAP_CLAMP_TO_EDGE,
676                                                          ColorBufferObject::FILTER_LINEAR,
677                                                          false, false);
678
679        ColorBufferObject *mypositionBuffer =
680                myfbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32,
681                                      ColorBufferObject::WRAP_CLAMP_TO_EDGE,
682                                                          ColorBufferObject::FILTER_NEAREST,
683                                                          false, false);
684
685
686        ColorBufferObject *mynormalsBuffer =
687                myfbo->AddColorBuffer(ColorBufferObject::BUFFER_UBYTE,
688                                      ColorBufferObject::WRAP_CLAMP_TO_EDGE,
689                                                          ColorBufferObject::FILTER_NEAREST,
690                                                          false, false);
691
692       
693
694
695        ////////////////////////
696
697        glGenFramebuffersEXT(1, &fbo);
698        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
699
700       
701        ////////////
702        //-- colors buffer
703
704        glGenRenderbuffersEXT(1, &colorsBuffer);
705        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorsBuffer);
706       
707#if 1
708        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, texWidth, texHeight);
709#else
710        int samples = 8;
711        glEnable(GL_MULTISAMPLE_ARB);
712        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_RGBA8, texWidth, texHeight);
713#endif
714
715        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorsBuffer);
716       
717        glGenTextures(1, &colorsTex);
718        glBindTexture(GL_TEXTURE_2D, colorsTex);
719
720        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
721        //glGenerateMipmapEXT(GL_TEXTURE_2D);
722        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorsTex, 0);
723
724        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
725        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
726
727        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
728        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
729
730
731        //////////
732        //-- positions buffer
733
734        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
735        glGenRenderbuffersEXT(1, &positionsBuffer);
736        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, positionsBuffer);
737        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, texWidth, texHeight);
738
739        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER_EXT, positionsBuffer);
740
741        glGenTextures(1, &positionsTex);
742        glBindTexture(GL_TEXTURE_2D, positionsTex);
743        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
744        //glGenerateMipmapEXT(GL_TEXTURE_2D);
745        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, positionsTex, 0);
746
747        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
748        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
749
750        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
751        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
752
753        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
754       
755       
756        ////////
757        //-- normals buffer
758
759        glGenRenderbuffersEXT(1, &normalsBuffer);
760        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, normalsBuffer);
761        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, texWidth, texHeight);
762       
763        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_RENDERBUFFER_EXT, normalsBuffer);
764
765        glGenTextures(1, &normalsTex);
766        glBindTexture(GL_TEXTURE_2D, normalsTex);
767        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
768        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, normalsTex, 0);
769
770        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
771        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
772
773        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
774        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
775
776        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
777
778
779        ///////////
780        //-- create depth buffer
781
782        glGenRenderbuffersEXT(1, &depthBuffer);
783        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
784        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, texWidth, texHeight);
785        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
786
787       
788        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
789       
790       
791
792        //////////////////////////////////
793
794
795
796        glGenFramebuffersEXT(1, &fbo1);
797        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo1);
798
799       
800        ////////////
801        //-- colors buffer
802
803        glGenRenderbuffersEXT(1, &colorsBuffer1);
804        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorsBuffer1);
805       
806        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, texWidth, texHeight);
807        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorsBuffer1);
808       
809        glGenTextures(1, &colorsTex1);
810        glBindTexture(GL_TEXTURE_2D, colorsTex1);
811
812        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
813        //glGenerateMipmapEXT(GL_TEXTURE_2D);
814        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorsTex1, 0);
815
816        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
817        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
818
819        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
820        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
821
822        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
823        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
824
825        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
826
827
828
829        /////////////////////////
830
831        glGenFramebuffersEXT(1, &fbo2);
832        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
833
834       
835        ////////////
836        //-- colors buffer
837
838        glGenRenderbuffersEXT(1, &colorsBuffer2);
839        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorsBuffer2);
840       
841        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, texWidth, texHeight);
842        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorsBuffer2);
843       
844        glGenTextures(1, &colorsTex2);
845        glBindTexture(GL_TEXTURE_2D, colorsTex2);
846
847        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
848        //glGenerateMipmapEXT(GL_TEXTURE_2D);
849        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorsTex2, 0);
850
851        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
852        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
853
854        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
855        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
856
857        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
858        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
859
860        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
861        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
862
863        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
864
865        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
866
867        PrintGLerror("fbo");
868}
869
870
871bool InitFont(void)
872{
873        glEnable(GL_TEXTURE_2D);
874
875        glGenTextures(1, &fontTex);
876        glBindTexture(GL_TEXTURE_2D, fontTex);
877        if (!myfont.Create("data/fonts/verdana.glf", fontTex))
878                return false;
879
880        glDisable(GL_TEXTURE_2D);
881       
882        return true;
883}
884
885
886void InitGLstate()
887{
888        glClearColor(0.5f, 0.5f, 0.8f, 0.0f);
889       
890        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
891        glPixelStorei(GL_PACK_ALIGNMENT,1);
892       
893        glDepthFunc(GL_LESS);
894        glEnable(GL_DEPTH_TEST);
895
896        SetupLighting();
897
898        glColor3f(1.0f, 1.0f, 1.0f);
899        glShadeModel(GL_SMOOTH);
900       
901        glMaterialf(GL_FRONT, GL_SHININESS, 64);
902        glEnable(GL_NORMALIZE);
903               
904        //glEnable(GL_ALPHA_TEST);
905        glDisable(GL_ALPHA_TEST);
906        glAlphaFunc(GL_GEQUAL, 0.8f);
907
908        glFrontFace(GL_CCW);
909        glCullFace(GL_BACK);
910        glEnable(GL_CULL_FACE);
911
912        //glDisable(GL_CULL_FACE);
913        glDisable(GL_TEXTURE_2D);
914
915        GLfloat ambientColor[] = {0.5, 0.5, 0.5, 1.0};
916        GLfloat diffuseColor[] = {1.0, 0.0, 0.0, 1.0};
917        GLfloat specularColor[] = {0.0, 0.0, 0.0, 1.0};
918
919        glMaterialfv(GL_FRONT, GL_AMBIENT, ambientColor);
920        glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor);
921        glMaterialfv(GL_FRONT, GL_SPECULAR, specularColor);
922
923        glDepthFunc(GL_LESS);
924
925        if (!InitFont())
926                cerr << "font creation failed" << endl;
927        else
928                cout << "successfully created font" << endl;
929}
930
931
932void DrawHelpMessage()
933{
934        const char *message[] =
935        {
936                "Help information",
937                "",
938                "'F1'           - shows/dismisses this message",
939                "'F2'           - shows/hides bird eye view",
940                "'F3'           - shows/hides bounds (boxes or tight bounds)",
941                "'F4',          - shows/hides parameters",
942                "'F5'           - shows/hides statistics",
943                "'F6',          - toggles between fly/walkmode",
944                "'F7',          - cycles throw render modes",
945                "'F8',          - enables/disables ambient occlusion (only deferred)",
946                "'F9',          - shows pure algorithm render time (using glFinish)",
947                "'SPACE'        - cycles through occlusion culling algorithms",
948                "",
949                "'MOUSE LEFT'        - turn left/right, move forward/backward",
950                "'MOUSE RIGHT'       - turn left/right, move forward/backward",
951                "'MOUSE MIDDLE'      - move up/down, left/right",
952                "'CURSOR UP/DOWN'    - move forward/backward",
953                "'CURSOR LEFT/RIGHT' - turn left/right",
954                "",
955                "'-'/'+'        - decreases/increases max batch size",
956                "'1'/'2'        - downward/upward motion",
957                "'3'/'4'        - decreases/increases triangles per virtual bvh leaf (sets bvh depth)",
958                "'5'/'6'        - decreases/increases assumed visible frames",
959                "",
960                "'R'            - use render queue",
961                "'B'            - use tight bounds",
962                "'M'            - use multiqueries",
963                "'O'            - use CHC optimization (geometry queries for leaves)",
964                0,
965        };
966       
967       
968        glColor4f(0.0f, 1.0f , 0.0f, 0.2f); // 20% green.
969
970        glRecti(30, 30, winWidth - 30, winHeight - 30);
971
972        glEnd();
973
974        glColor3f(1.0f, 1.0f, 1.0f);
975       
976        glEnable(GL_TEXTURE_2D);
977        myfont.Begin();
978
979        int x = 40, y = 30;
980
981        for(int i = 0; message[i] != 0; ++ i)
982        {
983                if(message[i][0] == '\0')
984                {
985                        y += 15;
986                }
987                else
988                {
989                        myfont.DrawString(message[i], x, winHeight - y);
990                        y += 25;
991                }
992        }
993        glDisable(GL_TEXTURE_2D);
994}
995
996
997void ResetTraverser()
998{
999        DEL_PTR(traverser);
1000
1001        bvh->ResetNodeClassifications();
1002
1003        switch (renderMode)
1004        {
1005        case RenderTraverser::CULL_FRUSTUM:
1006                traverser = new FrustumCullingTraverser();
1007                break;
1008        case RenderTraverser::STOP_AND_WAIT:
1009                traverser = new StopAndWaitTraverser();
1010                break;
1011        case RenderTraverser::CHC:
1012                traverser = new CHCTraverser();
1013                break;
1014        case RenderTraverser::CHCPLUSPLUS:
1015                traverser = new CHCPlusPlusTraverser();
1016                break;
1017       
1018        default:
1019                traverser = new FrustumCullingTraverser();
1020        }
1021
1022        traverser->SetCamera(camera);
1023        traverser->SetHierarchy(bvh);
1024        traverser->SetRenderQueue(renderQueue);
1025        traverser->SetRenderState(&state);
1026        traverser->SetUseOptimization(useOptimization);
1027        traverser->SetUseRenderQueue(useRenderQueue);
1028        traverser->SetVisibilityThreshold(threshold);
1029        traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
1030        traverser->SetMaxBatchSize(maxBatchSize);
1031        traverser->SetUseMultiQueries(useMultiQueries);
1032        traverser->SetUseTightBounds(useTightBounds);
1033        traverser->SetUseDepthPass(renderType == RenderState::DEPTH_PASS);
1034        traverser->SetRenderQueue(renderQueue);
1035}
1036
1037
1038void SetupLighting()
1039{
1040        glEnable(GL_LIGHTING);
1041        glEnable(GL_LIGHT0);
1042        glEnable(GL_LIGHT1);
1043       
1044        GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
1045        GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0};
1046        GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
1047           
1048        GLfloat lmodel_ambient[] = {0.3f, 0.3f, 0.3f, 1.0f};
1049
1050        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
1051        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
1052        glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
1053
1054
1055        ////////////
1056        //-- second light
1057
1058        GLfloat ambient1[] = {0.2, 0.2, 0.2, 1.0};
1059        GLfloat diffuse1[] = {1.0, 1.0, 1.0, 1.0};
1060        //GLfloat diffuse1[] = {0.5, 0.5, 0.5, 1.0};
1061        GLfloat specular1[] = {0.0, 0.0, 0.0, 1.0};
1062
1063        glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1);
1064        glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1);
1065        glLightfv(GL_LIGHT1, GL_SPECULAR, specular1);
1066
1067       
1068        //////////////////////////////
1069
1070        GLfloat position[] = {0.8f, -1.0f, 0.7f, 0.0f};
1071        glLightfv(GL_LIGHT0, GL_POSITION, position);
1072
1073        GLfloat position1[] = {-0.5f, 0.5f, 0.4f, 0.0f};
1074        glLightfv(GL_LIGHT1, GL_POSITION, position1);
1075
1076        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
1077        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
1078        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SINGLE_COLOR_EXT);
1079}
1080
1081
1082void SetupEyeView()
1083{
1084        Matrix4x4 matViewing, matProjection;
1085
1086        if (renderType == RenderState::DEFERRED)
1087        {
1088                cgGLSetMatrixParameterfc(sOldModelViewProjMatrixParam, (const float *)matProjectionView.x);
1089        }
1090
1091        glMatrixMode(GL_PROJECTION);
1092        glLoadIdentity();
1093
1094        gluPerspective(fov, winAspectRatio, nearDist, myfar);
1095
1096        glMatrixMode(GL_MODELVIEW);
1097        glLoadIdentity();
1098        camera->SetupCameraView();
1099
1100        GLfloat position[] = {0.8f, -1.0f, 0.7f, 0.0f};
1101        glLightfv(GL_LIGHT0, GL_POSITION, position);
1102
1103        GLfloat position1[] = {-0.5f, 0.5f, 0.4f, 0.0f};
1104        glLightfv(GL_LIGHT1, GL_POSITION, position1);
1105
1106       
1107        camera->GetModelViewMatrix(matViewing);
1108        camera->GetProjectionMatrix(matProjection);
1109
1110        matProjectionView = matViewing * matProjection;
1111       
1112        if (renderType == RenderState::DEFERRED)
1113        {
1114                // set modelview matrix for shaders
1115                cgGLSetStateMatrixParameter(sModelViewProjMatrixParam,
1116                                                                        CG_GL_MODELVIEW_PROJECTION_MATRIX,
1117                                                                        CG_GL_MATRIX_IDENTITY);
1118
1119                static Matrix4x4 identity = IdentityMatrix();
1120                cgGLSetMatrixParameterfc(Transform3::sModelMatrixParam, (const float *)identity.x);
1121        }               
1122}
1123
1124
1125void KeyHorizontalMotion(float shift)
1126{
1127        Vector3 hvec = camera->GetDirection();
1128        hvec.z = 0;
1129
1130        Vector3 pos = camera->GetPosition();
1131        pos += hvec * shift;
1132       
1133        camera->SetPosition(pos);
1134}
1135
1136
1137void KeyVerticalMotion(float shift)
1138{
1139        Vector3 uvec = Vector3(0, 0, shift);
1140
1141        Vector3 pos = camera->GetPosition();
1142        pos += uvec;
1143       
1144        camera->SetPosition(pos);
1145}
1146
1147
1148// the main rendering loop
1149void Display()
1150{       
1151        Vector3 oldPos = camera->GetPosition();
1152
1153        if (leftKeyPressed)
1154                camera->Pitch(KeyRotationAngle());
1155        if (rightKeyPressed)
1156                camera->Pitch(-KeyRotationAngle());
1157        if (upKeyPressed)
1158                KeyHorizontalMotion(KeyShift());
1159        if (downKeyPressed)
1160                KeyHorizontalMotion(-KeyShift());
1161        if (ascendKeyPressed)
1162                KeyVerticalMotion(KeyShift());
1163        if (descendKeyPressed)
1164                KeyVerticalMotion(-KeyShift());
1165
1166        // place view on ground
1167        if (!flyMode) PlaceViewer(oldPos);
1168
1169        if (showAlgorithmTime)
1170        {
1171                glFinish();
1172                algTimer.Start();
1173        }
1174       
1175        // render without shading
1176        switch (renderType)
1177        {
1178        case RenderState::FIXED:
1179       
1180                glEnable(GL_MULTISAMPLE_ARB);
1181                //glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
1182
1183                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1184
1185                state.SetRenderType(RenderState::FIXED);
1186                glEnable(GL_LIGHTING);
1187
1188                cgGLDisableProfile(RenderState::sCgFragmentProfile);
1189                cgGLDisableProfile(RenderState::sCgVertexProfile);
1190
1191                glDrawBuffers(1, mrt);
1192
1193                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1194
1195                break;
1196
1197        case RenderState::DEPTH_PASS:
1198
1199                glEnable(GL_MULTISAMPLE_ARB);
1200                //glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
1201
1202                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1203
1204                cgGLDisableProfile(RenderState::sCgFragmentProfile);
1205                cgGLDisableProfile(RenderState::sCgVertexProfile);
1206
1207                state.SetRenderType(RenderState::DEPTH_PASS);
1208
1209                // the scene is rendered withouth any shading   
1210                glDisable(GL_LIGHTING);
1211       
1212                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1213
1214                glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1215
1216                glDrawBuffers(1, mrt);
1217
1218                break;
1219       
1220        case RenderState::DEFERRED:
1221
1222                // multisampling not working with deferred shading
1223                //glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
1224                glDisable(GL_MULTISAMPLE_ARB);
1225
1226                state.SetRenderType(RenderState::DEFERRED);
1227
1228                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
1229       
1230                glPushAttrib(GL_VIEWPORT_BIT);
1231                glViewport(0, 0, texWidth, texHeight);
1232
1233                cgGLEnableProfile(RenderState::sCgFragmentProfile);
1234                cgGLBindProgram(RenderState::sCgMrtFragmentProgram);
1235
1236                cgGLEnableProfile(RenderState::sCgVertexProfile);
1237                cgGLBindProgram(sCgMrtVertexProgram);
1238
1239                glDrawBuffers(3, mrt);
1240
1241                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1242
1243                break;
1244        }
1245
1246
1247        glDepthFunc(GL_LESS);
1248
1249        glDisable(GL_TEXTURE_2D);
1250        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1251               
1252
1253        LODLevel::InitFrame(camera->GetPosition());
1254
1255
1256        // bring eye modelview matrix up-to-date
1257        SetupEyeView();
1258
1259        // actually render the scene geometry using one of the specified algorithms
1260        traverser->RenderScene();
1261
1262
1263
1264        /////////
1265        //-- do the rest of the rendering
1266
1267        glEnableClientState(GL_VERTEX_ARRAY);
1268        glEnableClientState(GL_NORMAL_ARRAY);
1269
1270
1271        // reset depth pass and render visible objects
1272        if (renderType == RenderState::DEPTH_PASS)
1273        {
1274                glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1275                RenderVisibleObjects();
1276        }
1277       
1278
1279        ///////////////
1280        //-- render sky
1281
1282        RenderSky();
1283
1284        state.Reset();
1285
1286        glDisableClientState(GL_VERTEX_ARRAY);
1287        glDisableClientState(GL_NORMAL_ARRAY);
1288
1289
1290        if (renderType == RenderState::DEFERRED)
1291        {
1292                //glPopAttrib();
1293                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1294
1295                cgGLDisableProfile(RenderState::sCgVertexProfile);
1296                cgGLDisableProfile(RenderState::sCgFragmentProfile);
1297
1298                glDrawBuffers(1, mrt);
1299
1300                DisplayRenderTexture();
1301        }
1302
1303       
1304        ///////////
1305
1306        state.SetRenderType(RenderState::FIXED);
1307
1308        if (showAlgorithmTime)
1309        {
1310                glFinish();
1311
1312                algTime = algTimer.Elapsedms();
1313                perfGraph->AddData(algTime);
1314
1315                perfGraph->Draw();
1316        }
1317        else
1318        {
1319                if (visMode) DisplayVisualization();
1320        }
1321
1322        //glFlush();
1323
1324        const bool restart = true;
1325        elapsedTime = frameTimer.Elapsedms(restart);
1326
1327        DisplayStats();
1328
1329        // flip textures for temporal smoothing
1330        isFirstTexture = !isFirstTexture;
1331
1332        glutSwapBuffers();
1333}
1334
1335
1336#pragma warning( disable : 4100 )
1337void KeyBoard(unsigned char c, int x, int y)
1338{
1339        switch(c)
1340        {
1341        case 27:
1342                CleanUp();
1343                exit(0);
1344                break;
1345        case 32: //space
1346                renderMode = (renderMode + 1) % RenderTraverser::NUM_TRAVERSAL_TYPES;
1347                ResetTraverser();
1348                break;
1349        case 'h':
1350        case 'H':
1351                showHelp = !showHelp;
1352                break;
1353        case '+':
1354                maxBatchSize += 10;
1355                traverser->SetMaxBatchSize(maxBatchSize);
1356                break;
1357        case '-':
1358                maxBatchSize -= 10;
1359                if (maxBatchSize < 0) maxBatchSize = 1;
1360                traverser->SetMaxBatchSize(maxBatchSize);               
1361                break;
1362        case 'M':
1363        case 'm':
1364                useMultiQueries = !useMultiQueries;
1365                traverser->SetUseMultiQueries(useMultiQueries);
1366                break;
1367        case '1':
1368                descendKeyPressed = true;
1369                break;
1370        case '2':
1371                ascendKeyPressed = true;
1372                break;
1373        case '3':
1374                if (trianglesPerVirtualLeaf >= 100)
1375                        trianglesPerVirtualLeaf -= 100;
1376                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1377                break;
1378        case '4':
1379                trianglesPerVirtualLeaf += 100;
1380                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1381                break;
1382        case '5':
1383                assumedVisibleFrames -= 1;
1384                if (assumedVisibleFrames < 1) assumedVisibleFrames = 1;
1385                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
1386                break;
1387        case '6':
1388                assumedVisibleFrames += 1;
1389                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);               
1390                break;
1391        case '7':
1392                expFactor *= 0.5f;
1393                break;
1394        case '8':
1395                expFactor *= 2.0f;
1396                if (expFactor > 1.0f) expFactor = 1.0f;
1397                break;
1398        case 'o':
1399        case 'O':
1400                useOptimization = !useOptimization;
1401                traverser->SetUseOptimization(useOptimization);
1402                break;
1403        case 'a':
1404        case 'A':
1405                        leftKeyPressed = true;
1406                break;
1407        case 'd':
1408        case 'D':
1409                        rightKeyPressed = true;
1410                break;
1411        case 'w':
1412        case 'W':
1413                        upKeyPressed = true;
1414                break;
1415        case 's':
1416        case 'S':
1417                        downKeyPressed = true;
1418                break;
1419        case 'r':
1420        case 'R':
1421                {
1422                        useRenderQueue = !useRenderQueue;
1423                        traverser->SetUseRenderQueue(useRenderQueue);
1424                }
1425                break;
1426        case 'b':
1427        case 'B':
1428                {
1429                        useTightBounds = !useTightBounds;
1430                        traverser->SetUseTightBounds(useTightBounds);
1431                }
1432                break;
1433        default:
1434                return;
1435        }
1436
1437        glutPostRedisplay();
1438}
1439
1440
1441void SpecialKeyUp(int c, int x, int y)
1442{
1443        switch (c)
1444        {
1445        case GLUT_KEY_LEFT:
1446                leftKeyPressed = false;
1447                break;
1448        case GLUT_KEY_RIGHT:
1449                rightKeyPressed = false;
1450                break;
1451        case GLUT_KEY_UP:
1452                upKeyPressed = false;
1453                break;
1454        case GLUT_KEY_DOWN:
1455                downKeyPressed = false;
1456                break;
1457        default:
1458                return;
1459        }
1460        //glutPostRedisplay();
1461}
1462
1463
1464void KeyUp(unsigned char c, int x, int y)
1465{
1466        switch (c)
1467        {
1468        case 'A':
1469        case 'a':
1470                leftKeyPressed = false;
1471                break;
1472        case 'D':
1473        case 'd':
1474                rightKeyPressed = false;
1475                break;
1476        case 'W':
1477        case 'w':
1478                upKeyPressed = false;
1479                break;
1480        case 'S':
1481        case 's':
1482                downKeyPressed = false;
1483                break;
1484        case '1':
1485                descendKeyPressed = false;
1486                break;
1487        case '2':
1488                ascendKeyPressed = false;
1489                break;
1490       
1491        default:
1492                return;
1493        }
1494        //glutPostRedisplay();
1495}
1496
1497
1498void Special(int c, int x, int y)
1499{
1500        switch(c)
1501        {
1502        case GLUT_KEY_F1:
1503                showHelp = !showHelp;
1504                break;
1505        case GLUT_KEY_F2:
1506                visMode = !visMode;
1507                break;
1508        case GLUT_KEY_F3:
1509                showBoundingVolumes = !showBoundingVolumes;
1510                traverser->SetShowBounds(showBoundingVolumes);
1511                break;
1512        case GLUT_KEY_F4:
1513                showOptions = !showOptions;
1514                break;
1515        case GLUT_KEY_F5:
1516                showStatistics = !showStatistics;
1517                break;
1518        case GLUT_KEY_F6:
1519                flyMode = !flyMode;
1520                break;
1521        case GLUT_KEY_F7:
1522
1523                renderType = (renderType + 1) % 3;
1524                traverser->SetUseDepthPass(renderType == RenderState::DEPTH_PASS);
1525               
1526                break;
1527        case GLUT_KEY_F8:
1528                useSsao = !useSsao;
1529                break;
1530        case GLUT_KEY_F9:
1531                showAlgorithmTime = !showAlgorithmTime;
1532                break;
1533
1534        case GLUT_KEY_LEFT:
1535                {
1536                        leftKeyPressed = true;
1537                        camera->Pitch(KeyRotationAngle());
1538                }
1539                break;
1540        case GLUT_KEY_RIGHT:
1541                {
1542                        rightKeyPressed = true;
1543                        camera->Pitch(-KeyRotationAngle());
1544                }
1545                break;
1546        case GLUT_KEY_UP:
1547                {
1548                        upKeyPressed = true;
1549                        KeyHorizontalMotion(KeyShift());
1550                }
1551                break;
1552        case GLUT_KEY_DOWN:
1553                {
1554                        downKeyPressed = true;
1555                        KeyHorizontalMotion(-KeyShift());
1556                }
1557                break;
1558        default:
1559                return;
1560
1561        }
1562
1563        glutPostRedisplay();
1564}
1565
1566#pragma warning( default : 4100 )
1567
1568
1569void Reshape(int w, int h)
1570{
1571        winAspectRatio = 1.0f;
1572
1573        glViewport(0, 0, w, h);
1574       
1575        winWidth = w;
1576        winHeight = h;
1577
1578        if (w) winAspectRatio = (float) w / (float) h;
1579
1580        glMatrixMode(GL_PROJECTION);
1581        glLoadIdentity();
1582
1583        gluPerspective(fov, winAspectRatio, nearDist, myfar);
1584
1585        glMatrixMode(GL_MODELVIEW);
1586
1587        glutPostRedisplay();
1588}
1589
1590
1591void Mouse(int button, int state, int x, int y)
1592{
1593        if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
1594        {
1595                xEyeBegin = x;
1596                yMotionBegin = y;
1597
1598                glutMotionFunc(LeftMotion);
1599        }
1600        else if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN))
1601        {
1602                xEyeBegin = x;
1603                yEyeBegin = y;
1604                yMotionBegin = y;
1605
1606                glutMotionFunc(RightMotion);
1607        }
1608        else if ((button == GLUT_MIDDLE_BUTTON) && (state == GLUT_DOWN))
1609        {
1610                horizontalMotionBegin = x;
1611                verticalMotionBegin = y;
1612                glutMotionFunc(MiddleMotion);
1613        }
1614
1615        glutPostRedisplay();
1616}
1617
1618
1619/**     rotation for left/right mouse drag
1620        motion for up/down mouse drag
1621*/
1622void LeftMotion(int x, int y)
1623{
1624        Vector3 viewDir = camera->GetDirection();
1625        Vector3 pos = camera->GetPosition();
1626
1627        // don't move in the vertical direction
1628        Vector3 horView(viewDir[0], viewDir[1], 0);
1629       
1630        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
1631
1632        camera->Pitch(eyeXAngle);
1633
1634        pos += horView * (yMotionBegin - y) * 0.2f;
1635       
1636        camera->SetPosition(pos);
1637       
1638        xEyeBegin = x;
1639        yMotionBegin = y;
1640
1641        glutPostRedisplay();
1642}
1643
1644
1645/**     rotation for left / right mouse drag
1646        motion for up / down mouse drag
1647*/
1648void RightMotion(int x, int y)
1649{
1650        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
1651        float eyeYAngle = -0.2f *  M_PI * (yEyeBegin - y) / 180.0;
1652
1653        camera->Yaw(eyeYAngle);
1654        camera->Pitch(eyeXAngle);
1655
1656        xEyeBegin = x;
1657        yEyeBegin = y;
1658
1659        glutPostRedisplay();
1660}
1661
1662
1663// strafe
1664void MiddleMotion(int x, int y)
1665{
1666        Vector3 viewDir = camera->GetDirection();
1667        Vector3 pos = camera->GetPosition();
1668
1669        // the 90 degree rotated view vector
1670        // y zero so we don't move in the vertical
1671        Vector3 rVec(viewDir[0], viewDir[1], 0);
1672       
1673        Matrix4x4 rot = RotationZMatrix(M_PI * 0.5f);
1674        rVec = rot * rVec;
1675       
1676        pos -= rVec * (x - horizontalMotionBegin) * 0.1f;
1677        pos[2] += (verticalMotionBegin - y) * 0.1f;
1678
1679        camera->SetPosition(pos);
1680
1681        horizontalMotionBegin = x;
1682        verticalMotionBegin = y;
1683
1684        glutPostRedisplay();
1685}
1686
1687
1688void InitExtensions(void)
1689{
1690        GLenum err = glewInit();
1691
1692        if (GLEW_OK != err)
1693        {
1694                // problem: glewInit failed, something is seriously wrong
1695                fprintf(stderr,"Error: %s\n", glewGetErrorString(err));
1696                exit(1);
1697        }
1698        if  (!GLEW_ARB_occlusion_query)
1699        {
1700                printf("I require the GL_ARB_occlusion_query to work.\n");
1701                exit(1);
1702        }
1703}
1704
1705
1706void Begin2D()
1707{
1708        glDisable(GL_LIGHTING);
1709        glDisable(GL_DEPTH_TEST);
1710
1711        glMatrixMode(GL_PROJECTION);
1712        glPushMatrix();
1713        glLoadIdentity();
1714
1715        gluOrtho2D(0, winWidth, 0, winHeight);
1716
1717        glMatrixMode(GL_MODELVIEW);
1718        glPushMatrix();
1719        glLoadIdentity();
1720}
1721
1722
1723void End2D()
1724{
1725        glMatrixMode(GL_PROJECTION);
1726        glPopMatrix();
1727
1728        glMatrixMode(GL_MODELVIEW);
1729        glPopMatrix();
1730
1731        glEnable(GL_LIGHTING);
1732        glEnable(GL_DEPTH_TEST);
1733}
1734
1735
1736// displays the visualisation of culling algorithm
1737void DisplayVisualization()
1738{
1739        visualization->SetFrameId(traverser->GetCurrentFrameId());
1740       
1741        Begin2D();
1742        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1743        glEnable(GL_BLEND);
1744        glColor4f(0.0f ,0.0f, 0.0f, 0.5f);
1745
1746        glRecti(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth, winHeight);
1747        glDisable(GL_BLEND);
1748        End2D();
1749       
1750       
1751        AxisAlignedBox3 box = bvh->GetBox();
1752
1753        // hack: set far plane for viz
1754        camera->SetFar(0.35f * Magnitude(box.Diagonal()));
1755
1756        const float offs = box.Size().x * 0.3f;
1757       
1758        //Vector3 vizpos = Vector3(box.Min().x, box.Min().y + box.Size().y * 0.5f, box.Min().z + box.Size().z * 50);
1759        Vector3 vizpos = Vector3(box.Min().x, box.Min().y  - box.Size().y * 0.35f, box.Min().z + box.Size().z * 50);
1760       
1761        visCamera->SetPosition(vizpos);
1762        visCamera->ResetPitchAndYaw();
1763        //visCamera->Pitch(M_PI);
1764
1765        glPushAttrib(GL_VIEWPORT_BIT);
1766        glViewport(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth / 3, winHeight / 3);
1767
1768        glMatrixMode(GL_PROJECTION);
1769        glPushMatrix();
1770
1771        glLoadIdentity();
1772       
1773        glOrtho(-offs, offs, -offs, offs, 0.0f, box.Size().z * 100.0f);
1774
1775        glMatrixMode(GL_MODELVIEW);
1776        glPushMatrix();
1777
1778        visCamera->SetupCameraView();
1779
1780        //Matrix4x4 rotX = RotationXMatrix(camera->GetYaw());
1781        //glMultMatrixf((float *)rotX.x);
1782        Matrix4x4 rotZ = RotationZMatrix(-camera->GetPitch());
1783        glMultMatrixf((float *)rotZ.x);
1784
1785        Vector3 pos = camera->GetPosition();
1786        glTranslatef(-pos.x, -pos.y, -pos.z);
1787
1788
1789        GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
1790        glLightfv(GL_LIGHT0, GL_POSITION, position);
1791
1792        GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
1793        glLightfv(GL_LIGHT1, GL_POSITION, position1);
1794
1795        glClear(GL_DEPTH_BUFFER_BIT);
1796
1797
1798        ////////////
1799        //-- visualization of the occlusion culling
1800
1801        visualization->Render();
1802       
1803       
1804        // reset previous settings
1805        glPopAttrib();
1806
1807        glMatrixMode(GL_PROJECTION);
1808        glPopMatrix();
1809        glMatrixMode(GL_MODELVIEW);
1810        glPopMatrix();
1811}
1812
1813
1814// cleanup routine after the main loop
1815void CleanUp()
1816{
1817        DEL_PTR(traverser);
1818        DEL_PTR(sceneQuery);
1819        DEL_PTR(bvh);
1820        DEL_PTR(visualization);
1821        DEL_PTR(camera);
1822        DEL_PTR(loader);
1823        DEL_PTR(renderQueue);
1824        DEL_PTR(perfGraph);
1825
1826        if (sCgMrtVertexProgram)
1827                cgDestroyProgram(sCgMrtVertexProgram);
1828        if (RenderState::sCgMrtFragmentProgram)
1829                cgDestroyProgram(RenderState::sCgMrtFragmentProgram);
1830        if (RenderState::sCgMrtFragmentTexProgram)
1831                cgDestroyProgram(RenderState::sCgMrtFragmentTexProgram);
1832        if (sCgSsaoProgram)
1833                cgDestroyProgram(sCgSsaoProgram);
1834        if (sCgDeferredProgram)
1835                cgDestroyProgram(sCgDeferredProgram);
1836        if (sCgContext)
1837                cgDestroyContext(sCgContext);
1838
1839        glDeleteFramebuffersEXT(1, &fbo);
1840        glDeleteRenderbuffersEXT(1, &depthBuffer);
1841        glDeleteRenderbuffersEXT(1, &colorsBuffer);
1842        glDeleteRenderbuffersEXT(1, &normalsBuffer);
1843        glDeleteRenderbuffersEXT(1, &positionsBuffer);
1844
1845        glDeleteTextures(1, &colorsTex);
1846        glDeleteTextures(1, &normalsTex);
1847        glDeleteTextures(1, &positionsTex);
1848        glDeleteTextures(1, &noiseTex);
1849        glDeleteTextures(1, &fontTex);
1850}
1851
1852
1853// this function inserts a dezimal point after each 1000
1854void CalcDecimalPoint(string &str, int d, int len)
1855{
1856        static vector<int> numbers;
1857        numbers.clear();
1858
1859        static string shortStr;
1860        shortStr.clear();
1861
1862        static char hstr[100];
1863
1864        while (d != 0)
1865        {
1866                numbers.push_back(d % 1000);
1867                d /= 1000;
1868        }
1869
1870        // first element without leading zeros
1871        if (numbers.size() > 0)
1872        {
1873                sprintf(hstr, "%d", numbers.back());
1874                shortStr.append(hstr);
1875        }
1876       
1877        for (int i = (int)numbers.size() - 2; i >= 0; i--)
1878        {
1879                sprintf(hstr, ",%03d", numbers[i]);
1880                shortStr.append(hstr);
1881        }
1882
1883        int dif = len - (int)shortStr.size();
1884
1885        for (int i = 0; i < dif; ++ i)
1886        {
1887                str += " ";
1888        }
1889
1890        str.append(shortStr);
1891}
1892
1893
1894void DisplayStats()
1895{
1896        static char msg[9][300];
1897
1898        static double frameTime = elapsedTime;
1899        static double renderTime = algTime;
1900
1901        const float expFactor = 0.1f;
1902
1903        // if some strange render time spike happened in this frame => don't count
1904        if (elapsedTime < 500) frameTime = elapsedTime * expFactor + (1.0f - expFactor) * elapsedTime;
1905       
1906        static float rTime = 1000.0f;
1907
1908        if (showAlgorithmTime)
1909        {
1910                if (algTime < 500) renderTime = algTime * expFactor + (1.0f - expFactor) * renderTime;
1911        }
1912
1913        accumulatedTime += elapsedTime;
1914
1915        if (accumulatedTime > 500) // update every fraction of a second
1916        {       
1917                accumulatedTime = 0;
1918
1919                if (frameTime) fps = 1e3f / (float)frameTime;
1920
1921                rTime = renderTime;
1922                renderedObjects = traverser->GetStats().mNumRenderedGeometry;
1923                renderedNodes = traverser->GetStats().mNumRenderedNodes;
1924                renderedTriangles = traverser->GetStats().mNumRenderedTriangles;
1925
1926                traversedNodes = traverser->GetStats().mNumTraversedNodes;
1927                frustumCulledNodes = traverser->GetStats().mNumFrustumCulledNodes;
1928                queryCulledNodes = traverser->GetStats().mNumQueryCulledNodes;
1929                issuedQueries = traverser->GetStats().mNumIssuedQueries;
1930                stateChanges = traverser->GetStats().mNumStateChanges;
1931                numBatches = traverser->GetStats().mNumBatches;
1932        }
1933
1934
1935        Begin2D();
1936
1937        glEnable(GL_BLEND);
1938        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1939
1940        if (showHelp)
1941        {       
1942                DrawHelpMessage();
1943        }
1944        else
1945        {
1946                if (showOptions)
1947                {
1948                        glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
1949                        glRecti(5, winHeight - 95, winWidth * 2 / 3 - 5, winHeight - 5);
1950                }
1951
1952                if (showStatistics)
1953                {
1954                        glColor4f(0.0f, 0.0f, 0.0f, 0.5f);
1955                        glRecti(5, winHeight - 165, winWidth * 2 / 3 - 5, winHeight - 100);
1956                }
1957
1958                glEnable(GL_TEXTURE_2D);
1959
1960                myfont.Begin();
1961
1962                if (showOptions)
1963                {
1964                        glColor3f(0.0f, 1.0f, 0.0f);
1965
1966                        int i = 0;
1967
1968                        static char *renderTypeStr[] = {"fixed function", "fixed function + depth pass", "deferred shading"};
1969       
1970                        sprintf(msg[i ++], "multiqueries: %d, tight bounds: %d, render queue: %d",
1971                                                        useMultiQueries, useTightBounds, useRenderQueue);
1972
1973                        sprintf(msg[i ++], "render technique: %s, SSAO: %d", renderTypeStr[renderType], useSsao);
1974
1975                        sprintf(msg[i ++], "triangles per virtual leaf: %5d", trianglesPerVirtualLeaf);
1976
1977                        sprintf(msg[i ++], "assumed visible frames: %4d, max batch size: %4d",
1978                                assumedVisibleFrames, maxBatchSize);
1979
1980                        for (int j = 0; j < 4; ++ j)
1981                                myfont.DrawString(msg[j], 10.0f, winHeight - 5 - j * 20);
1982                }
1983
1984                if (showStatistics)
1985                {
1986                        glColor3f(1.0f, 1.0f, 0.0f);
1987
1988                        string str;
1989                        string str2;
1990
1991                        int len = 10;
1992                        CalcDecimalPoint(str, renderedTriangles, len);
1993                        CalcDecimalPoint(str2, bvh->GetBvhStats().mTriangles, len);
1994
1995                        int i = 4;
1996
1997                        sprintf(msg[i ++], "rendered: %6d of %6d nodes, %s of %s triangles",
1998                                renderedNodes, bvh->GetNumVirtualNodes(), str.c_str(), str2.c_str());
1999
2000                        sprintf(msg[i ++], "traversed: %5d, frustum culled: %5d, query culled: %5d",
2001                                traversedNodes, frustumCulledNodes, queryCulledNodes);
2002
2003                        sprintf(msg[i ++], "issued queries: %5d, state changes: %5d, render batches: %5d",
2004                                issuedQueries, stateChanges, numBatches);
2005
2006                        for (int j = 4; j < 7; ++ j)
2007                                myfont.DrawString(msg[j], 10.0f, winHeight - (j + 1) * 20);
2008                }
2009
2010                glColor3f(1.0f, 1.0f, 1.0f);
2011                static char *alg_str[] = {"Frustum Cull", "Stop and Wait", "CHC", "CHC ++"};
2012               
2013                if (!showAlgorithmTime)
2014                {
2015                        sprintf(msg[7], "%s:  %6.1f fps", alg_str[renderMode], fps);
2016                }
2017                else
2018                {
2019                        sprintf(msg[7], "%s:  %6.1f ms", alg_str[renderMode], rTime);
2020                }
2021
2022                myfont.DrawString(msg[7], 1.3f, 690.0f, 760.0f);//, top_color, bottom_color);
2023               
2024                //sprintf(msg[8], "algorithm time: %6.1f ms", rTime);
2025                //myfont.DrawString(msg[8], 720.0f, 730.0f);           
2026        }
2027
2028        glDisable(GL_BLEND);
2029        glDisable(GL_TEXTURE_2D);
2030
2031        End2D();
2032}       
2033
2034
2035void RenderSky()
2036{
2037        SceneEntityContainer::const_iterator sit, sit_end = skyGeometry.end();
2038
2039        for (sit = skyGeometry.begin(); sit != sit_end; ++ sit)
2040                (*sit)->Render(&state);
2041}
2042
2043
2044void RenderVisibleObjects()
2045{
2046        state.SetRenderType(RenderState::FIXED);
2047        state.Reset();
2048
2049        glEnable(GL_LIGHTING);
2050        glDepthFunc(GL_LEQUAL);
2051
2052        //cout << "visible: " << (int)traverser->GetVisibleObjects().size() << endl;
2053
2054        SceneEntityContainer::const_iterator sit,
2055                sit_end = traverser->GetVisibleObjects().end();
2056
2057        for (sit = traverser->GetVisibleObjects().begin(); sit != sit_end; ++ sit)
2058                renderQueue->Enqueue(*sit);
2059               
2060        renderQueue->Apply();
2061
2062        glDepthFunc(GL_LESS);
2063}
2064
2065
2066void PlaceViewer(const Vector3 &oldPos)
2067{
2068        Vector3 playerPos = camera->GetPosition();
2069
2070        bool validIntersect = sceneQuery->CalcIntersection(playerPos);
2071
2072        if (validIntersect)
2073                // && ((playerPos.z - oldPos.z) < bvh->GetBox().Size(2) * 1e-1f))
2074        {
2075                camera->SetPosition(playerPos);
2076        }
2077}
2078
2079
2080void DisplayRenderTexture3()
2081{
2082        glEnable(GL_TEXTURE_2D);
2083
2084        if (isFirstTexture)
2085                glBindTexture(GL_TEXTURE_2D, colorsTex1);
2086        else
2087                glBindTexture(GL_TEXTURE_2D, colorsTex2);
2088
2089        glDisable(GL_LIGHTING);
2090       
2091        glMatrixMode(GL_PROJECTION);
2092        glPushMatrix();
2093        glLoadIdentity();
2094
2095        glMatrixMode(GL_MODELVIEW);
2096        glPushMatrix();
2097        glLoadIdentity();
2098
2099        const float offs = 0.5f;
2100        glOrtho(-offs, offs, -offs, offs, 0, 1);
2101       
2102        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2103
2104        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
2105        glBegin(GL_QUADS);
2106
2107        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
2108        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
2109        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
2110        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
2111
2112        glEnd();
2113
2114        glEnable(GL_LIGHTING);
2115        glDisable(GL_TEXTURE_2D);
2116       
2117        glMatrixMode(GL_PROJECTION);
2118        glPopMatrix();
2119
2120        glMatrixMode(GL_MODELVIEW);
2121        glPopMatrix();
2122
2123        PrintGLerror("displaytexture3");
2124}
2125
2126
2127void DisplayRenderTexture()
2128{
2129        GLuint oldTex;
2130
2131        if (isFirstTexture)
2132        {
2133                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo1);
2134                oldTex = colorsTex2;
2135        }
2136        else
2137        {
2138                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
2139                oldTex = colorsTex1;
2140        }
2141
2142        glPushAttrib(GL_VIEWPORT_BIT);
2143        glViewport(0, 0, texWidth, texHeight);
2144
2145        glDrawBuffers(1, mrt);
2146
2147        glDisable(GL_ALPHA_TEST);
2148        glDisable(GL_TEXTURE_2D);
2149        glDisable(GL_LIGHTING);
2150       
2151        glMatrixMode(GL_PROJECTION);
2152        glPushMatrix();
2153        glLoadIdentity();
2154
2155        glMatrixMode(GL_MODELVIEW);
2156        glPushMatrix();
2157        glLoadIdentity();
2158
2159        const float offs = 0.5f;
2160       
2161        glOrtho(-offs, offs, -offs, offs, 0, 1);
2162       
2163        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2164
2165        cgGLEnableProfile(RenderState::sCgFragmentProfile);
2166
2167        if (useSsao)
2168        {
2169                cgGLBindProgram(sCgSsaoProgram);
2170               
2171                cgGLSetTextureParameter(sPositionsTexParamSsao, positionsTex);
2172                cgGLEnableTextureParameter(sPositionsTexParamSsao);
2173
2174                cgGLSetTextureParameter(sColorsTexParamSsao, colorsTex);
2175                cgGLEnableTextureParameter(sColorsTexParamSsao);
2176
2177                cgGLSetTextureParameter(sNormalsTexParamSsao, normalsTex);
2178                cgGLEnableTextureParameter(sNormalsTexParamSsao);
2179
2180                cgGLSetTextureParameter(sNoiseTexParamSsao, noiseTex);
2181                cgGLEnableTextureParameter(sNoiseTexParamSsao);
2182
2183                cgGLSetTextureParameter(sOldTexParamSsao, oldTex);
2184                cgGLEnableTextureParameter(sOldTexParamSsao);
2185
2186                cgGLSetParameter1f(sNoiseMultiplierParam, RandomValue(3.0f, 17.0f));
2187                cgGLSetParameter1f(sExpFactorParamSsao, expFactor);
2188
2189                GenerateSamples(); cgGLSetParameterArray2f(sSamplesParamSsao, 0, NUM_SAMPLES, (const float *)samples);
2190        }
2191        else
2192        {
2193                cgGLBindProgram(sCgDeferredProgram);
2194
2195                cgGLSetTextureParameter(sPositionsTexParam, positionsTex);
2196                cgGLEnableTextureParameter(sPositionsTexParam);
2197
2198                cgGLSetTextureParameter(sColorsTexParam, colorsTex);
2199                cgGLEnableTextureParameter(sColorsTexParam);
2200
2201                cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
2202                cgGLEnableTextureParameter(sNormalsTexParam);
2203        }
2204
2205        Vector3 tl, tr, bl, br;
2206        ComputeViewVectors(tl, tr, bl, br);
2207
2208        glColor3f(1.0f, 1.0f, 1.0f);
2209
2210        glBegin(GL_QUADS);
2211
2212        // note: slightly larger texture hides ambient occlusion error on border but costs resolution
2213        //float offs2 = 0.55f;
2214        float offs2 = 0.5f;
2215
2216        glColor3f(bl.x, bl.y, bl.z); glTexCoord2f(0, 0); glVertex3f(-offs2, -offs2, -0.5f);
2217        glColor3f(br.x, br.y, br.z); glTexCoord2f(1, 0); glVertex3f( offs2, -offs2, -0.5f);
2218        glColor3f(tr.x, tr.y, tr.z); glTexCoord2f(1, 1); glVertex3f( offs2,  offs2, -0.5f);
2219        glColor3f(tl.x, tl.y, tl.z); glTexCoord2f(0, 1); glVertex3f(-offs2,  offs2, -0.5f);
2220
2221        glEnd();
2222
2223       
2224        if (useSsao)
2225        {
2226                cgGLDisableTextureParameter(sColorsTexParamSsao);
2227                cgGLDisableTextureParameter(sPositionsTexParamSsao);
2228                cgGLDisableTextureParameter(sNormalsTexParamSsao);
2229                cgGLDisableTextureParameter(sNoiseTexParamSsao);
2230                cgGLDisableTextureParameter(sOldTexParamSsao);
2231        }
2232        else
2233        {
2234                cgGLDisableTextureParameter(sColorsTexParam);
2235                cgGLDisableTextureParameter(sPositionsTexParam);
2236                cgGLDisableTextureParameter(sNormalsTexParam);
2237        }
2238
2239        cgGLDisableProfile(RenderState::sCgFragmentProfile);
2240       
2241        glEnable(GL_LIGHTING);
2242        glDisable(GL_TEXTURE_2D);
2243       
2244        glMatrixMode(GL_PROJECTION);
2245        glPopMatrix();
2246
2247        glMatrixMode(GL_MODELVIEW);
2248        glPopMatrix();
2249
2250        glPopAttrib();
2251
2252        PrintGLerror("displaytexture");
2253
2254        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
2255
2256        DisplayRenderTexture3();
2257}
2258
2259#if 0
2260// kustls magic sample positions
2261void GenerateSamples()
2262{
2263        static const float mysamples[] =
2264        {
2265                -0.326212f, -0.405805f,
2266                -0.840144f, -0.07358f,
2267                -0.695914f, 0.457137f,
2268                -0.203345f, 0.620716,
2269                0.96234f, -0.194983f,
2270                0.473434f, -0.480026f,
2271                0.519456, 0.767022f,
2272                0.185461f, -0.893124f,
2273                0.507431f, 0.064425f,
2274                0.89642f, 0.412458f,
2275                -0.32194f, -0.932615f,
2276                -0.791559f, -0.597705f,
2277                0.326212f, 0.405805f,
2278                0.840144f, 0.07358f,
2279                0.695914f, -0.457137f,
2280                0.203345f, -0.620716,
2281                -0.96234f, 0.194983f,
2282                -0.473434f, 0.480026f,
2283                -0.519456, -0.767022f,
2284                -0.185461f, 0.893124f,
2285                -0.507431f, -0.064425f,
2286                -0.89642f, -0.412458f,
2287                0.32194f, 0.932615f,
2288                0.791559f, 0.597705f
2289        };
2290
2291        for (int i = 0; i < NUM_SAMPLES; ++ i)
2292        {
2293                samples[i] = mysamples[i];
2294        }
2295}
2296
2297#else
2298
2299
2300void GenerateSamples()
2301{
2302        /*static HaltonSequence halton;
2303
2304        float r[2];
2305
2306        // generates poisson distribution on disc
2307        float minDist = 2.0f / sqrt((float)NUM_SAMPLES);
2308
2309        //cout << "minDist before= " << minDist << endl;
2310
2311        for (int i = 0; i < NUM_SAMPLES * 2; i += 2)
2312        {
2313                int tries = 0, totalTries = 0;
2314
2315                // repeat until valid sample was found
2316                while (1)
2317                {
2318                        ++ tries;
2319                        ++ totalTries;
2320
2321                        halton.GetNext(2, r);
2322
2323                        //const float rx = RandomValue(-1, 1);
2324                        //const float ry = RandomValue(-1, 1);
2325
2326                        const float rx = r[0] * 2.0f - 1.0f;
2327                        const float ry = r[1] * 2.0f - 1.0f;
2328
2329                        // check if in disk, else exit early
2330                        if (rx * rx + ry * ry > 1)
2331                                continue;
2332
2333                        bool sampleValid = true;
2334
2335                        // check poisson property
2336                        for (int j = 0; ((j < i) && sampleValid); j += 2)
2337                        {
2338                                const float dist =
2339                                        sqrt((samples[j] - rx) * (samples[j] - rx) +
2340                                             (samples[j + 1] - ry) * (samples[j + 1] - ry));
2341                       
2342                                if (dist < minDist)
2343                                        sampleValid = false;
2344                        }
2345
2346                        if (sampleValid)
2347                        {
2348                                samples[i] = rx;
2349                                samples[i + 1]= ry;
2350                                break;
2351                        }
2352
2353                        if (tries > 2000)
2354                        {
2355                                minDist *= 0.9f;
2356                                tries = 0;
2357                        }
2358                }
2359        }
2360*/
2361
2362        static PoissonDiscSampleGenerator poisson(NUM_SAMPLES, 1.0f);
2363        poisson.Generate((Sample2 *)samples);
2364}
2365
2366
2367#endif
2368
2369
2370void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
2371{
2372        float myfov = fov * M_PI / 180.0f;
2373
2374        const float w_far = 2.0f * tan(myfov / 2.0f);
2375        const float aspect = texWidth / texHeight;
2376
2377        const float h_far = w_far / aspect;
2378
2379        float t1 = h_far * 0.5f;
2380        float t2 = w_far * 0.5f;
2381
2382#if 0
2383        bl = Normalize(-Vector3(-t1, -t2, 1.0f));
2384        br = Normalize(-Vector3( t1, -t2, 1.0f));
2385        tl = Normalize(-Vector3(-t1,  t2, 1.0f));
2386        tr = Normalize(-Vector3( t1,  t2, 1.0f));
2387#else
2388        bl = -Normalize(camera->GetDirection());
2389        br = -Normalize(camera->GetDirection());
2390        tl = -Normalize(camera->GetDirection());
2391        tr = -Normalize(camera->GetDirection());
2392#endif
2393        // normalize to 0 .. 1
2394        bl = bl * 0.5f + 0.5f;
2395        br = br * 0.5f + 0.5f;
2396        tl = tl * 0.5f + 0.5f;
2397        tr = tr * 0.5f + 0.5f;
2398}
2399
2400
2401void CreateNoiseTex2D()
2402{
2403        randomNormals = new GLubyte[texWidth * texHeight * 3];
2404
2405        for (int i = 0; i < texWidth * texHeight * 3; i += 3)
2406        {
2407                // create random samples over sphere
2408                const float rx = RandomValue(0, 1);
2409                const float theta = 2.0f * acos(sqrt(1.0f - rx));
2410
2411                randomNormals[i + 0] = (GLubyte)((cos(theta) * 0.5f + 0.5f) * 255.0f);
2412                randomNormals[i + 1] = (GLubyte)((sin(theta) * 0.5f + 0.5f) * 255.0f);
2413                randomNormals[i + 2] = 0;
2414        }
2415
2416        glEnable(GL_TEXTURE_2D);
2417        glGenTextures(1, &noiseTex);
2418        glBindTexture(GL_TEXTURE_2D, noiseTex);
2419               
2420        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2421        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2422        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2423        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2424
2425        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, randomNormals);
2426        //gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, texWidth, texHeight, GL_RGB, GL_UNSIGNED_BYTE, randomNormals);
2427
2428        glBindTexture(GL_TEXTURE_2D, 0);
2429        glDisable(GL_TEXTURE_2D);
2430
2431        cout << "created noise texture" << endl;
2432        PrintGLerror("noisetexture");
2433}
Note: See TracBrowser for help on using the repository browser.