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

Revision 2809, 41.4 KB checked in by mattausch, 16 years ago (diff)

working on ssao deferred shading approach (debug version!!)

Line 
1// occquery.cpp : Defines the entry point for the console application.
2//
3#include <math.h>
4#include <time.h>
5#include "common.h"
6#include "glInterface.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 <Cg/cg.h>
26#include <Cg/cgGL.h>
27
28
29
30using namespace std;
31using namespace CHCDemoEngine;
32
33
34GLuint fbo;
35GLuint depthbuffer;
36GLuint colorbuffer;
37GLuint colorbuffer2;
38GLuint depthTex;
39GLuint colorTex;
40GLuint colorTex2;
41
42GLuint normalTex;
43
44GLuint fbo2;
45GLuint occlusionbuffer;
46GLuint occlusionTex;
47
48int texWidth2 = 512;
49int texHeight2 = 512;
50
51/// the renderable scene geometry
52SceneEntityContainer sceneEntities;
53// traverses and renders the hierarchy
54RenderTraverser *traverser = NULL;
55/// the hierarchy
56Bvh *bvh = NULL;
57/// handles scene loading
58ResourceManager *loader = NULL;
59/// the scene camera
60Camera *camera = NULL;
61/// the scene camera
62Camera *visCamera = NULL;
63/// the visualization
64Visualization *visualization = NULL;
65/// the current render state
66RenderState state;
67/// the rendering algorithm
68int renderMode = RenderTraverser::CHCPLUSPLUS;
69// eye near plane distance
70float nearDist = 0.1f;
71/// the pixel threshold where a node is still considered invisible
72int threshold;
73
74float fov = 50.0f;
75
76int assumedVisibleFrames = 10;
77int maxBatchSize = 50;
78
79int trianglesPerVirtualLeaf = INITIAL_TRIANGLES_PER_VIRTUAL_LEAVES;
80
81SceneQuery *sceneQuery = NULL;
82RenderQueue *renderQueue = NULL;
83
84/// these values get scaled with the frame rate
85const static float keyForwardMotion = 50.0f;
86const static float keyRotation = 2.0f;
87
88/// elapsed time in seconds
89double elapsedTime = 1.0f;
90double algTime = 1.0f;
91
92static int winWidth = 1024;
93static int winHeight = 768;
94static float winAspectRatio = 1.0f;
95
96double accumulatedTime = 1000;
97float fps = 1e3f;
98
99float myfar = 0;
100
101// rendertexture
102const static int texWidth = 2048;
103const static int texHeight = 2048;
104
105int renderedObjects = 0;
106int renderedNodes = 0;
107int renderedTriangles = 0;
108
109int issuedQueries = 0;
110int traversedNodes = 0;
111int frustumCulledNodes = 0;
112int queryCulledNodes = 0;
113int stateChanges = 0;
114int numBatches = 0;
115
116bool showHelp = false;
117bool showStatistics = true;
118bool showOptions = true;
119bool showBoundingVolumes = false;
120bool visMode = false;
121
122// mouse navigation state
123int xEyeBegin = 0;
124int yEyeBegin = 0;
125int yMotionBegin = 0;
126int verticalMotionBegin = 0;
127int horizontalMotionBegin = 0;
128
129bool useOptimization = false;
130bool useTightBounds = true;
131bool useRenderQueue = true;
132bool useMultiQueries = true;
133bool flyMode = true;
134bool depthPass = false;
135bool useGlFinish = false;
136
137SceneEntityContainer skyGeometry;
138
139bool leftKeyPressed = false;
140bool rightKeyPressed = false;
141bool upKeyPressed = false;
142bool downKeyPressed = false;
143bool nineKeyPressed = false;
144bool eightKeyPressed = false;
145
146
147static Vector3 samples[32];
148
149
150// function forward declarations
151void InitExtensions();
152void DisplayVisualization();
153void InitGLstate();
154void InitRenderTexture();
155void InitCg();
156void CleanUp();
157void SetupEyeView();
158void UpdateEyeMtx();
159void SetupLighting();
160void DisplayStats();
161void Output(int x, int y, const char *string);
162void DrawHelpMessage();
163void RenderSky();
164void RenderVisibleObjects();
165
166void Begin2D();
167void End2D();
168void KeyBoard(unsigned char c, int x, int y);
169void DrawStatistics();
170void Display();
171void Special(int c, int x, int y);
172void KeyUp(unsigned char c, int x, int y);
173void SpecialKeyUp(int c, int x, int y);
174void Reshape(int w, int h);
175void Mouse(int button, int state, int x, int y);
176void LeftMotion(int x, int y);
177void RightMotion(int x, int y);
178void MiddleMotion(int x, int y);
179void CalcDecimalPoint(string &str, int d);
180void ResetTraverser();
181
182void KeyHorizontalMotion(float shift);
183void KeyVerticalMotion(float shift);
184
185void PlaceViewer(const Vector3 &oldPos);
186void DisplayRenderTexture();
187
188
189inline float KeyRotationAngle() { return keyRotation * elapsedTime; }
190inline float KeyShift() { return keyForwardMotion * elapsedTime; }
191
192void InitFBO();
193
194void GenerateSamples();
195
196void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br);
197
198GLenum mrt[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
199
200
201// cg stuff
202static CGcontext sCgContext = NULL;
203static CGprogram sCgLinearDepthProgram = NULL;
204static CGprogram sCgSSAOProgram = NULL;
205static CGprogram sCgTestProgram = NULL;
206
207static CGprofile sCgFragmentProfile;
208static CGprofile sCgVertexProfile;
209
210static CGparameter sTextureParam;
211static CGparameter sSceneTextureParam;
212static CGparameter sNormalTextureParam;
213
214static CGparameter sTexSizeParam;
215static CGparameter sSamplesParam;
216static CGparameter sEyeVecParam;
217static CGparameter sRadiusParam;
218
219//static CGparameter sPositionParam;
220static CGparameter sModelViewMatrixParam;       
221static CGparameter sMaxDepthParam;
222
223const static float radius = 1e-3f;
224
225
226static void cgErrorCallback()
227{
228        CGerror lastError = cgGetError();
229
230        if(lastError)
231        {
232                printf("%s\n\n", cgGetErrorString(lastError));
233                printf("%s\n", cgGetLastListing(sCgContext));
234                printf("Cg error, exiting...\n");
235
236                exit(0);
237        }
238}
239
240
241static void PrintGLerror(char *msg)
242{
243        GLenum errCode;
244        const GLubyte *errStr;
245       
246        if ((errCode = glGetError()) != GL_NO_ERROR)
247        {
248                errStr = gluErrorString(errCode);
249                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
250        }
251}
252
253
254int main(int argc, char* argv[])
255{
256        int returnCode = 0;
257
258        camera = new Camera(winWidth, winHeight, fov);
259        camera->SetNear(nearDist);
260       
261        visCamera = new Camera(winWidth, winHeight, fov);
262
263        visCamera->SetNear(0.0f);
264        visCamera->Yaw(.5 * M_PI);
265
266        renderQueue = new RenderQueue(&state, camera);
267
268        glutInitWindowSize(winWidth, winHeight);
269        glutInit(&argc, argv);
270        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
271
272        glutCreateWindow("FriendlyCulling");
273
274        glutDisplayFunc(Display);
275        glutKeyboardFunc(KeyBoard);
276        glutSpecialFunc(Special);
277        glutReshapeFunc(Reshape);
278        glutMouseFunc(Mouse);
279        glutIdleFunc(Display);
280        glutKeyboardUpFunc(KeyUp);
281        glutSpecialUpFunc(SpecialKeyUp);
282        glutIgnoreKeyRepeat(true);
283
284        InitExtensions();
285        InitGLstate();
286        //InitRenderTexture();
287        InitFBO();
288
289        LeftMotion(0, 0);
290        MiddleMotion(0, 0);
291
292
293        loader = new ResourceManager();
294
295        //const string filename("data/city/model/city.dem");
296        const string filename = string(model_path + "city.dem");
297
298        if (loader->Load(filename, sceneEntities))
299                cout << "scene " << filename << " loaded" << endl;
300        else
301        {
302                cerr << "loading scene " << filename << " failed" << endl;
303                CleanUp();
304                exit(0);
305        }
306
307        SceneEntityContainer dummy;
308
309        const string envname = string(model_path + "env.dem");
310
311        if (loader->Load(envname, skyGeometry))
312                cout << "sky box " << filename << " loaded" << endl;
313        else
314        {
315                cerr << "loading sky box " << filename << " failed" << endl;
316                CleanUp();
317                exit(0);
318        }
319
320
321        const string bvh_filename = string(model_path + "city.bvh");
322        BvhLoader bvhLoader;
323        bvh = bvhLoader.Load(bvh_filename, sceneEntities);
324        //bvh = bvhLoader.Load("data/city/model/city.bvh", sceneEntities);
325
326        myfar = 10.0f * Magnitude(bvh->GetBox().Diagonal());
327
328        if (!bvh)
329        {
330                cerr << "loading bvh " << bvh_filename << " failed" << endl;
331                CleanUp();
332                exit(0);
333        }
334
335        InitCg();
336
337        bvh->SetCamera(camera);
338
339        ResetTraverser();
340
341        camera->Pitch(-M_PI * 0.5);
342        camera->SetPosition(Vector3(483.398f, 242.364f, 186.078f));
343
344        visualization = new Visualization(bvh, camera, NULL, &state);
345
346        sceneQuery = new SceneQuery(bvh->GetBox(), traverser);
347
348
349        glutMainLoop();
350
351        // clean up
352        CleanUp();
353
354        return 0;
355}
356
357
358void InitCg(void)
359{
360        GenerateSamples();
361
362        // Setup Cg
363        cgSetErrorCallback(cgErrorCallback);
364
365        // Create cgContext.
366        sCgContext = cgCreateContext();
367
368        // get the best profile for this hardware
369        sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
370        //assert(sCgFragmentProfile != CG_PROFILE_UNKNOWN);
371        cgGLSetOptimalOptions(sCgFragmentProfile);
372
373        sCgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
374        cgGLSetOptimalOptions(sCgVertexProfile);
375
376        sCgLinearDepthProgram =
377                cgCreateProgramFromFile(sCgContext,
378                                                                CG_SOURCE,
379                                                                "src/lineardepth.cg",
380                                                                sCgVertexProfile,
381                                                                "main",
382                                                                NULL);
383
384        if(sCgLinearDepthProgram != NULL)
385        {
386                cgGLLoadProgram(sCgLinearDepthProgram);
387       
388                sModelViewMatrixParam = cgGetNamedParameter(sCgLinearDepthProgram, "ModelViewProj");
389        }
390
391        sCgTestProgram =
392                cgCreateProgramFromFile(sCgContext,
393                                                                CG_SOURCE,
394                                                                "src/test2.cg",
395                                                                sCgFragmentProfile,
396                                                                "main",
397                                                                NULL);
398
399        if(sCgTestProgram != NULL)
400        {
401                cgGLLoadProgram(sCgTestProgram);
402
403                sMaxDepthParam = cgGetNamedParameter(sCgTestProgram, "maxDepth");
404                cgGLSetParameter1f(sMaxDepthParam, 1.0f / myfar);
405        }
406        else
407                cerr << "test program failed to load" << endl;
408
409        PrintGLerror("test");
410
411
412        ///////////////
413
414        sCgSSAOProgram =
415                cgCreateProgramFromFile(sCgContext,
416                                                                CG_SOURCE,
417                                                                "src/ssao.cg",
418                                                                //"src/test.cg",
419                                                                sCgFragmentProfile,
420                                                                NULL,
421                                                                NULL);
422
423        if(sCgSSAOProgram != NULL)
424        {
425                cgGLLoadProgram(sCgSSAOProgram);
426
427                // we need size of texture for scaling
428                sTextureParam = cgGetNamedParameter(sCgSSAOProgram, "lindepth"); 
429                sSceneTextureParam = cgGetNamedParameter(sCgSSAOProgram, "scene"); 
430                sNormalTextureParam = cgGetNamedParameter(sCgSSAOProgram, "normal"); 
431                sTexSizeParam = cgGetNamedParameter(sCgSSAOProgram, "invTexSize");
432                sRadiusParam = cgGetNamedParameter(sCgSSAOProgram, "radius");
433                sEyeVecParam = cgGetNamedParameter(sCgSSAOProgram, "eyevec");
434                sSamplesParam = cgGetNamedParameter(sCgSSAOProgram, "samples");
435
436                cgGLSetParameter1f(sTexSizeParam, 1.0f / (float)texWidth);
437                cgGLSetParameter1f(sRadiusParam, radius);
438                cgGLSetParameterArray3f(sSamplesParam, 0, 32, (const float *)samples);
439        }
440        else
441                cerr << "ssao program failed to load" << endl;
442
443        PrintGLerror("init");
444}
445
446
447void PrintFBOStatus(GLenum status)
448{
449        switch(status)
450        {
451        case GL_FRAMEBUFFER_COMPLETE_EXT:
452                cout << "frame buffer object created successfully" << endl;
453                break;
454        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
455                cerr << "incomplete attachment" << endl;
456                break;
457        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
458                cerr << "missing attachment" << endl;
459                break;
460        case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
461                cerr << "incomplete dimensions" << endl;
462                break;
463        case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
464                cerr << "incomplete formats" << endl;
465                break;
466        case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
467                cerr << "incomplete draw buffer" << endl;
468                break;
469        case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
470                cerr << "incomplete read buffer" << endl;
471                break;
472        case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
473                cerr << "framebuffer unsupported" << endl;
474                break;
475        default:
476                cerr << "unknown status code " << status << endl;
477        }
478}
479
480
481void InitFBO()
482{       
483        glGenFramebuffersEXT(1, &fbo);
484        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
485
486        // create color buffer
487        int samples = 8;
488
489        glGenRenderbuffersEXT(1, &colorbuffer);
490        //glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA16F_ARB, texWidth, texHeight);
491        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_FLOAT_RGBA_NV, texWidth, texHeight);
492        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorbuffer);
493        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, colorbuffer);
494
495        glGenTextures(1, &colorTex);
496        glBindTexture(GL_TEXTURE_2D, colorTex);
497        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB,  texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
498        glGenerateMipmapEXT(GL_TEXTURE_2D);
499        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorTex, 0);
500
501        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
502        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
503
504        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
505        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
506
507        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
508
509
510        glGenRenderbuffersEXT(1, &colorbuffer2);
511        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA16F_ARB, texWidth, texHeight);
512        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorbuffer2);
513        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER_EXT, colorbuffer2);
514
515        glGenTextures(1, &colorTex2);
516        glBindTexture(GL_TEXTURE_2D, colorTex2);
517        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB,  texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
518        glGenerateMipmapEXT(GL_TEXTURE_2D);
519        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, colorTex2, 0);
520
521        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
522        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
523
524        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
525        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
526
527        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
528
529        ///////////
530        // create depth buffer
531
532        glGenRenderbuffersEXT(1, &depthbuffer);
533        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthbuffer);
534        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, texWidth, texHeight);
535        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthbuffer);
536
537       
538        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
539       
540        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
541
542
543        ////////////////
544        //-- second fbo
545
546        /*glGenFramebuffersEXT(1, &fbo2);
547        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
548
549        // create color buffer
550        glGenRenderbuffersEXT(1, &occlusionbuffer);
551        //glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA16F_ARB, texWidth, texHeight);
552        glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, GL_FLOAT_RGBA_NV, texWidth2, texHeight2);
553        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, occlusionbuffer);
554        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, occlusionbuffer);
555
556        glGenTextures(1, &occlusionTex);
557        glBindTexture(GL_TEXTURE_2D, occlusionTex);
558        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB,  texWidth2, texHeight2, 0, GL_RGBA, GL_FLOAT, NULL);
559        glGenerateMipmapEXT(GL_TEXTURE_2D);
560        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorTex, 0);
561
562        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
563
564        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);*/
565}
566
567
568void InitGLstate(void)
569{
570        glClearColor(0.5f, 0.5f, 0.8f, 0.0f);
571       
572        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
573        glPixelStorei(GL_PACK_ALIGNMENT,1);
574       
575        glDepthFunc(GL_LESS);
576        glEnable(GL_DEPTH_TEST);
577
578        SetupLighting();
579
580        glColor3f(1.0f, 1.0f, 1.0f);
581        glShadeModel(GL_SMOOTH);
582       
583        glMaterialf(GL_FRONT, GL_SHININESS, 64);
584        glEnable(GL_NORMALIZE);
585               
586        //glEnable(GL_ALPHA_TEST);
587        glDisable(GL_ALPHA_TEST);
588        glAlphaFunc(GL_GEQUAL, 0.5f);
589
590        glFrontFace(GL_CCW);
591        glCullFace(GL_BACK);
592        glEnable(GL_CULL_FACE);
593        //glDisable(GL_CULL_FACE);
594        glDisable(GL_TEXTURE_2D);
595
596        GLfloat ambientColor[] = {0.5, 0.5, 0.5, 1.0};
597        GLfloat diffuseColor[] = {1.0, 0.0, 0.0, 1.0};
598        GLfloat specularColor[] = {0.0, 0.0, 0.0, 1.0};
599
600        glMaterialfv(GL_FRONT, GL_AMBIENT, ambientColor);
601        glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor);
602        glMaterialfv(GL_FRONT, GL_SPECULAR, specularColor);
603
604        glDepthFunc(GL_LESS);
605}
606
607
608void DrawHelpMessage(void)
609{
610        const char *message[] =
611        {
612                "Help information",
613                "",
614                "'F1'           - shows/dismisses this message",
615                "'F2'           - shows/hides bird eye view",
616                "'F3'           - shows/hides bounds (boxes or tight bounds)",
617                "'F4'           - shows/hides statistics",
618                "'F5',          - shows/hides parameters",
619                "'F6',          - toggles between fly / walkmode",
620                "'F7',          - depth pass",
621                "'F8',          - enable/disable glFinish for more accurate timings",
622                "'SPACE'        - cycles through occlusion culling algorithms",
623                "",
624                "'MOUSE-LEFT'   - turn left/right, move forward/backward",
625                "'MOUSE-RIGHT'  - turn left/right, move forward/backward",
626                "'MOUSE-MIDDLE' - move up/down, left/right",
627                "'CURSOR UP'    - move forward",
628                "'CURSOR BACK'  - move backward",
629                "'CURSOR RIGHT' - turn right",
630                "'CURSOR LEFT'  - turn left",
631                "",
632                "'-'            - decreases max batch size",
633                "'+'            - increases max batch size",
634                "'4'            - decrease triangles per virtual leaf (sets depth of bvh)",
635                "'5'            - increase triangles per virtual leaf (sets depth of bvh)",
636                "'6'            - decrease assumed visible frames",
637                "'7'            - increase assumed visible frames",
638                "'8'            - downward motion",
639                "'9'            - upward motion",
640                "",
641                "'R'            - use render queue",
642                "'B'            - use tight bounds",
643                "'M'            - use multiqueries",
644                "'O'            - use CHC optimization (geometry queries for leaves)",
645                0,
646        };
647       
648       
649        int x = 40, y = 60;
650
651        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
652        glEnable(GL_BLEND);
653        glColor4f(0.0f, 1.0f , 0.0f, 0.2f);  // 20% green.
654
655        // Drawn clockwise because the flipped Y axis flips CCW and CW.
656        glRecti(winWidth - 30, 30, 30, winHeight - 30);
657       
658        glDisable(GL_BLEND);
659       
660        glColor3f(1.0f, 1.0f, 1.0f);
661       
662        for(int i = 0; message[i] != 0; i++)
663        {
664                if(message[i][0] == '\0')
665                {
666                        y += 15;
667                }
668                else
669                {
670                        Output(x, y, message[i]);
671                        y += 20;
672                }
673        }
674}
675
676
677void ResetTraverser()
678{
679        DEL_PTR(traverser);
680
681        bvh->ResetNodeClassifications();
682
683        switch (renderMode)
684        {
685        case RenderTraverser::CULL_FRUSTUM:
686                traverser = new FrustumCullingTraverser();
687                break;
688        case RenderTraverser::STOP_AND_WAIT:
689                traverser = new StopAndWaitTraverser();
690                break;
691        case RenderTraverser::CHC:
692                traverser = new CHCTraverser();
693                break;
694        case RenderTraverser::CHCPLUSPLUS:
695                traverser = new CHCPlusPlusTraverser();
696                break;
697       
698        default:
699                traverser = new FrustumCullingTraverser();
700        }
701
702        traverser->SetCamera(camera);
703        traverser->SetHierarchy(bvh);
704        traverser->SetRenderQueue(renderQueue);
705        traverser->SetRenderState(&state);
706        traverser->SetUseOptimization(useOptimization);
707        traverser->SetUseRenderQueue(useRenderQueue);
708        traverser->SetVisibilityThreshold(threshold);
709        traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
710        traverser->SetMaxBatchSize(maxBatchSize);
711        traverser->SetUseMultiQueries(useMultiQueries);
712        traverser->SetUseTightBounds(useTightBounds);
713        traverser->SetUseDepthPass(depthPass);
714        traverser->SetRenderQueue(renderQueue);
715}
716
717
718void SetupLighting()
719{
720        glEnable(GL_LIGHTING);
721        glEnable(GL_LIGHT0);
722        //glEnable(GL_LIGHT1);
723        glDisable(GL_LIGHT1);
724
725        //GLfloat ambient[] = {0.5, 0.5, 0.5, 1.0};
726        GLfloat ambient[] = {0.2, 0.2, 0.2, 1.0};
727        GLfloat diffuse[] = {1.0, 1.0, 1.0, 1.0};
728        GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
729           
730        GLfloat lmodel_ambient[] = {0.5f, 0.5f, 0.5f, 1.0f};
731        //GLfloat lmodel_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f};
732
733        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
734        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
735        glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
736
737        GLfloat position[] = {1.0, 1.0, 1.0, 0.0};
738        glLightfv(GL_LIGHT0, GL_POSITION, position);
739
740
741        ////////////
742        //-- second light
743
744        GLfloat ambient1[] = {0.5, 0.5, 0.5, 1.0};
745        //GLfloat diffuse1[] = {1.0, 1.0, 1.0, 1.0};
746        GLfloat diffuse1[] = {0.5, 0.5, 0.5, 1.0};
747        GLfloat specular1[] = {0.5, 0.5, 0.5, 1.0};
748
749        glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1);
750        glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1);
751        glLightfv(GL_LIGHT1, GL_SPECULAR, specular1);
752       
753        GLfloat position1[] = {0.0, 1.0, 0.0, 1.0};
754        glLightfv(GL_LIGHT1, GL_POSITION, position1);
755
756        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
757        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
758        //glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
759        //glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SEPARATE_SPECULAR_COLOR_EXT);
760        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SINGLE_COLOR_EXT);
761}
762
763
764void SetupEyeView()
765{
766        glMatrixMode(GL_PROJECTION);
767        glLoadIdentity();
768
769        gluPerspective(fov, 1.0f / winAspectRatio, nearDist, myfar);
770
771        glMatrixMode(GL_MODELVIEW);
772        glLoadIdentity();
773        camera->SetupCameraView();
774
775        GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
776        glLightfv(GL_LIGHT0, GL_POSITION, position);
777
778        GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
779        glLightfv(GL_LIGHT1, GL_POSITION, position1);
780}
781
782
783void KeyHorizontalMotion(float shift)
784{
785        Vector3 hvec = camera->GetDirection();
786        hvec.z = 0;
787
788        Vector3 pos = camera->GetPosition();
789        pos += hvec * shift;
790       
791        camera->SetPosition(pos);
792}
793
794
795void KeyVerticalMotion(float shift)
796{
797        Vector3 uvec = Vector3(0, 0, shift);
798
799        Vector3 pos = camera->GetPosition();
800        pos += uvec;
801       
802        camera->SetPosition(pos);
803}
804
805
806
807void Display()
808{       
809        PerfTimer frameTimer, algTimer;
810        frameTimer.Start();
811
812        Vector3 oldPos = camera->GetPosition();
813
814        if (leftKeyPressed)
815                camera->Pitch(KeyRotationAngle());
816        if (rightKeyPressed)
817                camera->Pitch(-KeyRotationAngle());
818        if (upKeyPressed)
819                KeyHorizontalMotion(KeyShift());
820        if (downKeyPressed)
821                KeyHorizontalMotion(-KeyShift());
822        if (eightKeyPressed)
823                KeyVerticalMotion(-KeyShift());
824        if (nineKeyPressed)
825                KeyVerticalMotion(KeyShift());
826
827        // place view on ground
828        if (!flyMode) PlaceViewer(oldPos);
829
830        if (useGlFinish) glFinish();
831
832        algTimer.Start();
833
834        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
835       
836        glPushAttrib(GL_VIEWPORT_BIT);
837        glViewport(0, 0, texWidth, texHeight);
838
839        cgGLEnableProfile(sCgFragmentProfile);
840        cgGLBindProgram(sCgTestProgram);
841
842        cgGLEnableProfile(sCgVertexProfile);
843        cgGLBindProgram(sCgLinearDepthProgram);
844
845        glDrawBuffers(2, mrt);
846       
847        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
848
849        glDepthFunc(GL_LESS);
850        glDisable(GL_TEXTURE_2D);
851        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
852
853        // render without shading
854        if (depthPass)
855        {
856                state.SetDepthPass(true);
857                glDisable(GL_LIGHTING);
858        }
859        else
860        {
861                state.SetDepthPass(false);
862                glEnable(GL_LIGHTING);
863        }
864
865        // bring eye modelview matrix up-to-date
866        SetupEyeView();
867
868        Vector3 dir =  camera->GetDirection();
869        cgGLSetParameter3f(sEyeVecParam, dir.x, dir.y, dir.z);
870
871        // set modelview matrix for shaders
872        cgGLSetStateMatrixParameter(sModelViewMatrixParam, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
873        cgGLEnableProfile(sCgVertexProfile);
874
875        // actually render the scene geometry using one of the specified algorithms
876        traverser->RenderScene();
877
878
879        //////
880        //-- do the rest of the rendering
881
882        glEnableClientState(GL_VERTEX_ARRAY);
883        glEnableClientState(GL_NORMAL_ARRAY);
884
885
886        // reset depth pass and render visible objects
887        if (depthPass)
888        {
889                RenderVisibleObjects();
890        }
891       
892
893        ///////////////
894        //-- render sky
895
896        RenderSky();
897
898        state.Reset();
899
900        glDisableClientState(GL_VERTEX_ARRAY);
901        glDisableClientState(GL_NORMAL_ARRAY);
902       
903       
904        cgGLDisableProfile(sCgVertexProfile);
905        cgGLDisableProfile(sCgFragmentProfile);
906
907        glPopAttrib();
908       
909        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
910
911        DisplayRenderTexture();
912
913        if (useGlFinish) glFinish();
914
915        algTime = algTimer.Elapsedms();
916
917        ///////////
918
919        if (visMode) DisplayVisualization();
920       
921        DisplayStats();
922
923        glutSwapBuffers();
924
925        elapsedTime = frameTimer.Elapsed();
926}
927
928
929#pragma warning( disable : 4100 )
930void KeyBoard(unsigned char c, int x, int y)
931{
932        switch(c)
933        {
934        case 27:
935                CleanUp();
936                exit(0);
937                break;
938        case 32: //space
939                renderMode = (renderMode + 1) % RenderTraverser::NUM_TRAVERSAL_TYPES;
940                ResetTraverser();
941                break;
942        case 'h':
943        case 'H':
944                showHelp = !showHelp;
945                break;
946        case '+':
947                maxBatchSize += 10;
948                traverser->SetMaxBatchSize(maxBatchSize);
949                break;
950        case '-':
951                maxBatchSize -= 10;
952                if (maxBatchSize < 0) maxBatchSize = 1;
953                traverser->SetMaxBatchSize(maxBatchSize);               
954                break;
955        case '6':
956                assumedVisibleFrames -= 1;
957                if (assumedVisibleFrames < 1) assumedVisibleFrames = 1;
958                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
959                break;
960        case '7':
961                assumedVisibleFrames += 1;
962                traverser->SetAssumedVisibleFrames(assumedVisibleFrames);               
963                break;
964        case 'M':
965        case 'm':
966                useMultiQueries = !useMultiQueries;
967                traverser->SetUseMultiQueries(useMultiQueries);
968                break;
969        case '8':
970                        eightKeyPressed = true;
971                        break;
972        case '9':
973                        nineKeyPressed = true;
974                        break;
975        case 'o':
976        case 'O':
977                useOptimization = !useOptimization;
978                traverser->SetUseOptimization(useOptimization);
979                break;
980        case 'a':
981        case 'A':
982                        leftKeyPressed = true;
983                break;
984        case 'd':
985        case 'D':
986                        rightKeyPressed = true;
987                break;
988        case 'w':
989        case 'W':
990                        upKeyPressed = true;
991                break;
992        case 'x':
993        case 'X':
994                        downKeyPressed = true;
995                break;
996        case 'r':
997        case 'R':
998                {
999                        useRenderQueue = !useRenderQueue;
1000                        traverser->SetUseRenderQueue(useRenderQueue);
1001                }
1002                break;
1003        case 'b':
1004        case 'B':
1005                {
1006                        useTightBounds = !useTightBounds;
1007                        traverser->SetUseTightBounds(useTightBounds);
1008                }
1009                break;
1010        case '4':
1011                if (trianglesPerVirtualLeaf >= 100)
1012                        trianglesPerVirtualLeaf -= 100;
1013
1014                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1015                break;
1016        case '5':
1017                trianglesPerVirtualLeaf += 100;
1018                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1019                break;
1020        default:
1021                return;
1022        }
1023
1024        glutPostRedisplay();
1025}
1026
1027
1028void SpecialKeyUp(int c, int x, int y)
1029{
1030        switch (c)
1031        {
1032        case GLUT_KEY_LEFT:
1033                leftKeyPressed = false;
1034                break;
1035        case GLUT_KEY_RIGHT:
1036                rightKeyPressed = false;
1037                break;
1038        case GLUT_KEY_UP:
1039                upKeyPressed = false;
1040                break;
1041        case GLUT_KEY_DOWN:
1042                downKeyPressed = false;
1043                break;
1044        default:
1045                return;
1046        }
1047        //glutPostRedisplay();
1048}
1049
1050
1051void KeyUp(unsigned char c, int x, int y)
1052{
1053        switch (c)
1054        {
1055        case 'A':
1056        case 'a':
1057                leftKeyPressed = false;
1058                break;
1059        case 'D':
1060        case 'd':
1061                rightKeyPressed = false;
1062                break;
1063        case 'W':
1064        case 'w':
1065                upKeyPressed = false;
1066                break;
1067        case 'X':
1068        case 'x':
1069                downKeyPressed = false;
1070                break;
1071        case '8':
1072                eightKeyPressed = false;
1073                break;
1074       
1075        case '9':
1076                nineKeyPressed = false;
1077                break;
1078       
1079        default:
1080                return;
1081        }
1082        //glutPostRedisplay();
1083}
1084
1085
1086void Special(int c, int x, int y)
1087{
1088        switch(c)
1089        {
1090        case GLUT_KEY_F1:
1091                showHelp = !showHelp;
1092                break;
1093        case GLUT_KEY_F2:
1094                visMode = !visMode;
1095                break;
1096        case GLUT_KEY_F3:
1097                showBoundingVolumes = !showBoundingVolumes;
1098                traverser->SetShowBounds(showBoundingVolumes);
1099                break;
1100        case GLUT_KEY_F4:
1101                showStatistics = !showStatistics;
1102                break;
1103        case GLUT_KEY_F5:
1104                showOptions = !showOptions;
1105                break;
1106        case GLUT_KEY_F6:
1107                flyMode = !flyMode;
1108                break;
1109        case GLUT_KEY_F7:
1110                depthPass = !depthPass;
1111                traverser->SetUseDepthPass(depthPass);
1112                break;
1113        case GLUT_KEY_F8:
1114                useGlFinish = !useGlFinish;
1115                break;
1116        case GLUT_KEY_LEFT:
1117                {
1118                        leftKeyPressed = true;
1119                        camera->Pitch(KeyRotationAngle());
1120                }
1121                break;
1122        case GLUT_KEY_RIGHT:
1123                {
1124                        rightKeyPressed = true;
1125                        camera->Pitch(-KeyRotationAngle());
1126                }
1127                break;
1128        case GLUT_KEY_UP:
1129                {
1130                        upKeyPressed = true;
1131                        KeyHorizontalMotion(KeyShift());
1132                }
1133                break;
1134        case GLUT_KEY_DOWN:
1135                {
1136                        downKeyPressed = true;
1137                        KeyHorizontalMotion(-KeyShift());
1138                }
1139                break;
1140        default:
1141                return;
1142
1143        }
1144
1145        glutPostRedisplay();
1146}
1147
1148#pragma warning( default : 4100 )
1149
1150
1151void Reshape(int w, int h)
1152{
1153        winAspectRatio = 1.0f;
1154
1155        glViewport(0, 0, w, h);
1156       
1157        winWidth = w;
1158        winHeight = h;
1159
1160        if (w) winAspectRatio = (float) h / (float) w;
1161
1162        glMatrixMode(GL_PROJECTION);
1163        glLoadIdentity();
1164
1165        gluPerspective(fov, 1.0f / winAspectRatio, nearDist, myfar);
1166
1167        glMatrixMode(GL_MODELVIEW);
1168
1169        glutPostRedisplay();
1170}
1171
1172
1173void Mouse(int button, int state, int x, int y)
1174{
1175        if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
1176        {
1177                xEyeBegin = x;
1178                yMotionBegin = y;
1179
1180                glutMotionFunc(LeftMotion);
1181        }
1182        else if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN))
1183        {
1184                yEyeBegin = y;
1185                yMotionBegin = y;
1186
1187                glutMotionFunc(RightMotion);
1188        }
1189        else if ((button == GLUT_MIDDLE_BUTTON) && (state == GLUT_DOWN))
1190        {
1191                horizontalMotionBegin = x;
1192                verticalMotionBegin = y;
1193                glutMotionFunc(MiddleMotion);
1194        }
1195
1196        glutPostRedisplay();
1197}
1198
1199
1200/**     rotation for left/right mouse drag
1201        motion for up/down mouse drag
1202*/
1203void LeftMotion(int x, int y)
1204{
1205        Vector3 viewDir = camera->GetDirection();
1206        Vector3 pos = camera->GetPosition();
1207
1208        // don't move in the vertical direction
1209        Vector3 horView(viewDir[0], viewDir[1], 0);
1210       
1211        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
1212
1213        camera->Pitch(eyeXAngle);
1214
1215        pos += horView * (yMotionBegin - y) * 0.2f;
1216       
1217        camera->SetPosition(pos);
1218       
1219        xEyeBegin = x;
1220        yMotionBegin = y;
1221
1222        glutPostRedisplay();
1223}
1224
1225
1226/**     rotation for left / right mouse drag
1227        motion for up / down mouse drag
1228*/
1229void RightMotion(int x, int y)
1230{
1231        float eyeYAngle = -0.2f *  M_PI * (yEyeBegin - y) / 180.0;
1232
1233        camera->Yaw(eyeYAngle);
1234
1235        yEyeBegin = y;
1236        glutPostRedisplay();
1237}
1238
1239
1240// strafe
1241void MiddleMotion(int x, int y)
1242{
1243        Vector3 viewDir = camera->GetDirection();
1244        Vector3 pos = camera->GetPosition();
1245
1246        // the 90 degree rotated view vector
1247        // y zero so we don't move in the vertical
1248        Vector3 rVec(viewDir[0], viewDir[1], 0);
1249       
1250        Matrix4x4 rot = RotationZMatrix(M_PI * 0.5f);
1251        rVec = rot * rVec;
1252       
1253        pos -= rVec * (x - horizontalMotionBegin) * 0.1f;
1254        pos[2] += (verticalMotionBegin - y) * 0.1f;
1255
1256        camera->SetPosition(pos);
1257
1258        horizontalMotionBegin = x;
1259        verticalMotionBegin = y;
1260
1261        glutPostRedisplay();
1262}
1263
1264
1265void InitExtensions(void)
1266{
1267        GLenum err = glewInit();
1268
1269        if (GLEW_OK != err)
1270        {
1271                // problem: glewInit failed, something is seriously wrong
1272                fprintf(stderr,"Error: %s\n", glewGetErrorString(err));
1273                exit(1);
1274        }
1275        if  (!GLEW_ARB_occlusion_query)
1276        {
1277                printf("I require the GL_ARB_occlusion_query to work.\n");
1278                exit(1);
1279        }
1280}
1281
1282
1283void Begin2D(void)
1284{
1285        glDisable(GL_LIGHTING);
1286        glDisable(GL_DEPTH_TEST);
1287
1288        glPushMatrix();
1289        glLoadIdentity();
1290
1291        glMatrixMode(GL_PROJECTION);
1292        glPushMatrix();
1293        glLoadIdentity();
1294        gluOrtho2D(0, winWidth, winHeight, 0);
1295}
1296
1297
1298void End2D(void)
1299{
1300        glPopMatrix();
1301        glMatrixMode(GL_MODELVIEW);
1302        glPopMatrix();
1303
1304        glEnable(GL_LIGHTING);
1305        glEnable(GL_DEPTH_TEST);
1306}
1307
1308
1309void Output(int x, int y, const char *string)
1310{
1311        if (string != 0)
1312        {
1313                size_t len, i;
1314                glRasterPos2f(x, y);
1315                len = strlen(string);
1316               
1317                for (i = 0; i < len; ++ i)
1318                {
1319                        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, string[i]);
1320                }
1321        }
1322}
1323
1324
1325// displays the visualisation of culling algorithm
1326void DisplayVisualization()
1327{
1328        visualization->SetFrameId(traverser->GetCurrentFrameId());
1329       
1330        Begin2D();
1331        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1332        glEnable(GL_BLEND);
1333        glColor4f(0.0,0.0,0.0,0.5);
1334
1335        glRecti(winWidth, 0, winWidth - winWidth / 3, winHeight / 3);
1336        glDisable(GL_BLEND);
1337        End2D();
1338       
1339       
1340        AxisAlignedBox3 box = bvh->GetBox();
1341
1342        // set far for viz
1343        camera->SetFar(0.35f * Magnitude(box.Diagonal()));
1344
1345        const float offs = box.Size().x * 0.3f;
1346        //const float yoffs = box.Size().y * 0.5f;
1347
1348        Vector3 pos = camera->GetPosition();
1349
1350        Vector3 vizpos = Vector3(box.Min().x + 20, box.Min().y + 500, box.Min().z + box.Size().z * 50);
1351       
1352        visCamera->SetPosition(vizpos);
1353       
1354        glViewport(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth / 3, winHeight / 3);
1355
1356        glMatrixMode(GL_PROJECTION);
1357        glLoadIdentity();
1358       
1359        glOrtho(-offs, offs, -offs, offs, 0.0f, box.Size().z * 100.0f);
1360
1361        glMatrixMode(GL_MODELVIEW);
1362
1363        visCamera->SetupCameraView();
1364
1365        Matrix4x4 rotZ = RotationZMatrix(-camera->GetPitch());
1366        glMultMatrixf((float *)rotZ.x);
1367
1368        glTranslatef(-pos.x, -pos.y, -pos.z);
1369
1370
1371        GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
1372        glLightfv(GL_LIGHT0, GL_POSITION, position);
1373
1374        GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
1375        glLightfv(GL_LIGHT1, GL_POSITION, position1);
1376
1377        glClear(GL_DEPTH_BUFFER_BIT);
1378
1379
1380        ////////////
1381        //-- visualization of the occlusion culling
1382
1383        visualization->Render();
1384       
1385        // reset vp
1386        glViewport(0, 0, winWidth, winHeight);
1387}
1388
1389
1390// cleanup routine after the main loop
1391void CleanUp()
1392{
1393        DEL_PTR(traverser);
1394        DEL_PTR(sceneQuery);
1395        DEL_PTR(bvh);
1396        DEL_PTR(visualization);
1397        DEL_PTR(camera);
1398        DEL_PTR(loader);
1399        DEL_PTR(renderQueue);
1400
1401        if (sCgLinearDepthProgram)
1402                cgDestroyProgram(sCgLinearDepthProgram);
1403        if (sCgSSAOProgram)
1404                cgDestroyProgram(sCgSSAOProgram);
1405        if (sCgContext)
1406                cgDestroyContext(sCgContext);
1407}
1408
1409
1410// this function inserts a dezimal point after each 1000
1411void CalcDecimalPoint(string &str, int d)
1412{
1413        vector<int> numbers;
1414        char hstr[100];
1415
1416        while (d != 0)
1417        {
1418                numbers.push_back(d % 1000);
1419                d /= 1000;
1420        }
1421
1422        // first element without leading zeros
1423        if (numbers.size() > 0)
1424        {
1425                sprintf(hstr, "%d", numbers.back());
1426                str.append(hstr);
1427        }
1428       
1429        for (int i = (int)numbers.size() - 2; i >= 0; i--)
1430        {
1431                sprintf(hstr, ",%03d", numbers[i]);
1432                str.append(hstr);
1433        }
1434}
1435
1436
1437void DisplayStats()
1438{
1439        static char msg[7][300];
1440
1441        static double renderTime = algTime;
1442        const float expFactor = 0.5f;
1443
1444        // if some strange render time spike happened in this frame => don't count
1445        if (algTime < 500) renderTime = algTime * expFactor + (1.0f - expFactor) * algTime;
1446
1447        accumulatedTime += elapsedTime * 1e3f;
1448
1449        if (accumulatedTime > 500) // update every fraction of a second
1450        {       
1451                accumulatedTime = 0;
1452                if (renderTime) fps = 1e3f / (float)renderTime;
1453
1454                renderedObjects = traverser->GetStats().mNumRenderedGeometry;
1455                renderedNodes = traverser->GetStats().mNumRenderedNodes;
1456                renderedTriangles = traverser->GetStats().mNumRenderedTriangles;
1457
1458                traversedNodes = traverser->GetStats().mNumTraversedNodes;
1459                frustumCulledNodes = traverser->GetStats().mNumFrustumCulledNodes;
1460                queryCulledNodes = traverser->GetStats().mNumQueryCulledNodes;
1461                issuedQueries = traverser->GetStats().mNumIssuedQueries;
1462                stateChanges = traverser->GetStats().mNumStateChanges;
1463                numBatches = traverser->GetStats().mNumBatches;
1464        }
1465
1466        string str;
1467        string str2;
1468
1469        int i = 0;
1470
1471        CalcDecimalPoint(str, renderedTriangles);
1472        CalcDecimalPoint(str2, bvh->GetBvhStats().mTriangles);
1473
1474        sprintf(msg[i ++], "rendered nodes: %6d (of %6d), rendered triangles: %s (of %s)",
1475                        renderedNodes, bvh->GetNumVirtualNodes(), str.c_str(), str2.c_str());
1476
1477        sprintf(msg[i ++], "traversed: %5d, frustum culled: %5d, query culled: %5d",
1478                        traversedNodes, frustumCulledNodes, queryCulledNodes);
1479
1480        sprintf(msg[i ++], "issued queries: %5d, state changes: %5d, render batches: %5d",
1481                    issuedQueries, stateChanges, numBatches);
1482
1483        sprintf(msg[i ++], "fps: %6.1f", fps);
1484
1485
1486        sprintf(msg[i ++], "assumed visible frames: %4d, max batch size: %4d",
1487                    assumedVisibleFrames, maxBatchSize);
1488
1489        sprintf(msg[i ++], "multiqueries: %d, tight bounds: %d, render queue: %d, depth pass: %d, glFinish: %d",
1490                    useMultiQueries, useTightBounds, useRenderQueue, depthPass, useGlFinish);
1491
1492        sprintf(msg[i ++], "triangles per virtual leaf: %5d", trianglesPerVirtualLeaf);
1493
1494
1495        Begin2D();
1496       
1497        if(showHelp)
1498        {       
1499                DrawHelpMessage();
1500        }
1501        else
1502        {
1503                static char *alg_str[] = {"Frustum Culling", "Stop and Wait", "CHC", "CHC ++"};
1504
1505                glColor3f(1.0f, 1.0f, 1.0f);
1506                Output(850, 30, alg_str[renderMode]);
1507
1508                if (showStatistics)
1509                {
1510                        for (int i = 0; i < 4; ++ i)
1511                                Output(20, (i + 1) * 30, msg[i]);
1512                }
1513
1514                if (showOptions)
1515                {
1516                        for (int i = 4; i < 8; ++ i)
1517                                Output(20, (i + 1) * 30, msg[i]);
1518                }
1519        }
1520
1521        End2D();
1522}       
1523
1524
1525void RenderSky()
1526{
1527        SceneEntityContainer::const_iterator sit, sit_end = skyGeometry.end();
1528
1529        for (sit = skyGeometry.begin(); sit != sit_end; ++ sit)
1530                (*sit)->Render(&state);
1531}
1532
1533
1534void RenderVisibleObjects()
1535{
1536        state.SetDepthPass(false);
1537        state.Reset();
1538
1539        glEnable(GL_LIGHTING);
1540        glDepthFunc(GL_LEQUAL);
1541
1542        //cout << "visible: " << (int)traverser->GetVisibleObjects().size() << endl;
1543
1544        SceneEntityContainer::const_iterator sit,
1545                sit_end = traverser->GetVisibleObjects().end();
1546
1547        for (sit = traverser->GetVisibleObjects().begin(); sit != sit_end; ++ sit)
1548                renderQueue->Enqueue(*sit);
1549               
1550        renderQueue->Apply();
1551
1552        glDepthFunc(GL_LESS);
1553}
1554
1555
1556void PlaceViewer(const Vector3 &oldPos)
1557{
1558        Vector3 playerPos = camera->GetPosition();
1559
1560        bool validIntersect = sceneQuery->CalcIntersection(playerPos);
1561
1562        if (validIntersect &&
1563                (( playerPos.z - oldPos.z) < bvh->GetBox().Size(2) * 1e-1f))
1564        {
1565                camera->SetPosition(playerPos);
1566        }
1567}
1568
1569
1570void DisplayRenderTexture2()
1571{
1572        glEnable(GL_TEXTURE_2D);
1573        glBindTexture(GL_TEXTURE_2D, occlusionTex);
1574
1575        glDisable(GL_LIGHTING);
1576
1577        glMatrixMode(GL_PROJECTION);
1578        glPushMatrix();
1579        glLoadIdentity();
1580
1581        glMatrixMode(GL_MODELVIEW);
1582        glPushMatrix();
1583        glLoadIdentity();
1584       
1585        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
1586        glPushAttrib(GL_VIEWPORT_BIT);
1587        glViewport(0, 0, texWidth2, texHeight2);
1588
1589        glOrtho(-0.5f, 0.5f, -0.5f, 0.5f, 0, 1);
1590
1591        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1592        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1593       
1594        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1595
1596        glColor3f(1.0f, 1.0f, 1.0f);
1597
1598        glBegin(GL_QUADS);
1599        glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f);
1600        glTexCoord2f(1, 0); glVertex3f( 1, -1, -0.5f);
1601        glTexCoord2f(1, 1); glVertex3f( 1,  1, -0.5f);
1602        glTexCoord2f(0, 1); glVertex3f(-1,  1, -0.5f);
1603        glEnd();
1604
1605        glEnable(GL_LIGHTING);
1606        glDisable(GL_TEXTURE_2D);
1607       
1608        glMatrixMode(GL_PROJECTION);
1609        glPopMatrix();
1610
1611        glMatrixMode(GL_MODELVIEW);
1612        glPopMatrix();
1613
1614        glPopAttrib();
1615        glBindTexture(GL_TEXTURE_2D, 0);
1616
1617        PrintGLerror("displaytexture2");
1618}
1619
1620void DisplayRenderTexture()
1621{
1622        glDisable(GL_TEXTURE_2D);
1623        glDisable(GL_LIGHTING);
1624
1625        glMatrixMode(GL_PROJECTION);
1626        glPushMatrix();
1627        glLoadIdentity();
1628
1629        glMatrixMode(GL_MODELVIEW);
1630        glPushMatrix();
1631        glLoadIdentity();
1632       
1633        /*glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
1634        glPushAttrib(GL_VIEWPORT_BIT);
1635        glViewport(0, 0, texWidth2, texHeight2);
1636*/
1637        glOrtho(-0.5f, 0.5f, -0.5f, 0.5f, 0, 1);
1638       
1639        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1640
1641        cgGLEnableProfile(sCgFragmentProfile);
1642        cgGLBindProgram(sCgSSAOProgram);
1643
1644        cgGLEnableTextureParameter(sTextureParam);
1645        cgGLSetTextureParameter(sTextureParam, colorTex2);
1646       
1647        cgGLEnableTextureParameter(sSceneTextureParam);
1648        cgGLSetTextureParameter(sSceneTextureParam, colorTex);
1649       
1650        cgGLEnableTextureParameter(sNormalTextureParam);
1651        cgGLSetTextureParameter(sNormalTextureParam, normalTex);
1652
1653        Vector3 tl, tr, bl, br;
1654        ComputeViewVectors(tl, tr, bl, br);
1655
1656        glColor3f(1.0f, 1.0f, 1.0f);
1657
1658        glBegin(GL_QUADS);
1659#if 1
1660        glColor3f(bl.x, bl.y, bl.z); glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f);
1661        glColor3f(br.x, br.y, br.z); glTexCoord2f(1, 0); glVertex3f( 1, -1, -0.5f);
1662        glColor3f(tr.x, tr.y, tr.z); glTexCoord2f(1, 1); glVertex3f( 1,  1, -0.5f);
1663        glColor3f(tl.x, tl.y, tl.z); glTexCoord2f(0, 1); glVertex3f(-1,  1, -0.5f);
1664#else
1665        glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f);
1666        glTexCoord2f(1, 0); glVertex3f( 1, -1, -0.5f);
1667        glTexCoord2f(1, 1); glVertex3f( 1,  1, -0.5f);
1668        glTexCoord2f(0, 1); glVertex3f(-1,  1, -0.5f);
1669#endif
1670        glEnd();
1671
1672        cgGLDisableTextureParameter(sTextureParam);
1673        cgGLDisableTextureParameter(sSceneTextureParam);
1674        cgGLDisableProfile(sCgFragmentProfile);
1675       
1676        glEnable(GL_LIGHTING);
1677        glDisable(GL_TEXTURE_2D);
1678       
1679        glMatrixMode(GL_PROJECTION);
1680        glPopMatrix();
1681
1682        glMatrixMode(GL_MODELVIEW);
1683        glPopMatrix();
1684
1685        //glPopAttrib();
1686        //glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo2);
1687
1688        PrintGLerror("displaytexture");
1689        //DisplayRenderTexture2();
1690}
1691
1692
1693
1694void GenerateSamples()
1695{
1696        // fill an n * n * 2 array with uniformly distributed spherical samples
1697        for (int i = 0; i < 32; ++ i)
1698        {
1699                // create stratified samples over sphere
1700                const float rx = RandomValue(0, 1);
1701                const float ry = RandomValue(0, 1);
1702                //const float l = RandomValue(0, 1);
1703
1704                const float theta = 2.0f * acos(sqrt(1.0f - rx));
1705                const float phi = 2.0f * M_PI * ry;
1706
1707                samples[i] = Vector3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
1708                cout << samples[i] << endl;
1709        }
1710}
1711
1712
1713void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
1714{
1715        float myfov = fov * M_PI / 180.0f;
1716        const float h_far = 2.0f * tan(myfov / 2.0f);
1717        const float w_far = h_far * texWidth / texHeight;
1718
1719        float t1 = h_far * 0.5f;
1720        float t2 = w_far * 0.5f;
1721
1722        bl = Normalize(Vector3(-t1, -t2, 1.0f));
1723        br = Normalize(Vector3( t1, -t2, 1.0f));
1724        tl = Normalize(Vector3(-t1,  t2, 1.0f));
1725        tr = Normalize(Vector3( t1,  t2, 1.0f));
1726
1727        // normalize to 0 .. 1
1728        bl = bl * 0.5f + 0.5f;
1729        br = br * 0.5f + 0.5f;
1730        tl = tl * 0.5f + 0.5f;
1731        tr = tr * 0.5f + 0.5f;
1732
1733/*
1734        cout << "tl: " << tl << endl;
1735        cout << "tr: " << tr << endl;
1736        cout << "bl: " << bl << endl;
1737        cout << "br: " << bl << endl << endl;*/
1738}
1739
1740
1741void CreateNormalMap()
1742{
1743        Vector3 *data = new Vector3[texWidth * texHeight];
1744
1745        for (int i = 0; i < texWidth * texHeight; ++ i)
1746        {
1747                // create random samples over sphere
1748                const float rx = RandomValue(0, 1);
1749                const float ry = RandomValue(0, 1);
1750
1751                const float theta = 2.0f * acos(sqrt(1.0f - rx));
1752                const float phi = 2.0f * M_PI * ry;
1753
1754                data[i] = Vector3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
1755                data[i] += 1.0f;       
1756                data[i] *= 0.5f;
1757        }
1758
1759        glGenTextures(1, &normalTex);
1760        glBindTexture(GL_TEXTURE_2D, normalTex);
1761        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,  texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
1762}
Note: See TracBrowser for help on using the repository browser.