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

Revision 3020, 41.7 KB checked in by mattausch, 16 years ago (diff)

removed most leaks

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