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

Revision 2829, 49.3 KB checked in by mattausch, 16 years ago (diff)

worked on environment + hud

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