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

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