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

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