source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp @ 3021

Revision 3021, 42.0 KB checked in by mattausch, 16 years ago (diff)

removed leaks. added class for shaders

Line 
1#include "DeferredRenderer.h"
2#include "FrameBufferObject.h"
3#include "RenderState.h"
4#include "SampleGenerator.h"
5#include "Vector3.h"
6#include "Camera.h"
7#include "shaderenv.h"
8#include "Halton.h"
9#include "ShadowMapping.h"
10#include "Light.h"
11
12#include <IL/il.h>
13#include <assert.h>
14
15
16#ifdef _CRT_SET
17        #define _CRTDBG_MAP_ALLOC
18        #include <stdlib.h>
19        #include <crtdbg.h>
20
21        // redefine new operator
22        #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
23        #define new DEBUG_NEW
24#endif
25
26
27using namespace std;
28
29
30static void startil()
31{
32        ilInit();
33        assert(ilGetError() == IL_NO_ERROR);
34}
35
36
37static void stopil()
38{
39        ilShutDown();
40        assert(ilGetError() == IL_NO_ERROR);
41}
42
43namespace CHCDemoEngine
44{
45
46static CGprogram sCgSsaoProgram = NULL;
47static CGprogram sCgGiProgram = NULL;
48
49static CGprogram sCgDeferredProgram = NULL;
50static CGprogram sCgAntiAliasingProgram = NULL;
51static CGprogram sCgDeferredShadowProgram = NULL;
52
53static CGparameter sColorsTexCombineParam;
54static CGparameter sSsaoTexCombineParam;
55
56static CGparameter sColorsTexDeferredParam;
57static CGparameter sPositionsTexDeferredParam;
58static CGparameter sNormalsTexDeferredParam;
59
60static CGprogram sCgCombinedSsaoProgram = NULL;
61static CGprogram sCgCombinedIllumProgram = NULL;
62
63static CGparameter sColorsTexLogLumParam;
64
65static CGparameter sDownSampleOffsetParam;
66static CGparameter sFilterOffsetsParam;
67static CGparameter sFilterWeightsParam;
68
69static CGprogram sCgDownSampleProgram;
70static CGprogram sCgToneProgram;
71static CGprogram sCgLogLumProgram;
72
73
74ShaderContainer DeferredRenderer::sShaders;
75
76
77///////////////////////////////////////
78
79
80static CGparameter sColorsTexParam;
81static CGparameter sNormalsTexParam;
82
83static CGparameter sOldModelViewProjMatrixParam;
84static CGparameter sModelViewProjMatrixParam;
85static CGparameter sEyePosParam;
86static CGparameter sEyePosShadowParam;
87static CGparameter sSamplesParam;
88static CGparameter sOldTexParam;
89static CGparameter sNoiseTexParam;
90static CGparameter sTemporalCoherenceParam;
91
92
93///////////////////////////////////////
94
95
96static CGparameter sColorsTexGiParam;
97static CGparameter sNormalsTexGiParam;
98
99
100static CGparameter sOldModelViewProjMatrixGiParam;
101static CGparameter sModelViewProjMatrixGiParam;
102static CGparameter sSamplesGiParam;
103static CGparameter sOldSsaoTexGiParam;
104static CGparameter sOldIllumTexGiParam;
105static CGparameter sNoiseTexGiParam;
106static CGparameter sTemporalCoherenceGiParam;
107
108
109static CGparameter sColorsTexCombinedIllumParam;
110static CGparameter sSsaoTexCombinedIllumParam;
111static CGparameter sIllumTexCombinedIllumParam;
112
113static CGparameter sColorsTexCombinedSsaoParam;
114static CGparameter sSsaoTexCombinedSsaoParam;
115
116static CGparameter sTLParam;
117static CGparameter sTRParam;
118static CGparameter sBRParam;
119static CGparameter sBLParam;
120
121
122static CGparameter sTLGiParam;
123static CGparameter sTRGiParam;
124static CGparameter sBRGiParam;
125static CGparameter sBLGiParam;
126
127static CGparameter sEyePosGiParam;
128
129
130
131////////////
132
133static CGparameter sColorsTexAntiAliasingParam;
134static CGparameter sNormalsTexAntiAliasingParam;
135
136
137static CGparameter sShadowMapParam;
138static CGparameter sPositionsTexShadowParam; 
139static CGparameter sColorsTexShadowParam; 
140static CGparameter sNormalsTexShadowParam;
141
142static CGparameter sShadowMatrixParam;
143static CGparameter sSampleWidthParam;
144
145static CGparameter sNoiseTexShadowParam;
146static CGparameter sSamplesShadowParam;
147
148static CGparameter sLightDirParam;
149static CGparameter sLightDirShadowParam;
150static CGparameter sImageKeyParam;
151static CGparameter sMiddleGreyParam;
152static CGparameter sWhiteLumParam;
153
154
155static CGparameter sColorsTexInitialParam;
156static CGparameter sColorsTexToneParam;
157
158static CGparameter sColorsTexDownSampleParam;
159
160//#define USE_3D_SSAO
161
162
163static GLuint noiseTex = 0;
164
165// ssao random spherical samples
166#ifdef USE_3D_SSAO
167static Sample2 samples3[NUM_SAMPLES];
168#else
169static Sample2 samples2[NUM_SAMPLES];
170#endif
171
172// number of pcf tabs
173Sample2 pcfSamples[NUM_PCF_TABS];
174
175int DeferredRenderer::colorBufferIdx = 0;
176
177
178static void PrintGLerror(char *msg)
179{
180        GLenum errCode;
181        const GLubyte *errStr;
182       
183        if ((errCode = glGetError()) != GL_NO_ERROR)
184        {
185                errStr = gluErrorString(errCode);
186                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
187        }
188}
189
190static void ComputeSampleOffsets(float *sampleOffsets, int w, int h)
191{
192        /*
193        const float xoffs = 0.5f / w;
194        const float yoffs = 0.5f / h;
195
196        sampleOffsets[0] =  xoffs; sampleOffsets[1] =  yoffs;
197        sampleOffsets[2] =  xoffs; sampleOffsets[3] = -yoffs;
198        sampleOffsets[4] = -xoffs; sampleOffsets[5] = -yoffs;
199        sampleOffsets[6] = -xoffs; sampleOffsets[7] =  yoffs;
200        */
201        //const float xoffs = .5f / w;
202        //const float yoffs = .5f / h;
203       
204        const float xoffs = 1.0f / w;
205        const float yoffs = 1.0f / h;
206
207        int idx  = 0;
208
209        for (int x = -1; x <= 1; ++ x)
210        {
211                for (int y = -1; y <= 1; ++ y)
212                {
213                        sampleOffsets[idx + 0] = x * xoffs;
214                        sampleOffsets[idx + 1] = y * yoffs;
215
216                        idx += 2;
217                }
218        }
219}
220
221/** Generate poisson disc distributed sample points on the unit disc
222*/
223static void GenerateSamples(int sampling)
224{
225#ifdef USE_3D_SSAO
226
227        SphericalSampleGenerator sph(NUM_SAMPLES, 1.0f);
228        sph.Generate((float *)samples3);
229
230#else
231        switch (sampling)
232        {
233        case DeferredRenderer::SAMPLING_POISSON:
234                {
235                        PoissonDiscSampleGenerator2 poisson(NUM_SAMPLES, 1.0f);
236                        poisson.Generate((float *)samples2);
237                }
238                break;
239        case DeferredRenderer::SAMPLING_QUADRATIC:
240                {
241                        QuadraticDiscSampleGenerator2 g(NUM_SAMPLES, 1.0f);
242                        g.Generate((float *)samples2);
243                }
244                break;
245        default: // SAMPLING_DEFAULT
246
247                RandomSampleGenerator2 g(NUM_SAMPLES, 1.0f);
248                g.Generate((float *)samples2);
249        }
250#endif
251}
252
253
254static void CreateNoiseTex2D(int w, int h)
255{
256        //GLubyte *randomNormals = new GLubyte[mWidth * mHeight * 3];
257        float *randomNormals = new float[w * h * 3];
258
259        static HaltonSequence halton;
260        float r[2];
261
262        for (int i = 0; i < w * h * 3; i += 3)
263        {
264               
265#ifdef USE_3D_SSAO
266                //halton.GetNext(2, r);
267                r[0] = RandomValue(0, 1);
268                r[1] = RandomValue(0, 1);
269
270                const float theta = 2.0f * acos(sqrt(1.0f - r[0]));
271                const float phi = 2.0f * M_PI * r[1];
272
273                randomNormals[i + 0] = sin(theta) * cos(phi);
274                randomNormals[i + 1] = sin(theta) * sin(phi);
275                randomNormals[i + 2] = cos(theta);
276#else
277                // create random samples on a circle
278                r[0] = RandomValue(0, 1);
279                //halton.GetNext(1, r);
280
281                const float theta = 2.0f * acos(sqrt(1.0f - r[0]));
282               
283                randomNormals[i + 0] = cos(theta);
284                randomNormals[i + 1] = sin(theta);
285                randomNormals[i + 2] = 0;
286#endif
287        }
288
289        glEnable(GL_TEXTURE_2D);
290        glGenTextures(1, &noiseTex);
291        glBindTexture(GL_TEXTURE_2D, noiseTex);
292               
293        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
294        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
295        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
296        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
297
298        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGB, GL_FLOAT, randomNormals);
299
300        glBindTexture(GL_TEXTURE_2D, 0);
301        glDisable(GL_TEXTURE_2D);
302
303        delete [] randomNormals;
304
305        cout << "created noise texture" << endl;
306
307        PrintGLerror("noisetexture");
308}
309
310
311static void InitBuffer(FrameBufferObject *fbo, int index)
312{
313        // read the second buffer, write to the first buffer
314        fbo->Bind();
315        glDrawBuffers(1, mrt + index);
316
317        //glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
318        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
319
320        glEnd();
321
322        FrameBufferObject::Release();
323}
324
325
326DeferredRenderer::DeferredRenderer(int w, int h, Camera *cam, float scaleFactor):
327mWidth(w), mHeight(h),
328mCamera(cam),
329mUseTemporalCoherence(true),
330mRegenerateSamples(true),
331mSamplingMethod(SAMPLING_POISSON),
332mShadingMethod(DEFAULT),
333mIllumFboIndex(0)
334{
335        // create noise texture for ssao
336        CreateNoiseTex2D(w, h);
337
338
339        ///////////
340        //-- the flip-flop fbos
341
342        mIllumFbo = new FrameBufferObject(w / 2, h / 2, FrameBufferObject::DEPTH_NONE);
343        mFBOs.push_back(mIllumFbo);
344
345        for (int i = 0; i < 4; ++ i)
346        {
347                mIllumFbo->AddColorBuffer(ColorBufferObject::RGB_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
348                InitBuffer(mIllumFbo, i);
349        }
350
351        mDownSampleFbo = new FrameBufferObject(w / 2, h / 2, FrameBufferObject::DEPTH_NONE);
352        mDownSampleFbo->AddColorBuffer(ColorBufferObject::RGBA_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
353        mDownSampleFbo->AddColorBuffer(ColorBufferObject::RGB_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
354
355        mFBOs.push_back(mDownSampleFbo);
356}
357
358
359DeferredRenderer::~DeferredRenderer()
360{
361        CLEAR_CONTAINER(mFBOs);
362        glDeleteTextures(1, &noiseTex);
363}
364
365
366void DeferredRenderer::SetUseTemporalCoherence(bool temporal)
367{
368        mUseTemporalCoherence = temporal;
369}
370
371
372void DeferredRenderer::ReleaseCG()
373{
374        CLEAR_CONTAINER(sShaders);
375}
376
377
378void DeferredRenderer::InitCG(CGcontext context)
379{       
380        ShaderProgram *pr;
381
382
383        sCgDeferredProgram =
384                cgCreateProgramFromFile(context,
385                                                                CG_SOURCE,
386                                                                "src/shaders/deferred.cg",
387                                                                RenderState::sCgFragmentProfile,
388                                                                "main",
389                                                                NULL);
390
391        if (sCgDeferredProgram != NULL)
392        {
393                cgGLLoadProgram(sCgDeferredProgram);
394
395                // we need size of texture for scaling
396                sPositionsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "positions"); 
397                sColorsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "colors"); 
398                sNormalsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "normals");
399               
400                sLightDirParam = cgGetNamedParameter(sCgDeferredProgram, "lightDir");
401
402                pr = new ShaderProgram(sCgDeferredProgram);
403                sShaders.push_back(pr);
404        }
405        else
406                cerr << "deferred program failed to load" << endl;
407
408
409        ///////////////
410
411        sCgSsaoProgram =
412                cgCreateProgramFromFile(context,
413                                                                CG_SOURCE,
414#ifdef USE_3D_SSAO
415                                                                "src/shaders/ssao3d.cg",
416#else
417                                                                "src/shaders/ssao.cg",
418#endif
419                                                                RenderState::sCgFragmentProfile,
420                                                                "main",
421                                                                NULL);
422
423        if (sCgSsaoProgram != NULL)
424        {
425                cgGLLoadProgram(sCgSsaoProgram);
426
427                sColorsTexParam = cgGetNamedParameter(sCgSsaoProgram, "colors"); 
428                sEyePosParam = cgGetNamedParameter(sCgSsaoProgram, "eyePos");
429                sNormalsTexParam = cgGetNamedParameter(sCgSsaoProgram, "normals"); 
430                sNoiseTexParam = cgGetNamedParameter(sCgSsaoProgram, "noiseTexture");
431               
432                sOldModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "oldModelViewProj");
433                sModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "modelViewProj");
434                sTemporalCoherenceParam = cgGetNamedParameter(sCgSsaoProgram, "temporalCoherence");
435
436                sOldTexParam = cgGetNamedParameter(sCgSsaoProgram, "oldTex"); 
437                sSamplesParam = cgGetNamedParameter(sCgSsaoProgram, "samples");
438
439                sTLParam = cgGetNamedParameter(sCgSsaoProgram, "tl");
440                sTRParam = cgGetNamedParameter(sCgSsaoProgram, "tr");
441                sBRParam = cgGetNamedParameter(sCgSsaoProgram, "br");
442                sBLParam = cgGetNamedParameter(sCgSsaoProgram, "bl");
443
444                pr = new ShaderProgram(sCgSsaoProgram);
445                sShaders.push_back(pr);
446        }
447        else
448                cerr << "ssao program failed to load" << endl;
449
450        sCgGiProgram =
451                cgCreateProgramFromFile(context,
452                                                                CG_SOURCE,
453                                                                "src/shaders/globillum.cg",
454                                                                RenderState::sCgFragmentProfile,
455                                                                "main",
456                                                                NULL);
457
458        if (sCgGiProgram != NULL)
459        {
460                cgGLLoadProgram(sCgGiProgram);
461
462                // we need size of texture for scaling
463                sColorsTexGiParam = cgGetNamedParameter(sCgGiProgram, "colors"); 
464                sNormalsTexGiParam = cgGetNamedParameter(sCgGiProgram, "normals"); 
465               
466                sOldModelViewProjMatrixGiParam = cgGetNamedParameter(sCgGiProgram, "oldModelViewProj");
467                sModelViewProjMatrixGiParam = cgGetNamedParameter(sCgGiProgram, "modelViewProj");
468                sTemporalCoherenceGiParam = cgGetNamedParameter(sCgGiProgram, "temporalCoherence");
469
470                sNoiseTexGiParam = cgGetNamedParameter(sCgGiProgram, "noiseTexture");
471                sSamplesGiParam = cgGetNamedParameter(sCgGiProgram, "samples");
472               
473                sOldSsaoTexGiParam = cgGetNamedParameter(sCgGiProgram, "oldSsaoTex"); 
474                sOldIllumTexGiParam = cgGetNamedParameter(sCgGiProgram, "oldIllumTex");
475
476                sTLGiParam = cgGetNamedParameter(sCgGiProgram, "tl");
477                sTRGiParam = cgGetNamedParameter(sCgGiProgram, "tr");
478                sBRGiParam = cgGetNamedParameter(sCgGiProgram, "br");
479                sBLGiParam = cgGetNamedParameter(sCgGiProgram, "bl");
480
481                sEyePosGiParam = cgGetNamedParameter(sCgGiProgram, "eyePos");
482
483                pr = new ShaderProgram(sCgGiProgram);
484                sShaders.push_back(pr);
485        }
486        else
487                cerr << "globillum program failed to load" << endl;
488
489        sCgCombinedIllumProgram =
490                cgCreateProgramFromFile(context,
491                                                                CG_SOURCE,
492                                                                "src/shaders/globillum.cg",
493                                                                RenderState::sCgFragmentProfile,
494                                                                "combine",
495                                                                NULL);
496
497        if (sCgCombinedIllumProgram != NULL)
498        {
499                cgGLLoadProgram(sCgCombinedIllumProgram);
500
501                sColorsTexCombinedIllumParam = cgGetNamedParameter(sCgCombinedIllumProgram, "colors"); 
502                sSsaoTexCombinedIllumParam = cgGetNamedParameter(sCgCombinedIllumProgram, "ssaoTex");
503                sIllumTexCombinedIllumParam = cgGetNamedParameter(sCgCombinedIllumProgram, "illumTex");
504
505                pr = new ShaderProgram(sCgCombinedIllumProgram);
506                sShaders.push_back(pr);
507        }
508        else
509                cerr << "combined illum program failed to load" << endl;
510
511
512        sCgCombinedSsaoProgram =
513                cgCreateProgramFromFile(context,
514                                                                CG_SOURCE,
515                                                                "src/shaders/ssao.cg",
516                                                                RenderState::sCgFragmentProfile,
517                                                                "combine",
518                                                                NULL);
519
520        if (sCgCombinedSsaoProgram != NULL)
521        {
522                cgGLLoadProgram(sCgCombinedSsaoProgram);
523
524                sColorsTexCombinedSsaoParam = cgGetNamedParameter(sCgCombinedSsaoProgram, "colors"); 
525                sSsaoTexCombinedSsaoParam = cgGetNamedParameter(sCgCombinedSsaoProgram, "ssaoTex");
526
527                sFilterOffsetsParam = cgGetNamedParameter(sCgCombinedSsaoProgram, "filterOffs");
528                sFilterWeightsParam = cgGetNamedParameter(sCgCombinedSsaoProgram, "filterWeights");
529
530                pr = new ShaderProgram(sCgCombinedSsaoProgram);
531                sShaders.push_back(pr);
532        }
533        else
534                cerr << "combied illum program failed to load" << endl;
535
536       
537        sCgAntiAliasingProgram =
538                cgCreateProgramFromFile(context,
539                                                                CG_SOURCE,
540                                                                "src/shaders/antialiasing.cg",
541                                                                RenderState::sCgFragmentProfile,
542                                                                "main",
543                                                                NULL);
544
545        if (sCgAntiAliasingProgram != NULL)
546        {
547                cgGLLoadProgram(sCgAntiAliasingProgram);
548
549                sColorsTexAntiAliasingParam = cgGetNamedParameter(sCgAntiAliasingProgram, "colors"); 
550                sNormalsTexAntiAliasingParam = cgGetNamedParameter(sCgAntiAliasingProgram, "normals");
551
552                pr = new ShaderProgram(sCgAntiAliasingProgram);
553                sShaders.push_back(pr);
554        }
555        else
556                cerr << "antialiasing program failed to load" << endl;
557
558        sCgDeferredShadowProgram =
559                cgCreateProgramFromFile(context,
560                                                                CG_SOURCE,
561                                                                "src/shaders/deferred.cg",
562                                                                RenderState::sCgFragmentProfile,
563                                                                "main_shadow",
564                                                                NULL);
565
566        if (sCgDeferredShadowProgram != NULL)
567        {
568                cgGLLoadProgram(sCgDeferredShadowProgram);
569
570                // we need size of texture for scaling
571                sPositionsTexShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "positions"); 
572                sColorsTexShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "colors"); 
573                sNormalsTexShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "normals");
574
575                sShadowMapParam = cgGetNamedParameter(sCgDeferredShadowProgram, "shadowMap"); 
576                sSampleWidthParam = cgGetNamedParameter(sCgDeferredShadowProgram, "sampleWidth");
577                sShadowMatrixParam = cgGetNamedParameter(sCgDeferredShadowProgram, "shadowMatrix");
578
579                sNoiseTexShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "noiseTexture");
580                sSamplesShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "samples");
581                sLightDirShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "lightDir");
582
583                sEyePosShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "eyePos");
584
585                PoissonDiscSampleGenerator2 poisson(NUM_PCF_TABS, 1.0f);
586                poisson.Generate((float *)pcfSamples);
587
588                cgGLSetParameterArray2f(sSamplesShadowParam, 0, NUM_PCF_TABS, (const float *)pcfSamples);
589
590                pr = new ShaderProgram(sCgDeferredShadowProgram);
591                sShaders.push_back(pr);
592        }
593        else
594                cerr << "deferred program failed to load" << endl;
595
596        sCgLogLumProgram =
597                cgCreateProgramFromFile(context,
598                                                                CG_SOURCE,
599                                                                "src/shaders/tonemap.cg",
600                                                                RenderState::sCgFragmentProfile,
601                                                                "CalcAvgLogLum",
602                                                                NULL);
603
604        if (sCgLogLumProgram != NULL)
605        {
606                cgGLLoadProgram(sCgLogLumProgram);
607                sColorsTexLogLumParam = cgGetNamedParameter(sCgLogLumProgram, "colors");
608
609                pr = new ShaderProgram(sCgLogLumProgram);
610                sShaders.push_back(pr);
611        }
612        else
613                cerr << "avg loglum program failed to load" << endl;
614
615
616        sCgToneProgram =
617                cgCreateProgramFromFile(context,
618                                                                CG_SOURCE,
619                                                                "src/shaders/tonemap.cg",
620                                                                RenderState::sCgFragmentProfile,
621                                                                "ToneMap",
622                                                                NULL);
623
624        if (sCgToneProgram != NULL)
625        {
626                cgGLLoadProgram(sCgToneProgram);
627
628                sImageKeyParam = cgGetNamedParameter(sCgToneProgram, "imageKey");
629                sMiddleGreyParam = cgGetNamedParameter(sCgToneProgram, "middleGrey");
630                sWhiteLumParam = cgGetNamedParameter(sCgToneProgram, "whiteLum");
631
632                sColorsTexToneParam = cgGetNamedParameter(sCgToneProgram, "colors"); 
633
634                pr = new ShaderProgram(sCgToneProgram);
635                sShaders.push_back(pr);
636        }
637        else
638                cerr << "tone program failed to load" << endl;
639
640
641        sCgDownSampleProgram =
642                cgCreateProgramFromFile(context,
643                                                                CG_SOURCE,
644                                                                "src/shaders/tonemap.cg",
645                                                                RenderState::sCgFragmentProfile,
646                                                                "DownSample",
647                                                                NULL);
648
649        if (sCgDownSampleProgram != NULL)
650        {
651                cgGLLoadProgram(sCgDownSampleProgram);
652
653                // we need size of texture for scaling
654                sColorsTexDownSampleParam = cgGetNamedParameter(sCgDownSampleProgram, "colors");
655                sDownSampleOffsetParam = cgGetNamedParameter(sCgDownSampleProgram, "downSampleOffs");
656
657                pr = new ShaderProgram(sCgDownSampleProgram);
658                sShaders.push_back(pr);
659        }
660        else
661                cerr << "downsample program failed to load" << endl;
662
663        PrintGLerror("init");
664}
665
666
667void DeferredRenderer::Render(FrameBufferObject *fbo,
668                                                          const Matrix4x4 &oldProjViewMatrix,
669                                                          const Matrix4x4 &projViewMatrix,
670                                                          float tempCohFactor,
671                                                          DirectionalLight *light,
672                                                          bool useToneMapping,
673                                                          ShadowMap *shadowMap
674                                                          )
675{
676        // switch roles of old and new fbo
677        // the algorihm uses two input fbos, where the one
678        // contais the color buffer from the last frame,
679        // the other one will be written
680
681        mIllumFboIndex = 2 - mIllumFboIndex;
682       
683
684        cgGLEnableProfile(RenderState::sCgFragmentProfile);
685
686        glDisable(GL_ALPHA_TEST);
687        glDisable(GL_TEXTURE_2D);
688        glDisable(GL_LIGHTING);
689        glDisable(GL_BLEND);
690        glDisable(GL_DEPTH_TEST);
691
692        glPushAttrib(GL_VIEWPORT_BIT);
693        glViewport(0, 0, mWidth, mHeight);
694
695        glMatrixMode(GL_PROJECTION);
696        glPushMatrix();
697        glLoadIdentity();
698
699        const float offs = 0.5f;
700        glOrtho(-offs, offs, -offs, offs, 0, 1);
701
702        glMatrixMode(GL_MODELVIEW);
703        glPushMatrix();
704        glLoadIdentity();
705
706        if (shadowMap)
707                FirstPassShadow(fbo, light, shadowMap);
708        else
709                FirstPass(fbo, light);
710
711        switch (mShadingMethod)
712        {
713        case SSAO:
714                // downsample fbo buffers for colors, normals
715                DownSample(fbo, colorBufferIdx, mDownSampleFbo, 0);
716                DownSample(fbo, 1, mDownSampleFbo, 1);
717
718                ComputeSsao(fbo, tempCohFactor, oldProjViewMatrix, projViewMatrix);
719                CombineSsao(fbo);
720                break;
721        case GI:
722                // downsample fbo buffers for colors, normals
723                DownSample(fbo, colorBufferIdx, mDownSampleFbo, 0);
724                DownSample(fbo, 1, mDownSampleFbo, 1);
725
726                ComputeGlobIllum(fbo, tempCohFactor, projViewMatrix, oldProjViewMatrix);
727                CombineIllum(fbo);
728                break;
729        default: // DEFAULT
730                // do nothing: standard deferred shading
731                break;
732        }
733
734        if (useToneMapping)
735        {
736                float imageKey, whiteLum, middleGrey;
737
738                ComputeToneParameters(fbo, light, imageKey, whiteLum, middleGrey);
739                ToneMap(fbo, imageKey, whiteLum, middleGrey);
740        }
741
742        AntiAliasing(fbo, light);
743
744        glEnable(GL_LIGHTING);
745        glDisable(GL_TEXTURE_2D);
746
747        glMatrixMode(GL_PROJECTION);
748        glPopMatrix();
749
750        glMatrixMode(GL_MODELVIEW);
751        glPopMatrix();
752
753        glPopAttrib();
754
755        FrameBufferObject::Release();
756        cgGLDisableProfile(RenderState::sCgFragmentProfile);
757}
758
759
760void DeferredRenderer::ComputeSsao(FrameBufferObject *fbo,
761                                                                   float tempCohFactor,
762                                                                   const Matrix4x4 &oldProjViewMatrix,
763                                                                   const Matrix4x4 &projViewMatrix
764                                                                   )
765{
766#ifdef USE_3D_SSAO
767        // bias from [-1, 1] to [0, 1]
768        static Matrix4x4 biasMatrix(0.5f, 0.0f, 0.0f, 0.5f,
769                                                                0.0f, 0.5f, 0.0f, 0.5f,
770                                                                0.0f, 0.0f, 0.5f, 0.5f,
771                                                                0.0f, 0.0f, 0.0f, 1.0f);
772
773        Matrix4x4 m = projViewMatrix * biasMatrix;
774        cgGLSetMatrixParameterfc(sModelViewProjMatrixParam, (const float *)m.x);
775#else
776        cgGLSetMatrixParameterfc(sModelViewProjMatrixParam, (const float *)projViewMatrix.x);
777#endif
778
779
780        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixParam, (const float *)oldProjViewMatrix.x);
781#if 0
782        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
783        GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
784#else
785        GLuint colorsTex = mDownSampleFbo->GetColorBuffer(0)->GetTexture();
786        GLuint normalsTex = mDownSampleFbo->GetColorBuffer(1)->GetTexture();
787#endif
788
789        GLuint oldTex = mIllumFbo->GetColorBuffer(2 - mIllumFboIndex)->GetTexture();
790
791        glPushAttrib(GL_VIEWPORT_BIT);
792        glViewport(0, 0, mIllumFbo->GetWidth(), mIllumFbo->GetHeight());
793
794        // read the second buffer, write to the first buffer
795        mIllumFbo->Bind();
796        glDrawBuffers(1, mrt + mIllumFboIndex);
797
798       
799        cgGLBindProgram(sCgSsaoProgram);
800
801        cgGLSetTextureParameter(sColorsTexParam, colorsTex);
802        cgGLEnableTextureParameter(sColorsTexParam);
803
804        cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
805        cgGLEnableTextureParameter(sNormalsTexParam);
806
807        cgGLSetTextureParameter(sNoiseTexParam, noiseTex);
808        cgGLEnableTextureParameter(sNoiseTexParam);
809
810        cgGLSetTextureParameter(sOldTexParam, oldTex);
811        cgGLEnableTextureParameter(sOldTexParam);
812       
813        Vector3 pos = mCamera->GetPosition();
814        cgGLSetParameter3f(sEyePosParam, pos.x, pos.y, pos.z);
815       
816        cgGLSetParameter1f(sTemporalCoherenceParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
817
818        if (mUseTemporalCoherence || mRegenerateSamples)
819        {
820                mRegenerateSamples = false;
821
822                // q: should we generate new samples or only rotate the old ones?
823                // in the first case, the sample patterns look nicer, but the kernel
824                // needs longer to converge
825                GenerateSamples(mSamplingMethod);
826
827#ifdef USE_3D_SSAO
828                cgGLSetParameterArray3f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples3);
829#else
830                cgGLSetParameterArray2f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples2);
831#endif
832        }
833
834        Vector3 tl, tr, bl, br;
835        ComputeViewVectors(tl, tr, bl, br);
836
837        cgGLSetParameter3f(sBLParam, bl.x, bl.y, bl.z);
838        cgGLSetParameter3f(sBRParam, br.x, br.y, br.z);
839        cgGLSetParameter3f(sTLParam, tl.x, tl.y, tl.z);
840        cgGLSetParameter3f(sTRParam, tr.x, tr.y, tr.z);
841
842
843        glBegin(GL_QUADS);
844
845        // note: slightly larger texture could hide ambient occlusion error on border but costs resolution
846        const float offs = 0.5f;
847       
848        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f(-offs, -offs, -0.5f);
849        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f( offs, -offs, -0.5f);
850        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f( offs,  offs, -0.5f);
851        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f(-offs,  offs, -0.5f);
852
853        //cout<<bl << " " << br << endl;
854
855        glEnd();
856
857        cgGLDisableTextureParameter(sColorsTexParam);
858        cgGLDisableTextureParameter(sNormalsTexParam);
859        cgGLDisableTextureParameter(sNoiseTexParam);
860        cgGLDisableTextureParameter(sOldTexParam);
861
862        glPopAttrib();
863
864        PrintGLerror("ssao first pass");
865}
866
867
868void DeferredRenderer::ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
869{
870        Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
871
872        mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
873
874        bl = Normalize(nbl - fbl);
875        br = Normalize(nbr - fbr);
876        tl = Normalize(ntl - ftl);
877        tr = Normalize(ntr - ftr);
878}
879
880
881static void SetVertex(float x, float y, float x_offs, float y_offs)
882{
883        glMultiTexCoord2fARB(GL_TEXTURE0_ARB, x, y); // center
884        glMultiTexCoord2fARB(GL_TEXTURE1_ARB, x - x_offs, y + y_offs); // left top
885        glMultiTexCoord2fARB(GL_TEXTURE2_ARB, x + x_offs, y - y_offs); // right bottom
886        glMultiTexCoord2fARB(GL_TEXTURE3_ARB, x + x_offs, y + y_offs); // right top
887        glMultiTexCoord2fARB(GL_TEXTURE4_ARB, x - x_offs, y - y_offs); // left bottom
888
889        glMultiTexCoord4fARB(GL_TEXTURE5_ARB, x - x_offs, y, x + x_offs, y); // left right
890        glMultiTexCoord4fARB(GL_TEXTURE6_ARB, x, y + y_offs, x, y - y_offs); // top bottom
891
892        glVertex3f(x - 0.5f, y - 0.5f, -0.5f);
893}
894
895
896void DeferredRenderer::AntiAliasing(FrameBufferObject *fbo, DirectionalLight *light)
897{
898        FrameBufferObject::Release();
899
900        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
901
902        GLuint colorsTex = colorBuffer->GetTexture();
903        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
904
905        cgGLBindProgram(sCgAntiAliasingProgram);
906       
907        cgGLSetTextureParameter(sColorsTexAntiAliasingParam, colorsTex);
908        cgGLEnableTextureParameter(sColorsTexAntiAliasingParam);
909
910        cgGLSetTextureParameter(sNormalsTexAntiAliasingParam, normalsTex);
911        cgGLEnableTextureParameter(sNormalsTexAntiAliasingParam);
912
913        // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
914        glColor3f(1.0f, 1.0f, 1.0f);
915
916        glBegin(GL_QUADS);
917
918        // the neighbouring texels
919        float x_offs = 1.0f / mWidth;
920        float y_offs = 1.0f / mHeight;
921
922        SetVertex(0, 0, x_offs, y_offs);
923        SetVertex(1, 0, x_offs, y_offs);
924        SetVertex(1, 1, x_offs, y_offs);
925        SetVertex(0, 1, x_offs, y_offs);
926
927        glEnd();
928
929        cgGLDisableTextureParameter(sColorsTexAntiAliasingParam);
930        cgGLDisableTextureParameter(sNormalsTexAntiAliasingParam);
931
932        PrintGLerror("antialiasing");
933}
934
935
936void DeferredRenderer::FirstPass(FrameBufferObject *fbo, DirectionalLight *light)
937{
938        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
939        GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
940        GLuint positionsTex = fbo->GetColorBuffer(2)->GetTexture();
941
942        fbo->Bind();
943
944        colorBufferIdx = 3 - colorBufferIdx;
945        glDrawBuffers(1, mrt + colorBufferIdx);
946       
947        cgGLBindProgram(sCgDeferredProgram);
948
949        cgGLSetTextureParameter(sColorsTexDeferredParam, colorsTex);
950        cgGLEnableTextureParameter(sColorsTexDeferredParam);
951
952        cgGLSetTextureParameter(sPositionsTexDeferredParam, positionsTex);
953        cgGLEnableTextureParameter(sPositionsTexDeferredParam);
954
955        cgGLSetTextureParameter(sNormalsTexDeferredParam, normalsTex);
956        cgGLEnableTextureParameter(sNormalsTexDeferredParam);
957       
958        Vector3 lightDir = -light->GetDirection();
959        cgGLSetParameter3f(sLightDirParam, lightDir.x, lightDir.y, lightDir.z);
960
961        Vector3 tl, tr, bl, br;
962        ComputeViewVectors(tl, tr, bl, br);
963       
964        // note: slightly larger texture could hide ambient occlusion error on border but costs resolution
965        const float offs = 0.5f;
966       
967        glBegin(GL_QUADS);
968
969        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f(-offs, -offs, -0.5f);
970        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f( offs, -offs, -0.5f);
971        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f( offs,  offs, -0.5f);
972        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f(-offs,  offs, -0.5f);
973
974        glEnd();
975
976        cgGLDisableTextureParameter(sColorsTexDeferredParam);
977        cgGLDisableTextureParameter(sPositionsTexDeferredParam);
978        cgGLDisableTextureParameter(sNormalsTexDeferredParam);
979
980        PrintGLerror("deferred shading");
981}
982
983
984
985void DeferredRenderer::ComputeGlobIllum(FrameBufferObject *fbo,
986                                                                                float tempCohFactor,
987                                                                                const Matrix4x4 &projViewMatrix,
988                                                                                const Matrix4x4 &oldProjViewMatrix)
989{
990        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixGiParam, (const float *)oldProjViewMatrix.x);
991        cgGLSetMatrixParameterfc(sModelViewProjMatrixGiParam, (const float *)projViewMatrix.x);
992
993#if 0
994        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
995        GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
996#else
997        GLuint colorsTex = mDownSampleFbo->GetColorBuffer(0)->GetTexture();
998        GLuint normalsTex = mDownSampleFbo->GetColorBuffer(1)->GetTexture();
999#endif
1000
1001        glPushAttrib(GL_VIEWPORT_BIT);
1002        glViewport(0, 0, mIllumFbo->GetWidth(), mIllumFbo->GetHeight());
1003
1004        // read the second buffer, write to the first buffer
1005        mIllumFbo->Bind();
1006
1007        glDrawBuffers(2, mrt + mIllumFboIndex);
1008
1009        GLuint oldSsaoTex = mIllumFbo->GetColorBuffer(2 - mIllumFboIndex)->GetTexture();
1010        GLuint oldIllumTex = mIllumFbo->GetColorBuffer(2 - mIllumFboIndex + 1)->GetTexture();
1011       
1012        cgGLBindProgram(sCgGiProgram);
1013
1014
1015        cgGLSetTextureParameter(sColorsTexGiParam, colorsTex);
1016        cgGLEnableTextureParameter(sColorsTexGiParam);
1017
1018        cgGLSetTextureParameter(sNormalsTexGiParam, normalsTex);
1019        cgGLEnableTextureParameter(sNormalsTexGiParam);
1020
1021        cgGLSetTextureParameter(sNoiseTexGiParam, noiseTex);
1022        cgGLEnableTextureParameter(sNoiseTexGiParam);
1023
1024        cgGLSetTextureParameter(sOldSsaoTexGiParam, oldSsaoTex);
1025        cgGLEnableTextureParameter(sOldSsaoTexGiParam);
1026
1027        cgGLSetTextureParameter(sOldIllumTexGiParam, oldIllumTex);
1028        cgGLEnableTextureParameter(sOldIllumTexGiParam);
1029
1030
1031        cgGLSetParameter1f(sTemporalCoherenceGiParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
1032
1033
1034        if (mUseTemporalCoherence || mRegenerateSamples)
1035        {
1036                mRegenerateSamples = false;
1037
1038                // q: should we generate new samples or only rotate the old ones?
1039                // in the first case, the sample patterns look nicer, but the kernel
1040                // needs longer to converge
1041                GenerateSamples(mSamplingMethod);
1042
1043                cgGLSetParameterArray2f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples2);
1044        }
1045
1046
1047        Vector3 tl, tr, bl, br;
1048        ComputeViewVectors(tl, tr, bl, br);
1049       
1050        const Vector3 pos = mCamera->GetPosition();
1051        cgGLSetParameter3f(sEyePosGiParam, pos.x, pos.y, pos.z);
1052
1053        cgGLSetParameter3f(sBLGiParam, bl.x, bl.y, bl.z);
1054        cgGLSetParameter3f(sBRGiParam, br.x, br.y, br.z);
1055        cgGLSetParameter3f(sTLGiParam, tl.x, tl.y, tl.z);
1056        cgGLSetParameter3f(sTRGiParam, tr.x, tr.y, tr.z);
1057
1058
1059        // note: slightly larger texture could hide ambient occlusion error on border but costs resolution
1060        const float offs = 0.5f;
1061       
1062        glBegin(GL_QUADS);
1063
1064        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f(-offs, -offs, -0.5f);
1065        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f( offs, -offs, -0.5f);
1066        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f( offs,  offs, -0.5f);
1067        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f(-offs,  offs, -0.5f);
1068
1069        glEnd();
1070
1071        cgGLDisableTextureParameter(sColorsTexGiParam);
1072        cgGLDisableTextureParameter(sNormalsTexGiParam);
1073        cgGLDisableTextureParameter(sNoiseTexGiParam);
1074        cgGLDisableTextureParameter(sOldSsaoTexGiParam);
1075        cgGLDisableTextureParameter(sOldIllumTexGiParam);
1076
1077        glPopAttrib();
1078
1079        PrintGLerror("globillum first pass");
1080}
1081
1082
1083void DeferredRenderer::CombineIllum(FrameBufferObject *fbo)
1084{
1085        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
1086
1087        GLuint ssaoTex = mIllumFbo->GetColorBuffer(mIllumFboIndex)->GetTexture();
1088        GLuint illumTex = mIllumFbo->GetColorBuffer(mIllumFboIndex + 1)->GetTexture();
1089
1090
1091        fbo->Bind();
1092
1093        // overwrite old color texture
1094        colorBufferIdx = 3 - colorBufferIdx;
1095
1096        glDrawBuffers(1, mrt + colorBufferIdx);
1097
1098        cgGLBindProgram(sCgCombinedIllumProgram);
1099
1100
1101        cgGLSetTextureParameter(sColorsTexCombinedIllumParam, colorsTex);
1102        cgGLEnableTextureParameter(sColorsTexCombinedIllumParam);
1103
1104        cgGLSetTextureParameter(sSsaoTexCombinedIllumParam, ssaoTex);
1105        cgGLEnableTextureParameter(sSsaoTexCombinedIllumParam);
1106
1107        cgGLSetTextureParameter(sIllumTexCombinedIllumParam, illumTex);
1108        cgGLEnableTextureParameter(sIllumTexCombinedIllumParam);
1109       
1110        glColor3f(1.0f, 1.0f, 1.0f);
1111
1112        const float offs = 0.5f;
1113
1114        glBegin(GL_QUADS);
1115
1116        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
1117        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
1118        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
1119        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
1120
1121        glEnd();
1122
1123        cgGLDisableTextureParameter(sColorsTexCombinedIllumParam);
1124        cgGLDisableTextureParameter(sSsaoTexCombinedIllumParam);
1125        cgGLDisableTextureParameter(sIllumTexCombinedIllumParam);
1126
1127        PrintGLerror("combine");
1128}
1129
1130
1131static float GaussianDistribution(float x, float y, float rho)
1132{
1133    float g = 1.0f / sqrtf(2.0f * M_PI * rho * rho);
1134    g *= expf( -(x*x + y*y) / (2.0f * rho * rho));
1135
1136    return g;
1137}
1138
1139
1140void DeferredRenderer::CombineSsao(FrameBufferObject *fbo)
1141{
1142        fbo->Bind();
1143
1144        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
1145        GLuint positionsTex = fbo->GetColorBuffer(2)->GetTexture();
1146       
1147        GLuint ssaoTex = mIllumFbo->GetColorBuffer(mIllumFboIndex)->GetTexture();
1148
1149        // overwrite old color texture
1150        colorBufferIdx = 3 - colorBufferIdx;
1151        glDrawBuffers(1, mrt + colorBufferIdx);
1152
1153        cgGLBindProgram(sCgCombinedSsaoProgram);
1154
1155        float filterOffsets[NUM_DOWNSAMPLES * 2];
1156        float filterWeights[NUM_DOWNSAMPLES];
1157
1158        PoissonDiscSampleGenerator2 poisson(NUM_DOWNSAMPLES, 1.0f);
1159        poisson.Generate((float *)filterOffsets);
1160
1161        const float xoffs = 2.0f / fbo->GetWidth();
1162        const float yoffs = 2.0f / fbo->GetHeight();
1163
1164        for (int i = 0; i < NUM_DOWNSAMPLES; ++ i)
1165        {
1166                float x = filterOffsets[2 * i + 0];
1167                float y = filterOffsets[2 * i + 1];
1168
1169                filterOffsets[2 * i + 0] *= xoffs;
1170                filterOffsets[2 * i + 1] *= yoffs;
1171
1172                filterWeights[i] = GaussianDistribution(x, y, 1.0f);
1173        }
1174
1175        //ComputeSampleOffsets(filterOffsets, fbo->GetWidth(), fbo->GetHeight());
1176        cgGLSetParameterArray2f(sFilterOffsetsParam, 0, NUM_DOWNSAMPLES, (const float *)filterOffsets);
1177        cgGLSetParameterArray1f(sFilterWeightsParam, 0, NUM_DOWNSAMPLES, (const float *)filterWeights);
1178
1179        cgGLSetTextureParameter(sColorsTexCombinedSsaoParam, colorsTex);
1180        cgGLEnableTextureParameter(sColorsTexCombinedSsaoParam);
1181
1182        cgGLSetTextureParameter(sSsaoTexCombinedSsaoParam, ssaoTex);
1183        cgGLEnableTextureParameter(sSsaoTexCombinedSsaoParam);
1184
1185       
1186        glColor3f(1.0f, 1.0f, 1.0f);
1187
1188        const float offs = 0.5f;
1189
1190        glBegin(GL_QUADS);
1191
1192        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
1193        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
1194        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
1195        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
1196
1197        glEnd();
1198
1199        cgGLDisableTextureParameter(sColorsTexCombinedSsaoParam);
1200        cgGLDisableTextureParameter(sSsaoTexCombinedSsaoParam);
1201       
1202        PrintGLerror("combine ssao");
1203}
1204
1205
1206void DeferredRenderer::FirstPassShadow(FrameBufferObject *fbo,
1207                                                                           DirectionalLight *light,
1208                                                                           ShadowMap *shadowMap)
1209{
1210        fbo->Bind();
1211
1212        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
1213        GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
1214        GLuint positionsTex = fbo->GetColorBuffer(2)->GetTexture();
1215
1216        GLuint shadowTex = shadowMap->GetDepthTexture();
1217
1218        Matrix4x4 shadowMatrix;
1219        shadowMap->GetTextureMatrix(shadowMatrix);
1220
1221        colorBufferIdx = 3 - colorBufferIdx;
1222        glDrawBuffers(1, mrt + colorBufferIdx);
1223
1224       
1225        cgGLBindProgram(sCgDeferredShadowProgram);
1226
1227        cgGLSetTextureParameter(sColorsTexShadowParam, colorsTex);
1228        cgGLEnableTextureParameter(sColorsTexShadowParam);
1229
1230        cgGLSetTextureParameter(sPositionsTexShadowParam, positionsTex);
1231        cgGLEnableTextureParameter(sPositionsTexShadowParam);
1232
1233        cgGLSetTextureParameter(sNormalsTexShadowParam, normalsTex);
1234        cgGLEnableTextureParameter(sNormalsTexShadowParam);
1235       
1236        cgGLSetTextureParameter(sShadowMapParam, shadowTex);
1237        cgGLEnableTextureParameter(sShadowMapParam);
1238
1239        cgGLSetParameter1f(sSampleWidthParam, 2.0f / shadowMap->GetSize());
1240       
1241         
1242        cgGLSetMatrixParameterfc(sShadowMatrixParam, (const float *)shadowMatrix.x);
1243
1244        cgGLSetTextureParameter(sNoiseTexShadowParam, noiseTex);
1245        cgGLEnableTextureParameter(sNoiseTexShadowParam);
1246
1247        Vector3 lightDir = -light->GetDirection();
1248        cgGLSetParameter3f(sLightDirShadowParam, lightDir.x, lightDir.y, lightDir.z);
1249
1250        Vector3 tl, tr, bl, br;
1251        ComputeViewVectors(tl, tr, bl, br);
1252       
1253        const Vector3 pos = mCamera->GetPosition();
1254        cgGLSetParameter3f(sEyePosShadowParam, pos.x, pos.y, pos.z);
1255
1256        // note: slightly larger texture could hide ambient occlusion error on border but costs resolution
1257        const float offs = 0.5f;
1258       
1259        glBegin(GL_QUADS);
1260
1261        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f(-offs, -offs, -0.5f);
1262        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f( offs, -offs, -0.5f);
1263        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f( offs,  offs, -0.5f);
1264        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f(-offs,  offs, -0.5f);
1265
1266        glEnd();
1267
1268        cgGLDisableTextureParameter(sColorsTexShadowParam);
1269        cgGLDisableTextureParameter(sPositionsTexShadowParam);
1270        cgGLDisableTextureParameter(sNormalsTexShadowParam);
1271        cgGLDisableTextureParameter(sShadowMapParam);
1272        cgGLDisableTextureParameter(sNoiseTexShadowParam);
1273
1274        PrintGLerror("deferred shading + shadows");
1275}
1276
1277
1278void DeferredRenderer::SetSamplingMethod(SAMPLING_METHOD s)
1279{
1280        if (s != mSamplingMethod)
1281        {
1282                mSamplingMethod = s;
1283                mRegenerateSamples = true;
1284        }
1285}
1286
1287
1288void DeferredRenderer::SetShadingMethod(SHADING_METHOD s)
1289{
1290        if (s != mShadingMethod)
1291        {
1292                mShadingMethod = s;
1293                mRegenerateSamples = true;
1294        }
1295}
1296
1297
1298void DeferredRenderer::ComputeToneParameters(FrameBufferObject *fbo,
1299                                                                                         DirectionalLight *light,
1300                                                                                         float &imageKey,
1301                                                                                         float &whiteLum,
1302                                                                                         float &middleGrey)
1303{
1304        // hack: estimate value where sky burns out
1305        whiteLum = log(WHITE_LUMINANCE);
1306       
1307        ////////////////////
1308        //-- linear interpolate brightness key depending on the current sun position
1309
1310        const float minKey = 0.09f;
1311        const float maxKey = 0.36f;
1312
1313        const float lightIntensity = DotProd(-light->GetDirection(), Vector3::UNIT_Z());
1314        middleGrey = lightIntensity * maxKey + (1.0f - lightIntensity) * minKey;
1315
1316
1317        //////////
1318        //-- compute avg loglum
1319
1320        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
1321        GLuint colorsTex = colorBuffer->GetTexture();
1322
1323        fbo->Bind();
1324
1325        colorBufferIdx = 3 - colorBufferIdx;
1326        glDrawBuffers(1, mrt + colorBufferIdx);
1327       
1328        cgGLBindProgram(sCgLogLumProgram);
1329       
1330        cgGLSetTextureParameter(sColorsTexLogLumParam, colorsTex);
1331        cgGLEnableTextureParameter(sColorsTexLogLumParam);
1332       
1333        const float offs = 0.5f;
1334
1335        glBegin(GL_QUADS);
1336
1337        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
1338        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
1339        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
1340        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
1341
1342        glEnd();
1343
1344        cgGLDisableTextureParameter(sColorsTexLogLumParam);
1345
1346        PrintGLerror("ToneMapParams");
1347
1348
1349        ///////////////////
1350        //-- compute avg loglum in scene using mipmapping
1351
1352        glBindTexture(GL_TEXTURE_2D, fbo->GetColorBuffer(colorBufferIdx)->GetTexture());
1353        glGenerateMipmapEXT(GL_TEXTURE_2D);
1354}
1355
1356
1357static void ExportData(float *data, int w, int h)
1358{
1359        startil();
1360
1361        cout << "w: " << w << " h: " << h << endl;
1362        ILstring filename = ILstring("downsample2.jpg");
1363        ilRegisterType(IL_FLOAT);
1364
1365        const int depth = 1;
1366        const int bpp = 4;
1367
1368        if (!ilTexImage(w, h, depth, bpp, IL_RGBA, IL_FLOAT, data))
1369        {
1370                cerr << "IL error " << ilGetError() << endl;
1371                stopil();
1372                return;
1373        }
1374
1375        if (!ilSaveImage(filename))
1376        {
1377                cerr << "TGA write error " << ilGetError() << endl;
1378        }
1379
1380        stopil();
1381
1382        // cout << "exported buffer" << endl;
1383}
1384
1385
1386void DeferredRenderer::DownSample(FrameBufferObject *fbo, int bufferIdx,
1387                                                                  FrameBufferObject *downSampleFbo,
1388                                                                  int downSampleBufferIdx)
1389{
1390        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(bufferIdx);
1391        GLuint colorsTex = colorBuffer->GetTexture();
1392
1393        glPushAttrib(GL_VIEWPORT_BIT);
1394        glViewport(0, 0, downSampleFbo->GetWidth(), downSampleFbo->GetHeight());
1395
1396        cgGLBindProgram(sCgDownSampleProgram);
1397       
1398        cgGLSetTextureParameter(sColorsTexDownSampleParam, colorsTex);
1399        cgGLEnableTextureParameter(sColorsTexDownSampleParam);
1400
1401        float downSampleOffsets[NUM_DOWNSAMPLES * 2];
1402        ComputeSampleOffsets(downSampleOffsets, fbo->GetWidth(), fbo->GetHeight());
1403
1404        cgGLSetParameterArray2f(sDownSampleOffsetParam, 0, NUM_DOWNSAMPLES, (const float *)downSampleOffsets);
1405
1406        mDownSampleFbo->Bind();
1407        glDrawBuffers(1, mrt + downSampleBufferIdx);
1408
1409        cgGLBindProgram(sCgDownSampleProgram);
1410       
1411        const float offs = 0.5f;
1412
1413        glBegin(GL_QUADS);
1414
1415        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
1416        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
1417        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
1418        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
1419
1420        glEnd();
1421
1422        cgGLDisableTextureParameter(sColorsTexDownSampleParam);
1423
1424        /*float *data = (float *)mDownSampleFbo->GetColorBuffer(0)->ReadTexture();
1425        ExportData(data, mWidth / 2, mHeight / 2);
1426        delete [] data;*/
1427
1428        glPopAttrib();
1429       
1430        PrintGLerror("downsample");
1431}
1432
1433
1434void DeferredRenderer::ToneMap(FrameBufferObject *fbo,
1435                                                           float imageKey,
1436                                                           float whiteLum,
1437                                                           float middleGrey)
1438{
1439        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
1440        GLuint colorsTex = colorBuffer->GetTexture();
1441
1442        fbo->Bind();
1443#if 1
1444        colorBufferIdx = 3 - colorBufferIdx;
1445        glDrawBuffers(1, mrt + colorBufferIdx);
1446
1447        cgGLBindProgram(sCgToneProgram);
1448
1449        cgGLSetTextureParameter(sColorsTexToneParam, colorsTex);
1450        cgGLEnableTextureParameter(sColorsTexToneParam);
1451
1452        cgGLSetParameter1f(sImageKeyParam, imageKey);
1453        cgGLSetParameter1f(sWhiteLumParam, whiteLum);
1454        cgGLSetParameter1f(sMiddleGreyParam, middleGrey);
1455
1456        glColor3f(1.0f, 1.0f, 1.0f);
1457
1458
1459        glBegin(GL_QUADS);
1460
1461        const float offs = 0.5f;
1462
1463
1464        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
1465        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
1466        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
1467        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
1468
1469        glEnd();
1470#endif
1471
1472        cgGLDisableTextureParameter(sColorsTexToneParam);
1473
1474        PrintGLerror("ToneMap");
1475}
1476
1477
1478
1479
1480} // namespace
Note: See TracBrowser for help on using the repository browser.