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

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