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

Revision 2815, 44.5 KB checked in by mattausch, 16 years ago (diff)

shader nice but lights dull

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 = 0.1f;
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];
148
149
150// function forward declarations
151void InitExtensions();
152void DisplayVisualization();
153void InitGLstate();
154void InitRenderTexture();
155void InitCg();
156void CleanUp();
157void SetupEyeView();
158void UpdateEyeMtx();
159void SetupLighting();
160void DisplayStats();
161void Output(int x, int y, const char *string);
162void DrawHelpMessage();
163void RenderSky();
164void RenderVisibleObjects();
165
166void Begin2D();
167void End2D();
168void KeyBoard(unsigned char c, int x, int y);
169void DrawStatistics();
170void Display();
171void Special(int c, int x, int y);
172void KeyUp(unsigned char c, int x, int y);
173void SpecialKeyUp(int c, int x, int y);
174void Reshape(int w, int h);
175void Mouse(int button, int state, int x, int y);
176void LeftMotion(int x, int y);
177void RightMotion(int x, int y);
178void MiddleMotion(int x, int y);
179void CalcDecimalPoint(string &str, int d);
180void ResetTraverser();
181
182void KeyHorizontalMotion(float shift);
183void KeyVerticalMotion(float shift);
184
185void PlaceViewer(const Vector3 &oldPos);
186void DisplayRenderTexture();
187
188
189inline float KeyRotationAngle() { return keyRotation * elapsedTime; }
190inline float KeyShift() { return keyForwardMotion * elapsedTime; }
191
192void InitFBO();
193
194void GenerateSamples();
195
196void 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_LINEAR);
541        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
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_LINEAR);
565        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
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
1456
1457// this function inserts a dezimal point after each 1000
1458void CalcDecimalPoint(string &str, int d)
1459{
1460        vector<int> numbers;
1461        char hstr[100];
1462
1463        while (d != 0)
1464        {
1465                numbers.push_back(d % 1000);
1466                d /= 1000;
1467        }
1468
1469        // first element without leading zeros
1470        if (numbers.size() > 0)
1471        {
1472                sprintf(hstr, "%d", numbers.back());
1473                str.append(hstr);
1474        }
1475       
1476        for (int i = (int)numbers.size() - 2; i >= 0; i--)
1477        {
1478                sprintf(hstr, ",%03d", numbers[i]);
1479                str.append(hstr);
1480        }
1481}
1482
1483
1484void DisplayStats()
1485{
1486        static char msg[7][300];
1487
1488        static double renderTime = algTime;
1489        const float expFactor = 0.5f;
1490
1491        // if some strange render time spike happened in this frame => don't count
1492        if (algTime < 500) renderTime = algTime * expFactor + (1.0f - expFactor) * algTime;
1493
1494        accumulatedTime += elapsedTime * 1e3f;
1495
1496        if (accumulatedTime > 500) // update every fraction of a second
1497        {       
1498                accumulatedTime = 0;
1499                if (renderTime) fps = 1e3f / (float)renderTime;
1500
1501                renderedObjects = traverser->GetStats().mNumRenderedGeometry;
1502                renderedNodes = traverser->GetStats().mNumRenderedNodes;
1503                renderedTriangles = traverser->GetStats().mNumRenderedTriangles;
1504
1505                traversedNodes = traverser->GetStats().mNumTraversedNodes;
1506                frustumCulledNodes = traverser->GetStats().mNumFrustumCulledNodes;
1507                queryCulledNodes = traverser->GetStats().mNumQueryCulledNodes;
1508                issuedQueries = traverser->GetStats().mNumIssuedQueries;
1509                stateChanges = traverser->GetStats().mNumStateChanges;
1510                numBatches = traverser->GetStats().mNumBatches;
1511        }
1512
1513        string str;
1514        string str2;
1515
1516        int i = 0;
1517
1518        CalcDecimalPoint(str, renderedTriangles);
1519        CalcDecimalPoint(str2, bvh->GetBvhStats().mTriangles);
1520
1521        sprintf(msg[i ++], "rendered nodes: %6d (of %6d), rendered triangles: %s (of %s)",
1522                        renderedNodes, bvh->GetNumVirtualNodes(), str.c_str(), str2.c_str());
1523
1524        sprintf(msg[i ++], "traversed: %5d, frustum culled: %5d, query culled: %5d",
1525                        traversedNodes, frustumCulledNodes, queryCulledNodes);
1526
1527        sprintf(msg[i ++], "issued queries: %5d, state changes: %5d, render batches: %5d",
1528                    issuedQueries, stateChanges, numBatches);
1529
1530        sprintf(msg[i ++], "fps: %6.1f", fps);
1531
1532
1533        sprintf(msg[i ++], "assumed visible frames: %4d, max batch size: %4d",
1534                    assumedVisibleFrames, maxBatchSize);
1535
1536        sprintf(msg[i ++], "multiqueries: %d, tight bounds: %d, render queue: %d, depth pass: %d, glFinish: %d",
1537                    useMultiQueries, useTightBounds, useRenderQueue, depthPass, useGlFinish);
1538
1539        sprintf(msg[i ++], "triangles per virtual leaf: %5d", trianglesPerVirtualLeaf);
1540
1541
1542        Begin2D();
1543       
1544        if(showHelp)
1545        {       
1546                DrawHelpMessage();
1547        }
1548        else
1549        {
1550                static char *alg_str[] = {"Frustum Culling", "Stop and Wait", "CHC", "CHC ++"};
1551
1552                glColor3f(1.0f, 1.0f, 1.0f);
1553                Output(850, 30, alg_str[renderMode]);
1554
1555                if (showStatistics)
1556                {
1557                        for (int i = 0; i < 4; ++ i)
1558                                Output(20, (i + 1) * 30, msg[i]);
1559                }
1560
1561                if (showOptions)
1562                {
1563                        for (int i = 4; i < 8; ++ i)
1564                                Output(20, (i + 1) * 30, msg[i]);
1565                }
1566        }
1567
1568        End2D();
1569}       
1570
1571
1572void RenderSky()
1573{
1574        SceneEntityContainer::const_iterator sit, sit_end = skyGeometry.end();
1575
1576        for (sit = skyGeometry.begin(); sit != sit_end; ++ sit)
1577                (*sit)->Render(&state);
1578}
1579
1580
1581void RenderVisibleObjects()
1582{
1583        state.SetDepthPass(false);
1584        state.Reset();
1585
1586        glEnable(GL_LIGHTING);
1587        glDepthFunc(GL_LEQUAL);
1588
1589        //cout << "visible: " << (int)traverser->GetVisibleObjects().size() << endl;
1590
1591        SceneEntityContainer::const_iterator sit,
1592                sit_end = traverser->GetVisibleObjects().end();
1593
1594        for (sit = traverser->GetVisibleObjects().begin(); sit != sit_end; ++ sit)
1595                renderQueue->Enqueue(*sit);
1596               
1597        renderQueue->Apply();
1598
1599        glDepthFunc(GL_LESS);
1600}
1601
1602
1603void PlaceViewer(const Vector3 &oldPos)
1604{
1605        Vector3 playerPos = camera->GetPosition();
1606
1607        bool validIntersect = sceneQuery->CalcIntersection(playerPos);
1608
1609        if (validIntersect &&
1610                (( playerPos.z - oldPos.z) < bvh->GetBox().Size(2) * 1e-1f))
1611        {
1612                camera->SetPosition(playerPos);
1613        }
1614}
1615
1616
1617void DisplayRenderTexture()
1618{
1619        glDisable(GL_TEXTURE_2D);
1620        //glEnable(GL_TEXTURE_2D);
1621        glDisable(GL_LIGHTING);
1622        //glBindTexture(GL_TEXTURE_2D, noiseTex);
1623        glMatrixMode(GL_PROJECTION);
1624        glPushMatrix();
1625        glLoadIdentity();
1626
1627        glMatrixMode(GL_MODELVIEW);
1628        glPushMatrix();
1629        glLoadIdentity();
1630
1631        glOrtho(-0.5f, 0.5f, -0.5f, 0.5f, 0, 1);
1632       
1633        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1634
1635        cgGLEnableProfile(sCgFragmentProfile);
1636        cgGLBindProgram(sCgSSAOProgram);
1637
1638        cgGLEnableTextureParameter(sPositionsTexParam);
1639        cgGLSetTextureParameter(sPositionsTexParam, positionsTex);
1640       
1641        cgGLEnableTextureParameter(sColorsTexParam);
1642        cgGLSetTextureParameter(sColorsTexParam, colorsTex);
1643       
1644        cgGLEnableTextureParameter(sNormalsTexParam);
1645        cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
1646
1647        cgGLEnableTextureParameter(sNoiseTexParam);
1648        cgGLSetTextureParameter(sNoiseTexParam, noiseTex);
1649
1650        Vector3 tl, tr, bl, br;
1651        ComputeViewVectors(tl, tr, bl, br);
1652
1653        glColor3f(1.0f, 1.0f, 1.0f);
1654
1655        glBegin(GL_QUADS);
1656#if 1
1657        glColor3f(bl.x, bl.y, bl.z); glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f);
1658        glColor3f(br.x, br.y, br.z); glTexCoord2f(1, 0); glVertex3f( 1, -1, -0.5f);
1659        glColor3f(tr.x, tr.y, tr.z); glTexCoord2f(1, 1); glVertex3f( 1,  1, -0.5f);
1660        glColor3f(tl.x, tl.y, tl.z); glTexCoord2f(0, 1); glVertex3f(-1,  1, -0.5f);
1661#else
1662        glTexCoord2f(0, 0); glVertex3f(-1, -1, -0.5f);
1663        glTexCoord2f(1, 0); glVertex3f( 1, -1, -0.5f);
1664        glTexCoord2f(1, 1); glVertex3f( 1,  1, -0.5f);
1665        glTexCoord2f(0, 1); glVertex3f(-1,  1, -0.5f);
1666#endif
1667        glEnd();
1668
1669        cgGLDisableTextureParameter(sColorsTexParam);
1670        cgGLDisableTextureParameter(sPositionsTexParam);
1671        cgGLDisableTextureParameter(sNormalsTexParam);
1672        cgGLDisableTextureParameter(sNoiseTexParam);
1673
1674        cgGLDisableProfile(sCgFragmentProfile);
1675       
1676        glEnable(GL_LIGHTING);
1677        glDisable(GL_TEXTURE_2D);
1678       
1679        glMatrixMode(GL_PROJECTION);
1680        glPopMatrix();
1681
1682        glMatrixMode(GL_MODELVIEW);
1683        glPopMatrix();
1684
1685       
1686        PrintGLerror("displaytexture");
1687}
1688
1689
1690
1691void GenerateSamples()
1692{
1693        // fill an n * n * 2 array with uniformly distributed spherical samples
1694        for (int i = 0; i < 32; ++ i)
1695        {
1696                // create stratified samples over sphere
1697                const float rx = RandomValue(0, 1);
1698                const float ry = RandomValue(0, 1);
1699                //const float l = RandomValue(0, 1);
1700
1701                const float theta = 2.0f * acos(sqrt(1.0f - rx));
1702                const float phi = 2.0f * M_PI * ry;
1703
1704                samples[i] = Vector3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
1705                cout << samples[i] << endl;
1706        }
1707}
1708
1709
1710void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
1711{
1712        float myfov = fov * M_PI / 180.0f;
1713        const float h_far = 2.0f * tan(myfov / 2.0f);
1714        const float w_far = h_far * texWidth / texHeight;
1715
1716        float t1 = h_far * 0.5f;
1717        float t2 = w_far * 0.5f;
1718
1719        bl = Normalize(Vector3(-t1, -t2, 1.0f));
1720        br = Normalize(Vector3( t1, -t2, 1.0f));
1721        tl = Normalize(Vector3(-t1,  t2, 1.0f));
1722        tr = Normalize(Vector3( t1,  t2, 1.0f));
1723
1724        // normalize to 0 .. 1
1725        bl = bl * 0.5f + 0.5f;
1726        br = br * 0.5f + 0.5f;
1727        tl = tl * 0.5f + 0.5f;
1728        tr = tr * 0.5f + 0.5f;
1729
1730/*
1731        cout << "tl: " << tl << endl;
1732        cout << "tr: " << tr << endl;
1733        cout << "bl: " << bl << endl;
1734        cout << "br: " << bl << endl << endl;
1735        */
1736}
1737
1738
1739void CreateNoiseTex3D()
1740{
1741        Vector3 *data = new Vector3[texWidth * texHeight];
1742
1743        for (int i = 0; i < texWidth * texHeight; ++ i)
1744        {
1745                // create random samples over sphere
1746                const float rx = RandomValue(0, 1);
1747                const float ry = RandomValue(0, 1);
1748
1749                const float theta = 2.0f * acos(sqrt(1.0f - rx));
1750                const float phi = 2.0f * M_PI * ry;
1751
1752                data[i] = Vector3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
1753                // bring in 0 .. 1 so we can use unsigned byte
1754                data[i] = data[i] * 0.5f + 0.5f;
1755        }
1756
1757        glGenTextures(1, &noiseTex);
1758        glBindTexture(GL_TEXTURE_2D, noiseTex);
1759        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,  texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
1760        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1761        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1762
1763        glBindTexture(GL_TEXTURE_2D, 0);
1764
1765        PrintGLerror("noisetexture");
1766}
1767
1768#if 0
1769void CreateNoiseTex2D()
1770{
1771        Vector3 *data = new Vector3[texWidth * texHeight];
1772
1773        for (int i = 0; i < texWidth * texHeight; ++ i)
1774        {
1775                // create random samples over sphere
1776                const float rx = RandomValue(0, 1);
1777                const float theta = 2.0f * acos(sqrt(1.0f - rx));
1778
1779                data[i] = Vector3(sin(theta), cos(theta), 0);
1780
1781                //if (i % 10000) cout << "vec: " << data[i] << endl;
1782       
1783                // bring in 0 .. 1 so we could use unsigned byte
1784                data[i] = 1;//data[i] * 0.5f + 0.5f;
1785        }
1786
1787        glGenTextures(1, &noiseTex);
1788        glBindTexture(GL_TEXTURE_2D, noiseTex);
1789        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F_ARB, texWidth, texHeight, 0, GL_RGB, GL_FLOAT, (float *)data);
1790       
1791        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1792        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
1793
1794        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1795        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1796
1797        glBindTexture(GL_TEXTURE_2D, 0);
1798
1799        PrintGLerror("noisetexture");
1800}
1801
1802#else
1803void CreateNoiseTex2D()
1804{
1805        GLubyte *data = new GLubyte[texWidth * texHeight * 4];
1806
1807        for (int i = 0; i < texWidth * texHeight * 4; i += 4)
1808        {
1809                // create random samples over sphere
1810                const float rx = RandomValue(0, 1);
1811                const float theta = 2.0f * acos(sqrt(1.0f - rx));
1812
1813                data[i + 0] = (GLubyte)((cos(theta) * 0.5f + 0.5f) * 255.0f);
1814                data[i + 1] = (GLubyte)((sin(theta) * 0.5f + 0.5f) * 255.0f);
1815                data[i + 2] = 0;
1816                data[i + 3] = 255;
1817
1818                //if (i % 100000) cout << "vec: " << " " << (int)data[i] << " " << (int)data[i + 1] << endl;
1819        }
1820
1821        glEnable(GL_TEXTURE_2D);
1822        glGenTextures(1, &noiseTex);
1823        glBindTexture(GL_TEXTURE_2D, noiseTex);
1824        //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
1825        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
1826
1827        gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, texWidth, texHeight, GL_RGBA, GL_UNSIGNED_BYTE, data);
1828        //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
1829        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1830        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1831        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1832        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1833
1834        glBindTexture(GL_TEXTURE_2D, 0);
1835
1836        glDisable(GL_TEXTURE_2D);
1837
1838        cout << "created noise texture" << endl;
1839        PrintGLerror("noisetexture");
1840}
1841#endif
Note: See TracBrowser for help on using the repository browser.