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

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