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

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