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

Revision 2826, 48.6 KB checked in by mattausch, 16 years ago (diff)

changed font

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