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

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