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

Revision 2992, 38.0 KB checked in by mattausch, 16 years ago (diff)

tone mapping working with using reconstructed depth

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       
669        // read the second buffer, write to the first buffer
670        mFbo->Bind();
671        glDrawBuffers(1, mrt + mFboIndex);
672
673        GLuint oldTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
674
675        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
676
677        cgGLEnableProfile(RenderState::sCgFragmentProfile);
678        cgGLBindProgram(sCgSsaoProgram);
679
680        cgGLSetTextureParameter(sPositionsTexParam, positionsTex);
681        cgGLEnableTextureParameter(sPositionsTexParam);
682
683        cgGLSetTextureParameter(sColorsTexParam, colorsTex);
684        cgGLEnableTextureParameter(sColorsTexParam);
685
686        cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
687        cgGLEnableTextureParameter(sNormalsTexParam);
688
689        cgGLSetTextureParameter(sNoiseTexParam, noiseTex);
690        cgGLEnableTextureParameter(sNoiseTexParam);
691
692        cgGLSetTextureParameter(sOldTexParam, oldTex);
693        cgGLEnableTextureParameter(sOldTexParam);
694       
695        cgGLSetParameter1f(sMaxDepthParam, mScaleFactor);
696
697        Vector3 pos = mCamera->GetPosition() / mScaleFactor;
698        cgGLSetParameter3f(sEyePosParam, pos.x, pos.y, pos.z);
699       
700        cgGLSetParameter1f(sTemporalCoherenceParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
701
702        if (mUseTemporalCoherence || mRegenerateSamples)
703        {
704                mRegenerateSamples = false;
705
706                // q: should we generate new samples or only rotate the old ones?
707                // in the first case, the sample patterns look nicer, but the kernel
708                // needs longer to converge
709                GenerateSamples(mSamplingMethod);
710
711#ifdef USE_3D_SSAO
712                cgGLSetParameterArray3f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples3);
713#else
714                cgGLSetParameterArray2f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples2);
715#endif
716        }
717
718        Vector3 tl, tr, bl, br;
719        ComputeViewVectors(tl, tr, bl, br);
720
721        cgGLSetParameter3f(sBLParam, bl.x, bl.y, bl.z);
722        cgGLSetParameter3f(sBRParam, br.x, br.y, br.z);
723        cgGLSetParameter3f(sTLParam, tl.x, tl.y, tl.z);
724        cgGLSetParameter3f(sTRParam, tr.x, tr.y, tr.z);
725
726
727        glBegin(GL_QUADS);
728
729        // note: slightly larger texture could hide ambient occlusion error on border but costs resolution
730        const float offs = 0.5f;
731       
732        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f(-offs, -offs, -0.5f);
733        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f( offs, -offs, -0.5f);
734        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f( offs,  offs, -0.5f);
735        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f(-offs,  offs, -0.5f);
736
737        glEnd();
738
739        cgGLDisableTextureParameter(sColorsTexParam);
740        cgGLDisableTextureParameter(sPositionsTexParam);
741        cgGLDisableTextureParameter(sNormalsTexParam);
742        cgGLDisableTextureParameter(sNoiseTexParam);
743        cgGLDisableTextureParameter(sOldTexParam);
744
745
746        FrameBufferObject::Release();
747
748        PrintGLerror("ssao first pass");
749}
750
751
752void DeferredRenderer::ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
753{
754        Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
755
756        mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
757
758        bl = Normalize(nbl - fbl);
759        br = Normalize(nbr - fbr);
760        tl = Normalize(ntl - ftl);
761        tr = Normalize(ntr - ftr);
762}
763
764
765static void SetVertex(float x, float y, float x_offs, float y_offs)
766{
767        glMultiTexCoord2fARB(GL_TEXTURE0_ARB, x, y); // center
768        glMultiTexCoord2fARB(GL_TEXTURE1_ARB, x - x_offs, y + y_offs); // left top
769        glMultiTexCoord2fARB(GL_TEXTURE2_ARB, x + x_offs, y - y_offs); // right bottom
770        glMultiTexCoord2fARB(GL_TEXTURE3_ARB, x + x_offs, y + y_offs); // right top
771        glMultiTexCoord2fARB(GL_TEXTURE4_ARB, x - x_offs, y - y_offs); // left bottom
772
773        glMultiTexCoord4fARB(GL_TEXTURE5_ARB, x - x_offs, y, x + x_offs, y); // left right
774        glMultiTexCoord4fARB(GL_TEXTURE6_ARB, x, y + y_offs, x, y - y_offs); // top bottom
775
776        glVertex3f(x - 0.5f, y - 0.5f, -0.5f);
777}
778
779
780void DeferredRenderer::AntiAliasing(FrameBufferObject *fbo, DirectionalLight *light)
781{
782        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
783
784        GLuint colorsTex = colorBuffer->GetTexture();
785        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
786       
787        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
788
789        cgGLEnableProfile(RenderState::sCgFragmentProfile);
790        cgGLBindProgram(sCgAntiAliasingProgram);
791       
792        cgGLSetTextureParameter(sColorsTexAntiAliasingParam, colorsTex);
793        cgGLEnableTextureParameter(sColorsTexAntiAliasingParam);
794
795        cgGLSetTextureParameter(sNormalsTexAntiAliasingParam, normalsTex);
796        cgGLEnableTextureParameter(sNormalsTexAntiAliasingParam);
797
798
799        glColor3f(1.0f, 1.0f, 1.0f);
800
801        glBegin(GL_QUADS);
802
803        // the neighbouring texels
804        float x_offs = 1.0f / mWidth;
805        float y_offs = 1.0f / mHeight;
806
807        SetVertex(0, 0, x_offs, y_offs);
808        SetVertex(1, 0, x_offs, y_offs);
809        SetVertex(1, 1, x_offs, y_offs);
810        SetVertex(0, 1, x_offs, y_offs);
811
812        glEnd();
813
814        cgGLDisableTextureParameter(sColorsTexAntiAliasingParam);
815        cgGLDisableTextureParameter(sNormalsTexAntiAliasingParam);
816
817        PrintGLerror("antialiasing");
818}
819
820
821void DeferredRenderer::FirstPass(FrameBufferObject *fbo, DirectionalLight *light)
822{
823        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
824        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
825        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
826
827        fbo->Bind();
828
829        colorBufferIdx = 3 - colorBufferIdx;
830        glDrawBuffers(1, mrt + colorBufferIdx);
831
832        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
833       
834        cgGLEnableProfile(RenderState::sCgFragmentProfile);
835
836        cgGLBindProgram(sCgDeferredProgram);
837
838        cgGLSetTextureParameter(sColorsTexDeferredParam, colorsTex);
839        cgGLEnableTextureParameter(sColorsTexDeferredParam);
840
841        cgGLSetTextureParameter(sPositionsTexDeferredParam, positionsTex);
842        cgGLEnableTextureParameter(sPositionsTexDeferredParam);
843
844        cgGLSetTextureParameter(sNormalsTexDeferredParam, normalsTex);
845        cgGLEnableTextureParameter(sNormalsTexDeferredParam);
846       
847        Vector3 lightDir = -light->GetDirection();
848        cgGLSetParameter3f(sLightDirParam, lightDir.x, lightDir.y, lightDir.z);
849
850
851        glColor3f(1.0f, 1.0f, 1.0f);
852
853        const float offs = 0.5f;
854
855        glBegin(GL_QUADS);
856
857        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
858        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
859        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
860        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
861
862        glEnd();
863
864        cgGLDisableTextureParameter(sColorsTexDeferredParam);
865        cgGLDisableTextureParameter(sPositionsTexDeferredParam);
866        cgGLDisableTextureParameter(sNormalsTexDeferredParam);
867
868        cgGLDisableProfile(RenderState::sCgFragmentProfile);
869
870        FrameBufferObject::Release();
871
872        PrintGLerror("deferred shading");
873}
874
875
876
877void DeferredRenderer::ComputeGlobIllum(FrameBufferObject *fbo,
878                                                                                float tempCohFactor,
879                                                                                const Matrix4x4 &oldProjViewMatrix)
880{
881        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixGiParam, (const float *)oldProjViewMatrix.x);
882
883        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
884        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
885        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
886
887        // generate mip map levels for position texture
888        //glBindTexture(GL_TEXTURE_2D, positionsTex); glGenerateMipmapEXT(GL_TEXTURE_2D);
889
890        // read the second buffer, write to the first buffer
891        mFbo->Bind();
892
893        glDrawBuffers(2, mrt + mFboIndex);
894
895        GLuint oldSsaoTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
896        GLuint oldIllumTex = mFbo->GetColorBuffer(2 - mFboIndex + 1)->GetTexture();
897
898        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
899
900        cgGLEnableProfile(RenderState::sCgFragmentProfile);
901        cgGLBindProgram(sCgGiProgram);
902
903        cgGLSetTextureParameter(sPositionsTexGiParam, positionsTex);
904        cgGLEnableTextureParameter(sPositionsTexGiParam);
905
906        cgGLSetTextureParameter(sColorsTexGiParam, colorsTex);
907        cgGLEnableTextureParameter(sColorsTexGiParam);
908
909        cgGLSetTextureParameter(sNormalsTexGiParam, normalsTex);
910        cgGLEnableTextureParameter(sNormalsTexGiParam);
911
912        cgGLSetTextureParameter(sNoiseTexGiParam, noiseTex);
913        cgGLEnableTextureParameter(sNoiseTexGiParam);
914
915        cgGLSetTextureParameter(sOldSsaoTexGiParam, oldSsaoTex);
916        cgGLEnableTextureParameter(sOldSsaoTexGiParam);
917
918        cgGLSetTextureParameter(sOldIllumTexGiParam, oldIllumTex);
919        cgGLEnableTextureParameter(sOldIllumTexGiParam);
920
921        cgGLSetParameter1f(sMaxDepthGiParam, mScaleFactor);
922
923
924        cgGLSetParameter1f(sTemporalCoherenceGiParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
925
926
927        if (mUseTemporalCoherence || mRegenerateSamples)
928        {
929                mRegenerateSamples = false;
930
931                // q: should we generate new samples or only rotate the old ones?
932                // in the first case, the sample patterns look nicer, but the kernel
933                // needs longer to converge
934                GenerateSamples(mSamplingMethod);
935
936#ifdef USE_3D_SSAO
937                cgGLSetParameterArray3f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples3);
938#else
939                cgGLSetParameterArray2f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples2);
940#endif
941        }
942
943
944        Vector3 tl, tr, bl, br;
945        ComputeViewVectors(tl, tr, bl, br);
946       
947        const Vector3 pos = mCamera->GetPosition() / mScaleFactor;
948        cgGLSetParameter3f(sEyePosGiParam, pos.x, pos.y, pos.z);
949
950        cgGLSetParameter3f(sBLGiParam, bl.x, bl.y, bl.z);
951        cgGLSetParameter3f(sBRGiParam, br.x, br.y, br.z);
952        cgGLSetParameter3f(sTLGiParam, tl.x, tl.y, tl.z);
953        cgGLSetParameter3f(sTRGiParam, tr.x, tr.y, tr.z);
954
955
956        glBegin(GL_QUADS);
957
958        // note: slightly larger texture hides ambient occlusion error on border but costs resolution
959        //const float new_offs = 0.55f;
960        const float new_offs = 0.5f;
961               
962        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f(-new_offs, -new_offs, -0.5f);
963        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f( new_offs, -new_offs, -0.5f);
964        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f( new_offs,  new_offs, -0.5f);
965        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f(-new_offs,  new_offs, -0.5f);
966
967        glEnd();
968
969        cgGLDisableTextureParameter(sColorsTexGiParam);
970        cgGLDisableTextureParameter(sPositionsTexGiParam);
971        cgGLDisableTextureParameter(sNormalsTexGiParam);
972        cgGLDisableTextureParameter(sNoiseTexGiParam);
973        cgGLDisableTextureParameter(sOldSsaoTexGiParam);
974        cgGLDisableTextureParameter(sOldIllumTexGiParam);
975
976        FrameBufferObject::Release();
977
978        PrintGLerror("globillum first pass");
979}
980
981
982void DeferredRenderer::CombineIllum(FrameBufferObject *fbo)
983{
984        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
985
986        GLuint ssaoTex = mFbo->GetColorBuffer(mFboIndex)->GetTexture();
987        GLuint illumTex = mFbo->GetColorBuffer(mFboIndex + 1)->GetTexture();
988
989
990        fbo->Bind();
991
992        // overwrite old color texture
993        colorBufferIdx = 3 - colorBufferIdx;
994
995        glDrawBuffers(1, mrt + colorBufferIdx);
996
997        cgGLEnableProfile(RenderState::sCgFragmentProfile);
998
999        cgGLBindProgram(sCgCombinedIllumProgram);
1000
1001        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1002       
1003
1004        cgGLSetTextureParameter(sColorsTexCombinedIllumParam, colorsTex);
1005        cgGLEnableTextureParameter(sColorsTexCombinedIllumParam);
1006
1007        cgGLSetTextureParameter(sSsaoTexCombinedIllumParam, ssaoTex);
1008        cgGLEnableTextureParameter(sSsaoTexCombinedIllumParam);
1009
1010        cgGLSetTextureParameter(sIllumTexCombinedIllumParam, illumTex);
1011        cgGLEnableTextureParameter(sIllumTexCombinedIllumParam);
1012       
1013        glColor3f(1.0f, 1.0f, 1.0f);
1014
1015        const float offs = 0.5f;
1016
1017        glBegin(GL_QUADS);
1018
1019        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
1020        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
1021        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
1022        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
1023
1024        glEnd();
1025
1026        cgGLDisableTextureParameter(sColorsTexCombinedIllumParam);
1027        cgGLDisableTextureParameter(sSsaoTexCombinedIllumParam);
1028        cgGLDisableTextureParameter(sIllumTexCombinedIllumParam);
1029
1030        cgGLDisableProfile(RenderState::sCgFragmentProfile);
1031
1032        FrameBufferObject::Release();
1033
1034        PrintGLerror("combine");
1035}
1036
1037
1038void DeferredRenderer::CombineSsao(FrameBufferObject *fbo)
1039{
1040        fbo->Bind();
1041
1042        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
1043        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
1044        GLuint ssaoTex = mFbo->GetColorBuffer(mFboIndex)->GetTexture();
1045
1046        // overwrite old color texture
1047        colorBufferIdx = 3 - colorBufferIdx;
1048        glDrawBuffers(1, mrt + colorBufferIdx);
1049
1050        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1051       
1052        cgGLEnableProfile(RenderState::sCgFragmentProfile);
1053
1054        cgGLBindProgram(sCgCombinedSsaoProgram);
1055
1056        cgGLSetTextureParameter(sColorsTexCombinedSsaoParam, colorsTex);
1057        cgGLEnableTextureParameter(sColorsTexCombinedSsaoParam);
1058
1059        cgGLSetTextureParameter(sSsaoTexCombinedSsaoParam, ssaoTex);
1060        cgGLEnableTextureParameter(sSsaoTexCombinedSsaoParam);
1061
1062        cgGLSetTextureParameter(sPositionsTexCombinedSsaoParam, positionsTex);
1063        cgGLEnableTextureParameter(sPositionsTexCombinedSsaoParam);
1064       
1065        glColor3f(1.0f, 1.0f, 1.0f);
1066
1067        const float offs = 0.5f;
1068
1069        glBegin(GL_QUADS);
1070
1071        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
1072        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
1073        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
1074        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
1075
1076        glEnd();
1077
1078        cgGLDisableTextureParameter(sColorsTexCombinedSsaoParam);
1079        cgGLDisableTextureParameter(sSsaoTexCombinedSsaoParam);
1080        cgGLDisableTextureParameter(sPositionsTexCombinedSsaoParam);
1081       
1082        cgGLDisableProfile(RenderState::sCgFragmentProfile);
1083
1084        FrameBufferObject::Release();
1085
1086        PrintGLerror("combine ssao");
1087}
1088
1089
1090void DeferredRenderer::FirstPassShadow(FrameBufferObject *fbo,
1091                                                                           DirectionalLight *light,
1092                                                                           ShadowMap *shadowMap)
1093{
1094        fbo->Bind();
1095
1096        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
1097
1098        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
1099        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
1100        GLuint shadowTex = shadowMap->GetDepthTexture();
1101
1102        Matrix4x4 shadowMatrix;
1103        shadowMap->GetTextureMatrix(shadowMatrix);
1104
1105        colorBufferIdx = 3 - colorBufferIdx;
1106        glDrawBuffers(1, mrt + colorBufferIdx);
1107
1108       
1109        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1110
1111        cgGLBindProgram(sCgDeferredShadowProgram);
1112
1113        cgGLSetTextureParameter(sColorsTexShadowParam, colorsTex);
1114        cgGLEnableTextureParameter(sColorsTexShadowParam);
1115
1116        cgGLSetTextureParameter(sPositionsTexShadowParam, positionsTex);
1117        cgGLEnableTextureParameter(sPositionsTexShadowParam);
1118
1119        cgGLSetTextureParameter(sNormalsTexShadowParam, normalsTex);
1120        cgGLEnableTextureParameter(sNormalsTexShadowParam);
1121       
1122        cgGLSetTextureParameter(sShadowMapParam, shadowTex);
1123        cgGLEnableTextureParameter(sShadowMapParam);
1124
1125        cgGLSetParameter1f(sMaxDepthShadowParam, mScaleFactor);
1126
1127        cgGLSetParameter1f(sSampleWidthParam, 2.0f / shadowMap->GetSize());
1128       
1129         
1130        cgGLSetMatrixParameterfc(sShadowMatrixParam, (const float *)shadowMatrix.x);
1131
1132        cgGLSetTextureParameter(sNoiseTexShadowParam, noiseTex);
1133        cgGLEnableTextureParameter(sNoiseTexShadowParam);
1134
1135        Vector3 lightDir = -light->GetDirection();
1136        cgGLSetParameter3f(sLightDirShadowParam, lightDir.x, lightDir.y, lightDir.z);
1137
1138
1139        glColor3f(1.0f, 1.0f, 1.0f);
1140       
1141        glBegin(GL_QUADS);
1142
1143        float offs2 = 0.5f;
1144
1145        glTexCoord2f(0, 0); glVertex3f(-offs2, -offs2, -0.5f);
1146        glTexCoord2f(1, 0); glVertex3f( offs2, -offs2, -0.5f);
1147        glTexCoord2f(1, 1); glVertex3f( offs2,  offs2, -0.5f);
1148        glTexCoord2f(0, 1); glVertex3f(-offs2,  offs2, -0.5f);
1149
1150        glEnd();
1151
1152        cgGLDisableTextureParameter(sColorsTexShadowParam);
1153        cgGLDisableTextureParameter(sPositionsTexShadowParam);
1154        cgGLDisableTextureParameter(sNormalsTexShadowParam);
1155        cgGLDisableTextureParameter(sShadowMapParam);
1156        cgGLDisableTextureParameter(sNoiseTexShadowParam);
1157
1158        FrameBufferObject::Release();
1159
1160        PrintGLerror("deferred shading + shadows");
1161}
1162
1163
1164void DeferredRenderer::SetSamplingMethod(SAMPLING_METHOD s)
1165{
1166        if (s != mSamplingMethod)
1167        {
1168                mSamplingMethod = s;
1169                mRegenerateSamples = true;
1170        }
1171}
1172
1173
1174void DeferredRenderer::SetShadingMethod(SHADING_METHOD s)
1175{
1176        if (s != mShadingMethod)
1177        {
1178                mShadingMethod = s;
1179                mRegenerateSamples = true;
1180        }
1181}
1182
1183
1184void DeferredRenderer::ComputeToneParameters(FrameBufferObject *fbo,
1185                                                                                         DirectionalLight *light,
1186                                                                                         float &imageKey,
1187                                                                                         float &whiteLum,
1188                                                                                         float &middleGrey)
1189{
1190        // hack: estimate value where sky burns out
1191        whiteLum = log(1e4f);
1192       
1193        ////////////////////
1194        //-- linear interpolate brightness key depending on the current sun position
1195
1196        const float minKey = 0.09f;
1197        const float maxKey = 0.5f;
1198
1199        const float lightIntensity = DotProd(-light->GetDirection(), Vector3::UNIT_Z());
1200        middleGrey = lightIntensity * maxKey + (1.0f - lightIntensity) * minKey;
1201
1202#if 1
1203
1204        //////////
1205        //-- compute avg loglum
1206
1207        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
1208        GLuint colorsTex = colorBuffer->GetTexture();
1209
1210        fbo->Bind();
1211
1212        colorBufferIdx = 3 - colorBufferIdx;
1213        glDrawBuffers(1, mrt + colorBufferIdx);
1214       
1215
1216        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1217
1218        cgGLEnableProfile(RenderState::sCgFragmentProfile);
1219        cgGLBindProgram(sCgLogLumProgram);
1220       
1221        cgGLSetTextureParameter(sColorsTexLogLumParam, colorsTex);
1222        cgGLEnableTextureParameter(sColorsTexLogLumParam);
1223       
1224        const float offs = 0.5f;
1225
1226        glBegin(GL_QUADS);
1227
1228        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
1229        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
1230        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
1231        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
1232
1233        glEnd();
1234
1235        cgGLDisableTextureParameter(sColorsTexLogLumParam);
1236
1237        FrameBufferObject::Release();
1238
1239        PrintGLerror("ToneMapParams");
1240
1241#endif
1242
1243        ///////////////////
1244        //-- compute avg loglum in scene using mipmapping
1245
1246        glBindTexture(GL_TEXTURE_2D, fbo->GetColorBuffer(colorBufferIdx)->GetTexture());
1247        glGenerateMipmapEXT(GL_TEXTURE_2D);
1248}
1249
1250
1251void DeferredRenderer::DownSample(FrameBufferObject *fbo)
1252{
1253        GLuint intensityTex=0;
1254       
1255        cgGLEnableProfile(RenderState::sCgFragmentProfile);
1256        cgGLBindProgram(sCgDownSampleProgram);
1257       
1258        cgGLSetTextureParameter(sIntensityTexDownSampleParam, intensityTex);
1259        cgGLEnableTextureParameter(sIntensityTexDownSampleParam);
1260}
1261
1262
1263void DeferredRenderer::ToneMap(FrameBufferObject *fbo,
1264                                                           DirectionalLight *light,
1265                                                           float imageKey,
1266                                                           float whiteLum,
1267                                                           float middleGrey)
1268{
1269        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
1270
1271        fbo->Bind();
1272
1273        colorBufferIdx = 3 - colorBufferIdx;
1274        glDrawBuffers(1, mrt + colorBufferIdx);
1275
1276
1277        GLuint colorsTex = colorBuffer->GetTexture();
1278       
1279        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1280
1281        cgGLEnableProfile(RenderState::sCgFragmentProfile);
1282        cgGLBindProgram(sCgToneProgram);
1283       
1284        cgGLSetTextureParameter(sColorsTexToneParam, colorsTex);
1285        cgGLEnableTextureParameter(sColorsTexToneParam);
1286
1287        cgGLSetParameter1f(sImageKeyParam, imageKey);
1288        cgGLSetParameter1f(sWhiteLumParam, whiteLum);
1289        cgGLSetParameter1f(sMiddleGreyParam, middleGrey);
1290
1291        glColor3f(1.0f, 1.0f, 1.0f);
1292
1293        glBegin(GL_QUADS);
1294
1295        // the neighbouring texels
1296        const float x_offs = 1.0f / mWidth;
1297        const float y_offs = 1.0f / mHeight;
1298
1299        SetVertex(0, 0, x_offs, y_offs);
1300        SetVertex(1, 0, x_offs, y_offs);
1301        SetVertex(1, 1, x_offs, y_offs);
1302        SetVertex(0, 1, x_offs, y_offs);
1303
1304        glEnd();
1305
1306        cgGLDisableTextureParameter(sColorsTexToneParam);
1307        FrameBufferObject::Release();
1308
1309        PrintGLerror("ToneMap");
1310}
1311
1312
1313
1314
1315} // namespace
Note: See TracBrowser for help on using the repository browser.