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

Line 
1// occquery.cpp : Defines the entry point for the console application.
2//
3#include "glInterface.h"
4#include <math.h>
5#include <time.h>
6#include "common.h"
7#include "RenderTraverser.h"
8#include "SceneEntity.h"
9#include "Vector3.h"
10#include "Matrix4x4.h"
11#include "ResourceManager.h"
12#include "Bvh.h"
13#include "Camera.h"
14#include "Geometry.h"
15#include "BvhLoader.h"
16#include "FrustumCullingTraverser.h"
17#include "StopAndWaitTraverser.h"
18#include "CHCTraverser.h"
19#include "CHCPlusPlusTraverser.h"
20#include "Visualization.h"
21#include "RenderState.h"
22#include "Timer/PerfTimer.h"
23#include "SceneQuery.h"
24#include "RenderQueue.h"
25#include "Material.h"
26#include <Cg/cg.h>
27#include <Cg/cgGL.h>
28#include "glfont2.h"
29#include "PerformanceGraph.h"
30#include "Environment.h"
31
32
33using namespace std;
34using namespace CHCDemoEngine;
35
36
37static Environment env;
38
39
40/////////////
41//-- textures
42GLuint fbo;
43
44GLuint depthBuffer;
45
46GLuint positionsBuffer;
47GLuint colorsBuffer;
48GLuint normalsBuffer;
49
50GLuint positionsTex;
51GLuint colorsTex;
52GLuint normalsTex;
53
54GLuint noiseTex;
55
56GLuint fontTex;
57
58/// the renderable scene geometry
59SceneEntityContainer sceneEntities;
60// traverses and renders the hierarchy
61RenderTraverser *traverser = NULL;
62/// the hierarchy
63Bvh *bvh = NULL;
64/// handles scene loading
65ResourceManager *loader = NULL;
66/// the scene camera
67Camera *camera = NULL;
68/// the scene camera
69Camera *visCamera = NULL;
70/// the visualization
71Visualization *visualization = NULL;
72/// the current render state
73RenderState state;
74/// the rendering algorithm
75int renderMode = RenderTraverser::CHCPLUSPLUS;
76// eye near plane distance
77float nearDist = 0.2f;
78/// the pixel threshold where a node is still considered invisible
79int threshold;
80
81float fov = 50.0f;
82
83int assumedVisibleFrames = 10;
84int maxBatchSize = 50;
85
86int trianglesPerVirtualLeaf = INITIAL_TRIANGLES_PER_VIRTUAL_LEAVES;
87
88SceneQuery *sceneQuery = NULL;
89RenderQueue *renderQueue = NULL;
90
91/// these values get scaled with the frame rate
92static float keyForwardMotion = 30.0f;
93static float keyRotation = 1.5f;
94
95/// elapsed time in milliseconds
96double elapsedTime = 1000.0f;
97double algTime = 1000.0f;
98
99static int winWidth = 1024;
100static int winHeight = 768;
101static float winAspectRatio = 1.0f;
102
103double accumulatedTime = 1000;
104float fps = 1e3f;
105
106float myfar = 0;
107
108glfont::GLFont myfont;
109
110// rendertexture
111static int texWidth = 1024;
112static int texHeight = 768;
113//static int texWidth = 2048;
114//static int texHeight = 2048;
115
116int renderedObjects = 0;
117int renderedNodes = 0;
118int renderedTriangles = 0;
119
120int issuedQueries = 0;
121int traversedNodes = 0;
122int frustumCulledNodes = 0;
123int queryCulledNodes = 0;
124int stateChanges = 0;
125int numBatches = 0;
126
127bool showHelp = false;
128bool showStatistics = false;
129bool showOptions = false;
130bool showBoundingVolumes = false;
131bool visMode = false;
132
133// mouse navigation state
134int xEyeBegin = 0;
135int yEyeBegin = 0;
136int yMotionBegin = 0;
137int verticalMotionBegin = 0;
138int horizontalMotionBegin = 0;
139
140bool useOptimization = false;
141bool useTightBounds = true;
142bool useRenderQueue = true;
143bool useMultiQueries = true;
144bool flyMode = true;
145
146SceneEntityContainer skyGeometry;
147
148bool leftKeyPressed = false;
149bool rightKeyPressed = false;
150bool upKeyPressed = false;
151bool downKeyPressed = false;
152bool nineKeyPressed = false;
153bool eightKeyPressed = false;
154
155bool useSsao = false;
156
157bool showAlgorithmTime = false;
158
159GLubyte *randomNormals = NULL;
160
161PerfTimer frameTimer, algTimer;
162
163int renderType = RenderState::FIXED;
164
165PerformanceGraph *perfGraph = NULL;
166
167bool useFullScreen = false;
168
169
170// ssao number of samples
171#define NUM_SAMPLES 8
172
173// ssao random spherical samples
174static float samples[NUM_SAMPLES * 2];
175
176
177// function forward declarations
178void InitExtensions();
179void DisplayVisualization();
180void InitGLstate();
181void InitRenderTexture();
182void InitCg();
183void CleanUp();
184void SetupEyeView();
185void UpdateEyeMtx();
186void SetupLighting();
187void DisplayStats();
188void Output(int x, int y, const char *string);
189void DrawHelpMessage();
190void RenderSky();
191void RenderVisibleObjects();
192
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);
207void ResetTraverser();
208
209void KeyHorizontalMotion(float shift);
210void KeyVerticalMotion(float shift);
211
212void PlaceViewer(const Vector3 &oldPos);
213void DisplayRenderTexture();
214
215
216inline float KeyRotationAngle() { return keyRotation * elapsedTime * 1e-3f; }
217inline float KeyShift() { return keyForwardMotion * elapsedTime * 1e-3f; }
218
219void InitFBO();
220
221void GenerateSamples();
222
223void CreateNoiseTex2D();
224
225void ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br);
226
227void GenerateSamples();
228
229
230GLenum mrt[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_COLOR_ATTACHMENT2_EXT};
231
232
233/////////
234//-- cg stuff
235
236static CGcontext sCgContext = NULL;
237static CGprogram sCgMrtVertexProgram = NULL;
238static CGprogram sCgSsaoProgram = NULL;
239static CGprogram sCgDeferredProgram = NULL;
240
241static CGparameter sColorsTexParam;
242static CGparameter sPositionsTexParam;
243static CGparameter sNormalsTexParam;
244//static CGparameter sNoiseTexParam;
245
246static CGparameter sColorsTexParamSsao;
247static CGparameter sPositionsTexParamSsao;
248static CGparameter sNormalsTexParamSsao;
249static CGparameter sNoiseTexParamSsao;
250
251static CGparameter sModelViewProjMatrixParam;
252//static CGparameter sModelMatrixParam;
253static CGparameter sMaxDepthParam;
254static CGparameter sMaxDepthParamTex;
255
256//static CGparameter sSamplesParam;
257static CGparameter sSamplesParamSsao;
258
259
260
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
289int main(int argc, char* argv[])
290{
291        int returnCode = 0;
292
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);
300        env.GetFloatParam(string("keyRotation"), keyRotation);
301
302        env.GetIntParam(string("winWidth"), winWidth);
303        env.GetIntParam(string("winHeight"), winHeight);
304
305        env.GetBoolParam(string("useFullScreen"), useFullScreen);
306
307        //env.GetIntParam(string("numSssaoSamples"), numSsaoSamples);
308
309        Vector3 camPos;
310        env.GetVectorParam(string("camPosition"), camPos);
311
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
325        ///////////////////////////
326
327        camera = new Camera(winWidth, winHeight, fov);
328        camera->SetNear(nearDist);
329       
330        camera->Pitch(-M_PI * 0.5);
331        camera->SetPosition(camPos);
332
333        visCamera = new Camera(winWidth, winHeight, fov);
334
335        visCamera->SetNear(0.0f);
336        visCamera->Yaw(.5 * M_PI);
337
338        renderQueue = new RenderQueue(&state, camera);
339
340        glutInitWindowSize(winWidth, winHeight);
341        glutInit(&argc, argv);
342        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
343
344        if (!useFullScreen)
345                glutCreateWindow("FriendlyCulling");
346        else
347        {
348                glutGameModeString( "1024x768:32@75" );
349                glutEnterGameMode();
350        }
351
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
362        // initialise gl graphics
363
364        InitExtensions();
365        InitGLstate();
366       
367        InitFBO();
368       
369        LeftMotion(0, 0);
370        MiddleMotion(0, 0);
371
372        perfGraph = new PerformanceGraph(1000);
373
374        loader = new ResourceManager();
375
376        //const string filename("data/city/model/city.dem");
377        const string filename = string(model_path + "city.dem");
378
379        if (loader->Load(filename, sceneEntities))
380                cout << "scene " << filename << " loaded" << endl;
381        else
382        {
383                cerr << "loading scene " << filename << " failed" << endl;
384                CleanUp();
385                exit(0);
386        }
387
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
401        const string bvh_filename = string(model_path + "city.bvh");
402        BvhLoader bvhLoader;
403        bvh = bvhLoader.Load(bvh_filename, sceneEntities);
404
405        if (!bvh)
406        {
407                cerr << "loading bvh " << bvh_filename << " failed" << endl;
408                CleanUp();
409                exit(0);
410        }
411
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       
418        InitCg();
419
420        // create noise texture for ssao
421        CreateNoiseTex2D();
422
423        // init render traverser
424        ResetTraverser();
425
426
427        visualization = new Visualization(bvh, camera, NULL, &state);
428
429        sceneQuery = new SceneQuery(bvh->GetBox(), traverser);
430
431
432        glutMainLoop();
433
434        // clean up
435        CleanUp();
436
437        return 0;
438}
439
440
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
452        RenderState::sCgFragmentProfile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
453        //assert(sCgFragmentProfile != CG_PROFILE_UNKNOWN);
454        cgGLSetOptimalOptions(RenderState::sCgFragmentProfile);
455
456        RenderState::sCgVertexProfile = cgGLGetLatestProfile(CG_GL_VERTEX);
457        cgGLSetOptimalOptions(RenderState::sCgVertexProfile);
458
459        sCgMrtVertexProgram =
460                cgCreateProgramFromFile(sCgContext,
461                                                                CG_SOURCE,
462                                                                "src/shaders/mrt.cg",
463                                                                RenderState::sCgVertexProfile,
464                                                                "vtx",
465                                                                NULL);
466
467        if (sCgMrtVertexProgram != NULL)
468        {
469                cgGLLoadProgram(sCgMrtVertexProgram);
470
471                SceneEntity::sModelMatrixParam = cgGetNamedParameter(sCgMrtVertexProgram, "ModelMatrix");
472                sModelViewProjMatrixParam = cgGetNamedParameter(sCgMrtVertexProgram, "ModelViewProj");
473        }
474
475        RenderState::sCgMrtFragmentTexProgram =
476                cgCreateProgramFromFile(sCgContext,
477                                                                CG_SOURCE,
478                                                                "src/shaders/mrt.cg",
479                                                                RenderState::sCgFragmentProfile,
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");
489                Material::sAmbientTexParam = cgGetNamedParameter(RenderState::sCgMrtFragmentTexProgram, "ambient");
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,
501                                                                "frag",
502                                                                NULL);
503
504        if (RenderState::sCgMrtFragmentProgram != NULL)
505        {
506                cgGLLoadProgram(RenderState::sCgMrtFragmentProgram);
507
508                sMaxDepthParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "maxDepth");
509                Material::sDiffuseParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "diffuse");
510                Material::sAmbientParam = cgGetNamedParameter(RenderState::sCgMrtFragmentProgram, "ambient");
511
512                cgGLSetParameter1f(sMaxDepthParam, 10.0f / myfar);
513        }
514        else
515                cerr << "fragment program failed to load" << endl;
516
517        PrintGLerror("test");
518
519
520        ///////////////
521
522        sCgSsaoProgram =
523                cgCreateProgramFromFile(sCgContext,
524                                                                CG_SOURCE,
525                                                                "src/shaders/deferred.cg",
526                                                                RenderState::sCgFragmentProfile,
527                                                                "main_ssao",
528                                                                NULL);
529
530        if (sCgSsaoProgram != NULL)
531        {
532                cgGLLoadProgram(sCgSsaoProgram);
533
534                // we need size of texture for scaling
535                sPositionsTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "positions"); 
536                sColorsTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "colors"); 
537                sNormalsTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "normals"); 
538                sNoiseTexParamSsao = cgGetNamedParameter(sCgSsaoProgram, "noiseTexture");
539                cgGLDisableTextureParameter(sNoiseTexParamSsao);
540
541                sSamplesParamSsao = cgGetNamedParameter(sCgSsaoProgram, "samples");
542                cgGLSetParameterArray2f(sSamplesParamSsao, 0, NUM_SAMPLES, (const float *)samples);
543        }
544        else
545                cerr << "ssao program failed to load" << endl;
546
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
569        PrintGLerror("init");
570
571        cout << "cg initialised" << endl;
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()
610{
611        glGenFramebuffersEXT(1, &fbo);
612        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
613
614       
615        ////////////
616        //-- colors buffer
617
618        glGenRenderbuffersEXT(1, &colorsBuffer);
619        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, colorsBuffer);
620       
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);
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
630        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
631        glGenerateMipmapEXT(GL_TEXTURE_2D);
632        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, colorsTex, 0);
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
640
641        //////////
642        //-- positions buffer
643
644        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
645        glGenRenderbuffersEXT(1, &positionsBuffer);
646        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, positionsBuffer);
647        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA32F_ARB, texWidth, texHeight);
648
649        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_RENDERBUFFER_EXT, positionsBuffer);
650
651        glGenTextures(1, &positionsTex);
652        glBindTexture(GL_TEXTURE_2D, positionsTex);
653        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB,  texWidth, texHeight, 0, GL_RGBA, GL_FLOAT, NULL);
654        //glGenerateMipmapEXT(GL_TEXTURE_2D);
655        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, positionsTex, 0);
656
657        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
658        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
659
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);
662
663        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
664       
665       
666        ////////
667        //-- normals buffer
668
669        glGenRenderbuffersEXT(1, &normalsBuffer);
670        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, normalsBuffer);
671        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, texWidth, texHeight);
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);
677        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8,  texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
678        //glGenerateMipmapEXT(GL_TEXTURE_2D);
679        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT2_EXT, GL_TEXTURE_2D, normalsTex, 0);
680
681        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
682        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
683
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
689
690        ///////////
691        //-- create depth buffer
692
693        glGenRenderbuffersEXT(1, &depthBuffer);
694        glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depthBuffer);
695        glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, texWidth, texHeight);
696        glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthBuffer);
697
698       
699        PrintFBOStatus(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT));
700       
701        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
702
703        PrintGLerror("fbo");
704}
705
706
707bool InitFont(void)
708{
709        glEnable(GL_TEXTURE_2D);
710
711        glGenTextures(1, &fontTex);
712        glBindTexture(GL_TEXTURE_2D, fontTex);
713        if (!myfont.Create("data/fonts/verdana.glf", fontTex))
714                return false;
715
716        glDisable(GL_TEXTURE_2D);
717       
718        return true;
719}
720
721
722void InitGLstate()
723{
724        glClearColor(0.5f, 0.5f, 0.8f, 0.0f);
725       
726        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
727        glPixelStorei(GL_PACK_ALIGNMENT,1);
728       
729        glDepthFunc(GL_LESS);
730        glEnable(GL_DEPTH_TEST);
731
732        SetupLighting();
733
734        glColor3f(1.0f, 1.0f, 1.0f);
735        glShadeModel(GL_SMOOTH);
736       
737        glMaterialf(GL_FRONT, GL_SHININESS, 64);
738        glEnable(GL_NORMALIZE);
739               
740        //glEnable(GL_ALPHA_TEST);
741        glDisable(GL_ALPHA_TEST);
742        glAlphaFunc(GL_GEQUAL, 0.5f);
743
744        glFrontFace(GL_CCW);
745        glCullFace(GL_BACK);
746        glEnable(GL_CULL_FACE);
747        //glDisable(GL_CULL_FACE);
748        glDisable(GL_TEXTURE_2D);
749
750        GLfloat ambientColor[] = {0.5, 0.5, 0.5, 1.0};
751        GLfloat diffuseColor[] = {1.0, 0.0, 0.0, 1.0};
752        GLfloat specularColor[] = {0.0, 0.0, 0.0, 1.0};
753
754        glMaterialfv(GL_FRONT, GL_AMBIENT, ambientColor);
755        glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseColor);
756        glMaterialfv(GL_FRONT, GL_SPECULAR, specularColor);
757
758        glDepthFunc(GL_LESS);
759
760        if (!InitFont())
761                cerr << "font creation failed" << endl;
762        else
763                cout << "successfully created font" << endl;
764}
765
766
767void DrawHelpMessage()
768{
769        const char *message[] =
770        {
771                "Help information",
772                "",
773                "'F1'           - shows/dismisses this message",
774                "'F2'           - shows/hides bird eye view",
775                "'F3'           - shows/hides bounds (boxes or tight bounds)",
776                "'F4',          - shows/hides parameters",
777                "'F5'           - shows/hides statistics",
778                "'F6',          - toggles between fly/walkmode",
779                "'F7',          - cycles throw render modes",
780                "'F8',          - enables/disables ambient occlusion (only deferred)",
781                "'F9',          - shows pure algorithm render time (using glFinish)",
782                "'SPACE'        - cycles through occlusion culling algorithms",
783                "",
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",
789                "",
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",
794                "",
795                "'R'            - use render queue",
796                "'B'            - use tight bounds",
797                "'M'            - use multiqueries",
798                "'O'            - use CHC optimization (geometry queries for leaves)",
799                0,
800        };
801       
802       
803        glColor4f(0.0f, 1.0f , 0.0f, 0.2f); // 20% green.
804
805        glRecti(30, 30, winWidth - 30, winHeight - 30);
806
807        glEnd();
808
809        glColor3f(1.0f, 1.0f, 1.0f);
810       
811        glEnable(GL_TEXTURE_2D);
812        myfont.Begin();
813
814        int x = 40, y = 30;
815
816        for(int i = 0; message[i] != 0; ++ i)
817        {
818                if(message[i][0] == '\0')
819                {
820                        y += 15;
821                }
822                else
823                {
824                        myfont.DrawString(message[i], x, winHeight - y);
825                        y += 25;
826                }
827        }
828        glDisable(GL_TEXTURE_2D);
829}
830
831
832void ResetTraverser()
833{
834        DEL_PTR(traverser);
835
836        bvh->ResetNodeClassifications();
837
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;
849        case RenderTraverser::CHCPLUSPLUS:
850                traverser = new CHCPlusPlusTraverser();
851                break;
852       
853        default:
854                traverser = new FrustumCullingTraverser();
855        }
856
857        traverser->SetCamera(camera);
858        traverser->SetHierarchy(bvh);
859        traverser->SetRenderQueue(renderQueue);
860        traverser->SetRenderState(&state);
861        traverser->SetUseOptimization(useOptimization);
862        traverser->SetUseRenderQueue(useRenderQueue);
863        traverser->SetVisibilityThreshold(threshold);
864        traverser->SetAssumedVisibleFrames(assumedVisibleFrames);
865        traverser->SetMaxBatchSize(maxBatchSize);
866        traverser->SetUseMultiQueries(useMultiQueries);
867        traverser->SetUseTightBounds(useTightBounds);
868        traverser->SetUseDepthPass(renderType == RenderState::DEPTH_PASS);
869        traverser->SetRenderQueue(renderQueue);
870}
871
872
873void SetupLighting()
874{
875        glEnable(GL_LIGHTING);
876        glEnable(GL_LIGHT0);
877        glEnable(GL_LIGHT1);
878       
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           
883        GLfloat lmodel_ambient[] = {0.3f, 0.3f, 0.3f, 1.0f};
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
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};
897
898        glLightfv(GL_LIGHT1, GL_AMBIENT, ambient1);
899        glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1);
900        glLightfv(GL_LIGHT1, GL_SPECULAR, specular1);
901
902       
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};
909        glLightfv(GL_LIGHT1, GL_POSITION, position1);
910
911        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
912        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
913        glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL_EXT, GL_SINGLE_COLOR_EXT);
914}
915
916
917void SetupEyeView()
918{
919        glMatrixMode(GL_PROJECTION);
920        glLoadIdentity();
921
922        gluPerspective(fov, 1.0f / winAspectRatio, nearDist, myfar);
923
924        glMatrixMode(GL_MODELVIEW);
925        glLoadIdentity();
926        camera->SetupCameraView();
927
928        GLfloat position[] = {0.8f, -1.0f, 0.7f, 0.0f};
929        glLightfv(GL_LIGHT0, GL_POSITION, position);
930
931        GLfloat position1[] = {-0.5f, 0.5f, 0.4f, 0.0f};
932        glLightfv(GL_LIGHT1, GL_POSITION, position1);
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        }       
945}
946
947
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
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
971void Display()
972{       
973        glFlush();
974        elapsedTime = frameTimer.Elapsedms();
975
976        // take time from last frame
977        frameTimer.Start();
978
979        Vector3 oldPos = camera->GetPosition();
980
981        if (leftKeyPressed)
982                camera->Pitch(KeyRotationAngle());
983        if (rightKeyPressed)
984                camera->Pitch(-KeyRotationAngle());
985        if (upKeyPressed)
986                KeyHorizontalMotion(KeyShift());
987        if (downKeyPressed)
988                KeyHorizontalMotion(-KeyShift());
989        if (eightKeyPressed)
990                KeyVerticalMotion(-KeyShift());
991        if (nineKeyPressed)
992                KeyVerticalMotion(KeyShift());
993
994        // place view on ground
995        if (!flyMode) PlaceViewer(oldPos);
996
997        if (showAlgorithmTime)
998        {
999                glFinish();
1000                algTimer.Start();
1001        }
1002       
1003        // render without shading
1004        switch (renderType)
1005        {
1006        case RenderState::FIXED:
1007       
1008                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1009
1010                state.SetRenderType(RenderState::FIXED);
1011                glEnable(GL_LIGHTING);
1012
1013                cgGLDisableProfile(RenderState::sCgFragmentProfile);
1014                cgGLDisableProfile(RenderState::sCgVertexProfile);
1015
1016                glDrawBuffers(1, mrt);
1017
1018                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1019
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);
1030       
1031                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1032
1033                glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
1034
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
1055                glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1056
1057                break;
1058        }
1059
1060
1061        glDepthFunc(GL_LESS);
1062
1063        glDisable(GL_TEXTURE_2D);
1064        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1065               
1066
1067        // bring eye modelview matrix up-to-date
1068        SetupEyeView();
1069
1070
1071        // actually render the scene geometry using one of the specified algorithms
1072        traverser->RenderScene();
1073
1074
1075
1076        /////////
1077        //-- do the rest of the rendering
1078
1079        glEnableClientState(GL_VERTEX_ARRAY);
1080        glEnableClientState(GL_NORMAL_ARRAY);
1081
1082
1083        // reset depth pass and render visible objects
1084        if (renderType == RenderState::DEPTH_PASS)
1085        {
1086                glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1087                RenderVisibleObjects();
1088        }
1089       
1090
1091        ///////////////
1092        //-- render sky
1093
1094        RenderSky();
1095
1096        state.Reset();
1097
1098        glDisableClientState(GL_VERTEX_ARRAY);
1099        glDisableClientState(GL_NORMAL_ARRAY);
1100
1101        if (renderType == RenderState::DEFERRED)
1102        {
1103                glPopAttrib();
1104                glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
1105
1106                cgGLDisableProfile(RenderState::sCgVertexProfile);
1107                cgGLDisableProfile(RenderState::sCgFragmentProfile);
1108
1109                glDrawBuffers(1, mrt);
1110
1111                DisplayRenderTexture();
1112        }
1113
1114       
1115        ///////////
1116
1117        state.SetRenderType(RenderState::FIXED);
1118
1119        if (showAlgorithmTime)
1120        {
1121                glFinish();
1122
1123                algTime = algTimer.Elapsedms();
1124                perfGraph->AddData(algTime);
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                */
1146                perfGraph->Draw();
1147        }
1148        else
1149        {
1150                if (visMode) DisplayVisualization();
1151        }
1152
1153        DisplayStats();
1154
1155        glutSwapBuffers();
1156}
1157
1158
1159#pragma warning( disable : 4100 )
1160void KeyBoard(unsigned char c, int x, int y)
1161{
1162        switch(c)
1163        {
1164        case 27:
1165                CleanUp();
1166                exit(0);
1167                break;
1168        case 32: //space
1169                renderMode = (renderMode + 1) % RenderTraverser::NUM_TRAVERSAL_TYPES;
1170                ResetTraverser();
1171                break;
1172        case 'h':
1173        case 'H':
1174                showHelp = !showHelp;
1175                break;
1176        case '+':
1177                maxBatchSize += 10;
1178                traverser->SetMaxBatchSize(maxBatchSize);
1179                break;
1180        case '-':
1181                maxBatchSize -= 10;
1182                if (maxBatchSize < 0) maxBatchSize = 1;
1183                traverser->SetMaxBatchSize(maxBatchSize);               
1184                break;
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;
1199        case '8':
1200                        eightKeyPressed = true;
1201                        break;
1202        case '9':
1203                        nineKeyPressed = true;
1204                        break;
1205        case 'o':
1206        case 'O':
1207                useOptimization = !useOptimization;
1208                traverser->SetUseOptimization(useOptimization);
1209                break;
1210        case 'a':
1211        case 'A':
1212                        leftKeyPressed = true;
1213                break;
1214        case 'd':
1215        case 'D':
1216                        rightKeyPressed = true;
1217                break;
1218        case 'w':
1219        case 'W':
1220                        upKeyPressed = true;
1221                break;
1222        case 's':
1223        case 'S':
1224                        downKeyPressed = true;
1225                break;
1226        case 'r':
1227        case 'R':
1228                {
1229                        useRenderQueue = !useRenderQueue;
1230                        traverser->SetUseRenderQueue(useRenderQueue);
1231                }
1232                break;
1233        case 'b':
1234        case 'B':
1235                {
1236                        useTightBounds = !useTightBounds;
1237                        traverser->SetUseTightBounds(useTightBounds);
1238                }
1239                break;
1240        case '4':
1241                if (trianglesPerVirtualLeaf >= 100)
1242                        trianglesPerVirtualLeaf -= 100;
1243
1244                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1245                break;
1246        case '5':
1247                trianglesPerVirtualLeaf += 100;
1248                bvh->SetVirtualLeaves(trianglesPerVirtualLeaf);
1249                break;
1250        default:
1251                return;
1252        }
1253
1254        glutPostRedisplay();
1255}
1256
1257
1258void SpecialKeyUp(int c, int x, int y)
1259{
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;
1297        case 'S':
1298        case 's':
1299                downKeyPressed = false;
1300                break;
1301        case '8':
1302                eightKeyPressed = false;
1303                break;
1304       
1305        case '9':
1306                nineKeyPressed = false;
1307                break;
1308       
1309        default:
1310                return;
1311        }
1312        //glutPostRedisplay();
1313}
1314
1315
1316void Special(int c, int x, int y)
1317{
1318        switch(c)
1319        {
1320        case GLUT_KEY_F1:
1321                showHelp = !showHelp;
1322                break;
1323        case GLUT_KEY_F2:
1324                visMode = !visMode;
1325                break;
1326        case GLUT_KEY_F3:
1327                showBoundingVolumes = !showBoundingVolumes;
1328                traverser->SetShowBounds(showBoundingVolumes);
1329                break;
1330        case GLUT_KEY_F4:
1331                showOptions = !showOptions;
1332                break;
1333        case GLUT_KEY_F5:
1334                showStatistics = !showStatistics;
1335                break;
1336        case GLUT_KEY_F6:
1337                flyMode = !flyMode;
1338                break;
1339        case GLUT_KEY_F7:
1340
1341                renderType = (renderType + 1) % 3;
1342                traverser->SetUseDepthPass(renderType == RenderState::DEPTH_PASS);
1343               
1344                break;
1345        case GLUT_KEY_F8:
1346                useSsao = !useSsao;
1347                break;
1348        case GLUT_KEY_F9:
1349                showAlgorithmTime = !showAlgorithmTime;
1350                break;
1351
1352        case GLUT_KEY_LEFT:
1353                {
1354                        leftKeyPressed = true;
1355                        camera->Pitch(KeyRotationAngle());
1356                }
1357                break;
1358        case GLUT_KEY_RIGHT:
1359                {
1360                        rightKeyPressed = true;
1361                        camera->Pitch(-KeyRotationAngle());
1362                }
1363                break;
1364        case GLUT_KEY_UP:
1365                {
1366                        upKeyPressed = true;
1367                        KeyHorizontalMotion(KeyShift());
1368                }
1369                break;
1370        case GLUT_KEY_DOWN:
1371                {
1372                        downKeyPressed = true;
1373                        KeyHorizontalMotion(-KeyShift());
1374                }
1375                break;
1376        default:
1377                return;
1378
1379        }
1380
1381        glutPostRedisplay();
1382}
1383
1384#pragma warning( default : 4100 )
1385
1386
1387void Reshape(int w, int h)
1388{
1389        winAspectRatio = 1.0f;
1390
1391        glViewport(0, 0, w, h);
1392       
1393        winWidth = w;
1394        winHeight = h;
1395
1396        if (w) winAspectRatio = (float) h / (float) w;
1397
1398        glMatrixMode(GL_PROJECTION);
1399        glLoadIdentity();
1400
1401        gluPerspective(fov, 1.0f / winAspectRatio, nearDist, myfar);
1402
1403        glMatrixMode(GL_MODELVIEW);
1404
1405        glutPostRedisplay();
1406}
1407
1408
1409void Mouse(int button, int state, int x, int y)
1410{
1411        if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN))
1412        {
1413                xEyeBegin = x;
1414                yMotionBegin = y;
1415
1416                glutMotionFunc(LeftMotion);
1417        }
1418        else if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN))
1419        {
1420                xEyeBegin = x;
1421                yEyeBegin = y;
1422                yMotionBegin = y;
1423
1424                glutMotionFunc(RightMotion);
1425        }
1426        else if ((button == GLUT_MIDDLE_BUTTON) && (state == GLUT_DOWN))
1427        {
1428                horizontalMotionBegin = x;
1429                verticalMotionBegin = y;
1430                glutMotionFunc(MiddleMotion);
1431        }
1432
1433        glutPostRedisplay();
1434}
1435
1436
1437/**     rotation for left/right mouse drag
1438        motion for up/down mouse drag
1439*/
1440void LeftMotion(int x, int y)
1441{
1442        Vector3 viewDir = camera->GetDirection();
1443        Vector3 pos = camera->GetPosition();
1444
1445        // don't move in the vertical direction
1446        Vector3 horView(viewDir[0], viewDir[1], 0);
1447       
1448        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
1449
1450        camera->Pitch(eyeXAngle);
1451
1452        pos += horView * (yMotionBegin - y) * 0.2f;
1453       
1454        camera->SetPosition(pos);
1455       
1456        xEyeBegin = x;
1457        yMotionBegin = y;
1458
1459        glutPostRedisplay();
1460}
1461
1462
1463/**     rotation for left / right mouse drag
1464        motion for up / down mouse drag
1465*/
1466void RightMotion(int x, int y)
1467{
1468        float eyeXAngle = 0.2f *  M_PI * (xEyeBegin - x) / 180.0;
1469        float eyeYAngle = -0.2f *  M_PI * (yEyeBegin - y) / 180.0;
1470
1471        camera->Yaw(eyeYAngle);
1472        camera->Pitch(eyeXAngle);
1473
1474        xEyeBegin = x;
1475        yEyeBegin = y;
1476
1477        glutPostRedisplay();
1478}
1479
1480
1481// strafe
1482void MiddleMotion(int x, int y)
1483{
1484        Vector3 viewDir = camera->GetDirection();
1485        Vector3 pos = camera->GetPosition();
1486
1487        // the 90 degree rotated view vector
1488        // y zero so we don't move in the vertical
1489        Vector3 rVec(viewDir[0], viewDir[1], 0);
1490       
1491        Matrix4x4 rot = RotationZMatrix(M_PI * 0.5f);
1492        rVec = rot * rVec;
1493       
1494        pos -= rVec * (x - horizontalMotionBegin) * 0.1f;
1495        pos[2] += (verticalMotionBegin - y) * 0.1f;
1496
1497        camera->SetPosition(pos);
1498
1499        horizontalMotionBegin = x;
1500        verticalMotionBegin = y;
1501
1502        glutPostRedisplay();
1503}
1504
1505
1506void InitExtensions(void)
1507{
1508        GLenum err = glewInit();
1509
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        }
1516        if  (!GLEW_ARB_occlusion_query)
1517        {
1518                printf("I require the GL_ARB_occlusion_query to work.\n");
1519                exit(1);
1520        }
1521}
1522
1523
1524void Begin2D()
1525{
1526        glDisable(GL_LIGHTING);
1527        glDisable(GL_DEPTH_TEST);
1528
1529        glMatrixMode(GL_PROJECTION);
1530        glPushMatrix();
1531        glLoadIdentity();
1532        gluOrtho2D(0, winWidth, 0, winHeight);
1533
1534        glMatrixMode(GL_MODELVIEW);
1535        glPushMatrix();
1536        glLoadIdentity();
1537}
1538
1539
1540void End2D()
1541{
1542        glPopMatrix();
1543        glMatrixMode(GL_MODELVIEW);
1544        glPopMatrix();
1545
1546        glEnable(GL_LIGHTING);
1547        glEnable(GL_DEPTH_TEST);
1548}
1549
1550
1551// displays the visualisation of culling algorithm
1552void DisplayVisualization()
1553{
1554        visualization->SetFrameId(traverser->GetCurrentFrameId());
1555       
1556        Begin2D();
1557        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1558        glEnable(GL_BLEND);
1559        glColor4f(0.0f ,0.0f, 0.0f, 0.5f);
1560
1561        glRecti(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth, winHeight);
1562        glDisable(GL_BLEND);
1563        End2D();
1564       
1565       
1566        AxisAlignedBox3 box = bvh->GetBox();
1567
1568        // set far for viz
1569        camera->SetFar(0.35f * Magnitude(box.Diagonal()));
1570
1571        const float offs = box.Size().x * 0.3f;
1572        //const float yoffs = box.Size().y * 0.5f;
1573
1574        Vector3 pos = camera->GetPosition();
1575
1576        Vector3 vizpos = Vector3(box.Min().x + 20, box.Min().y + 500, box.Min().z + box.Size().z * 50);
1577       
1578        visCamera->SetPosition(vizpos);
1579       
1580        glViewport(winWidth - winWidth / 3, winHeight - winHeight / 3, winWidth / 3, winHeight / 3);
1581
1582        glMatrixMode(GL_PROJECTION);
1583        glLoadIdentity();
1584       
1585        glOrtho(-offs, offs, -offs, offs, 0.0f, box.Size().z * 100.0f);
1586
1587        glMatrixMode(GL_MODELVIEW);
1588
1589        visCamera->SetupCameraView();
1590
1591        Matrix4x4 rotZ = RotationZMatrix(-camera->GetPitch());
1592        glMultMatrixf((float *)rotZ.x);
1593
1594        glTranslatef(-pos.x, -pos.y, -pos.z);
1595
1596
1597        GLfloat position[] = {0.8f, 1.0f, 1.5f, 0.0f};
1598        glLightfv(GL_LIGHT0, GL_POSITION, position);
1599
1600        GLfloat position1[] = {bvh->GetBox().Center().x, bvh->GetBox().Max().y, bvh->GetBox().Center().z, 1.0f};
1601        glLightfv(GL_LIGHT1, GL_POSITION, position1);
1602
1603        glClear(GL_DEPTH_BUFFER_BIT);
1604
1605
1606        ////////////
1607        //-- visualization of the occlusion culling
1608
1609        visualization->Render();
1610       
1611        // reset vp
1612        glViewport(0, 0, winWidth, winHeight);
1613}
1614
1615
1616// cleanup routine after the main loop
1617void CleanUp()
1618{
1619        DEL_PTR(traverser);
1620        DEL_PTR(sceneQuery);
1621        DEL_PTR(bvh);
1622        DEL_PTR(visualization);
1623        DEL_PTR(camera);
1624        DEL_PTR(loader);
1625        DEL_PTR(renderQueue);
1626        DEL_PTR(perfGraph);
1627
1628        if (sCgMrtVertexProgram)
1629                cgDestroyProgram(sCgMrtVertexProgram);
1630        if (RenderState::sCgMrtFragmentProgram)
1631                cgDestroyProgram(RenderState::sCgMrtFragmentProgram);
1632        if (RenderState::sCgMrtFragmentTexProgram)
1633                cgDestroyProgram(RenderState::sCgMrtFragmentTexProgram);
1634        if (sCgSsaoProgram)
1635                cgDestroyProgram(sCgSsaoProgram);
1636        if (sCgDeferredProgram)
1637                cgDestroyProgram(sCgDeferredProgram);
1638        if (sCgContext)
1639                cgDestroyContext(sCgContext);
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);
1651        glDeleteTextures(1, &fontTex);
1652}
1653
1654
1655// this function inserts a dezimal point after each 1000
1656void CalcDecimalPoint(string &str, int d, int len)
1657{
1658        static vector<int> numbers;
1659        numbers.clear();
1660
1661        static string shortStr;
1662        shortStr.clear();
1663
1664        static char hstr[100];
1665
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        {
1675                sprintf(hstr, "%d", numbers.back());
1676                shortStr.append(hstr);
1677        }
1678       
1679        for (int i = (int)numbers.size() - 2; i >= 0; i--)
1680        {
1681                sprintf(hstr, ",%03d", numbers[i]);
1682                shortStr.append(hstr);
1683        }
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);
1693}
1694
1695
1696void DisplayStats()
1697{
1698        static char msg[9][300];
1699
1700        static double frameTime = elapsedTime;
1701        static double renderTime = algTime;
1702
1703        const float expFactor = 0.1f;
1704
1705        // if some strange render time spike happened in this frame => don't count
1706        if (elapsedTime < 500) frameTime = elapsedTime * expFactor + (1.0f - expFactor) * elapsedTime;
1707       
1708        static float rTime = 1000.0f;
1709
1710        if (showAlgorithmTime)
1711        {
1712                if (algTime < 500) renderTime = algTime * expFactor + (1.0f - expFactor) * renderTime;
1713        }
1714
1715        accumulatedTime += elapsedTime;
1716
1717        if (accumulatedTime > 500) // update every fraction of a second
1718        {       
1719                accumulatedTime = 0;
1720
1721                if (frameTime) fps = 1e3f / (float)frameTime;
1722
1723                rTime = renderTime;
1724                renderedObjects = traverser->GetStats().mNumRenderedGeometry;
1725                renderedNodes = traverser->GetStats().mNumRenderedNodes;
1726                renderedTriangles = traverser->GetStats().mNumRenderedTriangles;
1727
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;
1733                numBatches = traverser->GetStats().mNumBatches;
1734        }
1735
1736
1737        Begin2D();
1738
1739        glEnable(GL_BLEND);
1740        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1741
1742        if (showHelp)
1743        {       
1744                DrawHelpMessage();
1745        }
1746        else
1747        {
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
1762                myfont.Begin();
1763
1764                if (showOptions)
1765                {
1766                        glColor3f(0.0f, 1.0f, 0.0f);
1767
1768                        int i = 0;
1769
1770                        static char *renderTypeStr[] = {"fixed function", "fixed function + depth pass", "deferred shading"};
1771       
1772                        sprintf(msg[i ++], "multiqueries: %d, tight bounds: %d, render queue: %d",
1773                                                        useMultiQueries, useTightBounds, useRenderQueue);
1774
1775                        sprintf(msg[i ++], "render technique: %s, SSAO: %d", renderTypeStr[renderType], useSsao);
1776
1777                        sprintf(msg[i ++], "triangles per virtual leaf: %5d", trianglesPerVirtualLeaf);
1778
1779                        sprintf(msg[i ++], "assumed visible frames: %4d, max batch size: %4d",
1780                                assumedVisibleFrames, maxBatchSize);
1781
1782                        for (int j = 0; j < 4; ++ j)
1783                                myfont.DrawString(msg[j], 10.0f, winHeight - 5 - j * 20);
1784                }
1785
1786                if (showStatistics)
1787                {
1788                        glColor3f(1.0f, 1.0f, 0.0f);
1789
1790                        string str;
1791                        string str2;
1792
1793                        int len = 10;
1794                        CalcDecimalPoint(str, renderedTriangles, len);
1795                        CalcDecimalPoint(str2, bvh->GetBvhStats().mTriangles, len);
1796
1797                        int i = 4;
1798
1799                        sprintf(msg[i ++], "rendered: %6d of %6d nodes, %s of %s triangles",
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)
1809                                myfont.DrawString(msg[j], 10.0f, winHeight - (j + 1) * 20);
1810                }
1811
1812                glColor3f(1.0f, 1.0f, 1.0f);
1813                static char *alg_str[] = {"Frustum Cull", "Stop and Wait", "CHC", "CHC ++"};
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                }
1823
1824                myfont.DrawString(msg[7], 1.3f, 690.0f, 760.0f);//, top_color, bottom_color);
1825               
1826                //sprintf(msg[8], "algorithm time: %6.1f ms", rTime);
1827                //myfont.DrawString(msg[8], 720.0f, 730.0f);           
1828        }
1829
1830        glDisable(GL_BLEND);
1831        glDisable(GL_TEXTURE_2D);
1832
1833        End2D();
1834}       
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);
1843}
1844
1845
1846void RenderVisibleObjects()
1847{
1848        state.SetRenderType(RenderState::FIXED);
1849        state.Reset();
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        }
1879}
1880
1881
1882void DisplayRenderTexture()
1883{
1884        glDisable(GL_ALPHA_TEST);
1885        glDisable(GL_TEXTURE_2D);
1886        glDisable(GL_LIGHTING);
1887       
1888        glMatrixMode(GL_PROJECTION);
1889        glPushMatrix();
1890        glLoadIdentity();
1891
1892        glMatrixMode(GL_MODELVIEW);
1893        glPushMatrix();
1894        glLoadIdentity();
1895
1896        const float offs = 0.5f;
1897       
1898        glOrtho(-offs, offs, -offs, offs, 0, 1);
1899       
1900        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1901
1902        cgGLEnableProfile(RenderState::sCgFragmentProfile);
1903
1904        if (useSsao)
1905        {
1906                cgGLBindProgram(sCgSsaoProgram);
1907               
1908                cgGLEnableTextureParameter(sPositionsTexParamSsao);
1909                cgGLSetTextureParameter(sPositionsTexParamSsao, positionsTex);
1910       
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);
1926       
1927                cgGLEnableTextureParameter(sColorsTexParam);
1928                cgGLSetTextureParameter(sColorsTexParam, colorsTex);
1929
1930                cgGLEnableTextureParameter(sNormalsTexParam);
1931                cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
1932        }
1933
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);
1940
1941        // note: slightly larger texture hides ambient occlusion error on border but costs resolution
1942        //float offs2 = 0.55f;
1943        float offs2 = 0.5f;
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);
1949
1950        glEnd();
1951
1952        cgGLDisableTextureParameter(sColorsTexParamSsao);
1953        cgGLDisableTextureParameter(sPositionsTexParamSsao);
1954        cgGLDisableTextureParameter(sNormalsTexParamSsao);
1955       
1956        if (useSsao)
1957                cgGLDisableTextureParameter(sNoiseTexParamSsao);
1958
1959        cgGLDisableProfile(RenderState::sCgFragmentProfile);
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
1970       
1971        PrintGLerror("displaytexture");
1972}
1973
1974
1975void GenerateSamples()
1976{
1977        float scale = 1.0f / (float)NUM_SAMPLES;
1978
1979        ////////
1980        //-- generate uniformly distributed spherical samples
1981
1982        for (int i = 0; i < NUM_SAMPLES; ++ i)
1983        {
1984                // create stratified samples over sphere
1985                const float rx = ((float)i + RandomValue(0, 1)) * scale;
1986                const float ry = ((float)i + RandomValue(0, 1)) * scale;
1987
1988                const float theta = 2.0f * acos(sqrt(1.0f - rx));
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
1993                //////
1994                //-- we sample in texture space => store 2D component
1995
1996                // q: project to plane or just drop z?
1997                Vector3 proj = unit / (1.0f + fabs(unit.z));
1998                //Vector3 proj = unit;
1999
2000                samples[i + 0] = proj.x;
2001                samples[i + 1] = proj.y;
2002                //cout << samples[i] << " " << samples[i + 1] << endl;
2003        }
2004}
2005
2006
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
2029void CreateNoiseTex2D()
2030{
2031        randomNormals = new GLubyte[texWidth * texHeight * 3];
2032
2033        for (int i = 0; i < texWidth * texHeight * 3; i += 3)
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
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;
2042        }
2043
2044        glEnable(GL_TEXTURE_2D);
2045        glGenTextures(1, &noiseTex);
2046        glBindTexture(GL_TEXTURE_2D, noiseTex);
2047               
2048        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2049        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2050        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
2051        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2052
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
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.