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

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