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

Revision 2994, 38.7 KB checked in by mattausch, 16 years ago (diff)

started to use a downsampling fbo

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 sCgDownSampleProgram;
41static CGprogram sCgToneProgram;
42static CGprogram sCgLogLumProgram;
43
44
45
46///////////////////////////////////////
47
48
49static CGparameter sColorsTexParam;
50static CGparameter sPositionsTexParam;
51static CGparameter sNormalsTexParam;
52
53static CGparameter sOldModelViewProjMatrixParam;
54static CGparameter sModelViewProjMatrixParam;
55static CGparameter sMaxDepthParam;
56static CGparameter sEyePosParam;
57static CGparameter sSamplesParam;
58static CGparameter sOldTexParam;
59static CGparameter sNoiseTexParam;
60static CGparameter sTemporalCoherenceParam;
61
62
63///////////////////////////////////////
64
65
66static CGparameter sColorsTexGiParam;
67static CGparameter sPositionsTexGiParam;
68static CGparameter sNormalsTexGiParam;
69
70
71static CGparameter sOldModelViewProjMatrixGiParam;
72static CGparameter sMaxDepthGiParam;
73static CGparameter sSamplesGiParam;
74static CGparameter sOldSsaoTexGiParam;
75static CGparameter sOldIllumTexGiParam;
76static CGparameter sNoiseTexGiParam;
77static CGparameter sTemporalCoherenceGiParam;
78
79
80static CGparameter sColorsTexCombinedIllumParam;
81static CGparameter sSsaoTexCombinedIllumParam;
82static CGparameter sIllumTexCombinedIllumParam;
83
84static CGparameter sColorsTexCombinedSsaoParam;
85static CGparameter sSsaoTexCombinedSsaoParam;
86static CGparameter sPositionsTexCombinedSsaoParam;
87
88static CGparameter sTLParam;
89static CGparameter sTRParam;
90static CGparameter sBRParam;
91static CGparameter sBLParam;
92
93
94static CGparameter sTLGiParam;
95static CGparameter sTRGiParam;
96static CGparameter sBRGiParam;
97static CGparameter sBLGiParam;
98
99static CGparameter sEyePosGiParam;
100
101
102
103////////////
104
105static CGparameter sColorsTexAntiAliasingParam;
106static CGparameter sNormalsTexAntiAliasingParam;
107
108
109static CGparameter sShadowMapParam;
110static CGparameter sPositionsTexShadowParam; 
111static CGparameter sColorsTexShadowParam; 
112static CGparameter sNormalsTexShadowParam;
113
114static CGparameter sShadowMatrixParam;
115static CGparameter sMaxDepthShadowParam;
116static CGparameter sSampleWidthParam;
117
118static CGparameter sNoiseTexShadowParam;
119static CGparameter sSamplesShadowParam;
120
121static CGparameter sLightDirParam;
122static CGparameter sLightDirShadowParam;
123static CGparameter sImageKeyParam;
124static CGparameter sMiddleGreyParam;
125static CGparameter sWhiteLumParam;
126
127
128static CGparameter sColorsTexInitialParam;
129static CGparameter sColorsTexToneParam;
130
131static CGparameter sColorsTexDownSampleParam;
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        sCgDownSampleProgram =
535                cgCreateProgramFromFile(context,
536                                                                CG_SOURCE,
537                                                                "src/shaders/tonemap.cg",
538                                                                RenderState::sCgFragmentProfile,
539                                                                "GreyScaleDownSample",
540                                                                NULL);
541
542        if (sCgDownSampleProgram != NULL)
543        {
544                cgGLLoadProgram(sCgDownSampleProgram);
545
546                // we need size of texture for scaling
547                sColorsTexDownSampleParam = cgGetNamedParameter(sCgDownSampleProgram, "colors"); 
548        }
549        else
550                cerr << "intensity program failed to load" << endl;
551
552        PrintGLerror("init");
553}
554
555
556void DeferredRenderer::Render(FrameBufferObject *fbo,
557                                                          const Matrix4x4 &oldProjViewMatrix,
558                                                          const Matrix4x4 &projViewMatrix,
559                                                          float tempCohFactor,
560                                                          DirectionalLight *light,
561                                                          bool useToneMapping,
562                                                          ShadowMap *shadowMap
563                                                          )
564{
565        // switch roles of old and new fbo
566        // the algorihm uses two input fbos, where the one
567        // contais the color buffer from the last frame,
568        // the other one will be written
569
570        mFboIndex = 2 - mFboIndex;
571       
572        FrameBufferObject::Release();
573
574        cgGLEnableProfile(RenderState::sCgFragmentProfile);
575
576        glDisable(GL_ALPHA_TEST);
577        glDisable(GL_TEXTURE_2D);
578        glDisable(GL_LIGHTING);
579
580        glPushAttrib(GL_VIEWPORT_BIT);
581        glViewport(0, 0, mWidth, mHeight);
582
583        glMatrixMode(GL_PROJECTION);
584        glPushMatrix();
585        glLoadIdentity();
586
587        const float offs = 0.5f;
588        glOrtho(-offs, offs, -offs, offs, 0, 1);
589
590        glMatrixMode(GL_MODELVIEW);
591        glPushMatrix();
592        glLoadIdentity();
593
594        if (shadowMap)
595                FirstPassShadow(fbo, light, shadowMap);
596        else
597                FirstPass(fbo, light);
598
599        switch (mShadingMethod)
600        {
601        case SSAO:
602                ComputeSsao(fbo, tempCohFactor, oldProjViewMatrix, projViewMatrix);
603                CombineSsao(fbo);
604                break;
605        case GI:
606                ComputeGlobIllum(fbo, tempCohFactor, oldProjViewMatrix);
607                CombineIllum(fbo);
608                break;
609        default: // DEFAULT
610                // do nothing: standard deferred shading
611                break;
612        }
613
614        if (useToneMapping)
615        {
616                float imageKey, whiteLum, middleGrey;
617
618                ComputeToneParameters(fbo, light, imageKey, whiteLum, middleGrey);
619                ToneMap(fbo, light, imageKey, whiteLum, middleGrey);
620        }
621
622        AntiAliasing(fbo, light);
623
624        glEnable(GL_LIGHTING);
625        glDisable(GL_TEXTURE_2D);
626
627        glMatrixMode(GL_PROJECTION);
628        glPopMatrix();
629
630        glMatrixMode(GL_MODELVIEW);
631        glPopMatrix();
632
633        glPopAttrib();
634
635        cgGLDisableProfile(RenderState::sCgFragmentProfile);
636}
637
638
639void DeferredRenderer::ComputeSsao(FrameBufferObject *fbo,
640                                                                   float tempCohFactor,
641                                                                   const Matrix4x4 &oldProjViewMatrix,
642                                                                   const Matrix4x4 &projViewMatrix
643                                                                   )
644{
645#ifdef USE_3D_SSAO
646        // bias from [-1, 1] to [0, 1]
647        static Matrix4x4 biasMatrix(0.5f, 0.0f, 0.0f, 0.5f,
648                                                                0.0f, 0.5f, 0.0f, 0.5f,
649                                                                0.0f, 0.0f, 0.5f, 0.5f,
650                                                                0.0f, 0.0f, 0.0f, 1.0f);
651
652        Matrix4x4 m = projViewMatrix * biasMatrix;
653
654        cgGLSetMatrixParameterfc(sModelViewProjMatrixParam, (const float *)m.x);
655#endif
656
657        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixParam, (const float *)oldProjViewMatrix.x);
658
659        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
660        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
661        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
662
663        // generate mip map levels of position in order to improve texture lookup performance
664        //glBindTexture(GL_TEXTURE_2D, positionsTex); glGenerateMipmapEXT(GL_TEXTURE_2D);
665        //glBindTexture(GL_TEXTURE_2D, colorsTex); glGenerateMipmapEXT(GL_TEXTURE_2D);
666
667        // read the second buffer, write to the first buffer
668        mFbo->Bind();
669        glDrawBuffers(1, mrt + mFboIndex);
670
671        GLuint oldTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
672
673        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
674
675        cgGLEnableProfile(RenderState::sCgFragmentProfile);
676        cgGLBindProgram(sCgSsaoProgram);
677
678        cgGLSetTextureParameter(sPositionsTexParam, positionsTex);
679        cgGLEnableTextureParameter(sPositionsTexParam);
680
681        cgGLSetTextureParameter(sColorsTexParam, colorsTex);
682        cgGLEnableTextureParameter(sColorsTexParam);
683
684        cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
685        cgGLEnableTextureParameter(sNormalsTexParam);
686
687        cgGLSetTextureParameter(sNoiseTexParam, noiseTex);
688        cgGLEnableTextureParameter(sNoiseTexParam);
689
690        cgGLSetTextureParameter(sOldTexParam, oldTex);
691        cgGLEnableTextureParameter(sOldTexParam);
692       
693        cgGLSetParameter1f(sMaxDepthParam, mScaleFactor);
694
695        Vector3 pos = mCamera->GetPosition() / mScaleFactor;
696        cgGLSetParameter3f(sEyePosParam, pos.x, pos.y, pos.z);
697       
698        cgGLSetParameter1f(sTemporalCoherenceParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
699
700        if (mUseTemporalCoherence || mRegenerateSamples)
701        {
702                mRegenerateSamples = false;
703
704                // q: should we generate new samples or only rotate the old ones?
705                // in the first case, the sample patterns look nicer, but the kernel
706                // needs longer to converge
707                GenerateSamples(mSamplingMethod);
708
709#ifdef USE_3D_SSAO
710                cgGLSetParameterArray3f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples3);
711#else
712                cgGLSetParameterArray2f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples2);
713#endif
714        }
715
716        Vector3 tl, tr, bl, br;
717        ComputeViewVectors(tl, tr, bl, br);
718
719        cgGLSetParameter3f(sBLParam, bl.x, bl.y, bl.z);
720        cgGLSetParameter3f(sBRParam, br.x, br.y, br.z);
721        cgGLSetParameter3f(sTLParam, tl.x, tl.y, tl.z);
722        cgGLSetParameter3f(sTRParam, tr.x, tr.y, tr.z);
723
724
725        glBegin(GL_QUADS);
726
727        // note: slightly larger texture could hide ambient occlusion error on border but costs resolution
728        const float offs = 0.5f;
729       
730        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f(-offs, -offs, -0.5f);
731        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f( offs, -offs, -0.5f);
732        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f( offs,  offs, -0.5f);
733        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f(-offs,  offs, -0.5f);
734
735        glEnd();
736
737        cgGLDisableTextureParameter(sColorsTexParam);
738        cgGLDisableTextureParameter(sPositionsTexParam);
739        cgGLDisableTextureParameter(sNormalsTexParam);
740        cgGLDisableTextureParameter(sNoiseTexParam);
741        cgGLDisableTextureParameter(sOldTexParam);
742
743
744        FrameBufferObject::Release();
745
746        PrintGLerror("ssao first pass");
747}
748
749
750void DeferredRenderer::ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
751{
752        Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
753
754        mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
755
756        bl = Normalize(nbl - fbl);
757        br = Normalize(nbr - fbr);
758        tl = Normalize(ntl - ftl);
759        tr = Normalize(ntr - ftr);
760}
761
762
763static void SetVertex(float x, float y, float x_offs, float y_offs)
764{
765        glMultiTexCoord2fARB(GL_TEXTURE0_ARB, x, y); // center
766        glMultiTexCoord2fARB(GL_TEXTURE1_ARB, x - x_offs, y + y_offs); // left top
767        glMultiTexCoord2fARB(GL_TEXTURE2_ARB, x + x_offs, y - y_offs); // right bottom
768        glMultiTexCoord2fARB(GL_TEXTURE3_ARB, x + x_offs, y + y_offs); // right top
769        glMultiTexCoord2fARB(GL_TEXTURE4_ARB, x - x_offs, y - y_offs); // left bottom
770
771        glMultiTexCoord4fARB(GL_TEXTURE5_ARB, x - x_offs, y, x + x_offs, y); // left right
772        glMultiTexCoord4fARB(GL_TEXTURE6_ARB, x, y + y_offs, x, y - y_offs); // top bottom
773
774        glVertex3f(x - 0.5f, y - 0.5f, -0.5f);
775}
776
777
778void DeferredRenderer::AntiAliasing(FrameBufferObject *fbo, DirectionalLight *light)
779{
780        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
781
782        GLuint colorsTex = colorBuffer->GetTexture();
783        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
784       
785        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
786
787        cgGLEnableProfile(RenderState::sCgFragmentProfile);
788        cgGLBindProgram(sCgAntiAliasingProgram);
789       
790        cgGLSetTextureParameter(sColorsTexAntiAliasingParam, colorsTex);
791        cgGLEnableTextureParameter(sColorsTexAntiAliasingParam);
792
793        cgGLSetTextureParameter(sNormalsTexAntiAliasingParam, normalsTex);
794        cgGLEnableTextureParameter(sNormalsTexAntiAliasingParam);
795
796
797        glColor3f(1.0f, 1.0f, 1.0f);
798
799        glBegin(GL_QUADS);
800
801        // the neighbouring texels
802        float x_offs = 1.0f / mWidth;
803        float y_offs = 1.0f / mHeight;
804
805        SetVertex(0, 0, x_offs, y_offs);
806        SetVertex(1, 0, x_offs, y_offs);
807        SetVertex(1, 1, x_offs, y_offs);
808        SetVertex(0, 1, x_offs, y_offs);
809
810        glEnd();
811
812        cgGLDisableTextureParameter(sColorsTexAntiAliasingParam);
813        cgGLDisableTextureParameter(sNormalsTexAntiAliasingParam);
814
815        PrintGLerror("antialiasing");
816}
817
818
819void DeferredRenderer::FirstPass(FrameBufferObject *fbo, DirectionalLight *light)
820{
821        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
822        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
823        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
824
825        fbo->Bind();
826
827        colorBufferIdx = 3 - colorBufferIdx;
828        glDrawBuffers(1, mrt + colorBufferIdx);
829
830        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
831       
832        cgGLEnableProfile(RenderState::sCgFragmentProfile);
833
834        cgGLBindProgram(sCgDeferredProgram);
835
836        cgGLSetTextureParameter(sColorsTexDeferredParam, colorsTex);
837        cgGLEnableTextureParameter(sColorsTexDeferredParam);
838
839        cgGLSetTextureParameter(sPositionsTexDeferredParam, positionsTex);
840        cgGLEnableTextureParameter(sPositionsTexDeferredParam);
841
842        cgGLSetTextureParameter(sNormalsTexDeferredParam, normalsTex);
843        cgGLEnableTextureParameter(sNormalsTexDeferredParam);
844       
845        Vector3 lightDir = -light->GetDirection();
846        cgGLSetParameter3f(sLightDirParam, lightDir.x, lightDir.y, lightDir.z);
847
848
849        glColor3f(1.0f, 1.0f, 1.0f);
850
851        const float offs = 0.5f;
852
853        glBegin(GL_QUADS);
854
855        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
856        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
857        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
858        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
859
860        glEnd();
861
862        cgGLDisableTextureParameter(sColorsTexDeferredParam);
863        cgGLDisableTextureParameter(sPositionsTexDeferredParam);
864        cgGLDisableTextureParameter(sNormalsTexDeferredParam);
865
866        cgGLDisableProfile(RenderState::sCgFragmentProfile);
867
868        FrameBufferObject::Release();
869
870        PrintGLerror("deferred shading");
871}
872
873
874
875void DeferredRenderer::ComputeGlobIllum(FrameBufferObject *fbo,
876                                                                                float tempCohFactor,
877                                                                                const Matrix4x4 &oldProjViewMatrix)
878{
879        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixGiParam, (const float *)oldProjViewMatrix.x);
880
881        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
882        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
883        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
884
885        // generate mip map levels for position texture
886        //glBindTexture(GL_TEXTURE_2D, positionsTex); glGenerateMipmapEXT(GL_TEXTURE_2D);
887
888        // read the second buffer, write to the first buffer
889        mFbo->Bind();
890
891        glDrawBuffers(2, mrt + mFboIndex);
892
893        GLuint oldSsaoTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
894        GLuint oldIllumTex = mFbo->GetColorBuffer(2 - mFboIndex + 1)->GetTexture();
895
896        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
897
898        cgGLEnableProfile(RenderState::sCgFragmentProfile);
899        cgGLBindProgram(sCgGiProgram);
900
901        cgGLSetTextureParameter(sPositionsTexGiParam, positionsTex);
902        cgGLEnableTextureParameter(sPositionsTexGiParam);
903
904        cgGLSetTextureParameter(sColorsTexGiParam, colorsTex);
905        cgGLEnableTextureParameter(sColorsTexGiParam);
906
907        cgGLSetTextureParameter(sNormalsTexGiParam, normalsTex);
908        cgGLEnableTextureParameter(sNormalsTexGiParam);
909
910        cgGLSetTextureParameter(sNoiseTexGiParam, noiseTex);
911        cgGLEnableTextureParameter(sNoiseTexGiParam);
912
913        cgGLSetTextureParameter(sOldSsaoTexGiParam, oldSsaoTex);
914        cgGLEnableTextureParameter(sOldSsaoTexGiParam);
915
916        cgGLSetTextureParameter(sOldIllumTexGiParam, oldIllumTex);
917        cgGLEnableTextureParameter(sOldIllumTexGiParam);
918
919        cgGLSetParameter1f(sMaxDepthGiParam, mScaleFactor);
920
921
922        cgGLSetParameter1f(sTemporalCoherenceGiParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
923
924
925        if (mUseTemporalCoherence || mRegenerateSamples)
926        {
927                mRegenerateSamples = false;
928
929                // q: should we generate new samples or only rotate the old ones?
930                // in the first case, the sample patterns look nicer, but the kernel
931                // needs longer to converge
932                GenerateSamples(mSamplingMethod);
933
934#ifdef USE_3D_SSAO
935                cgGLSetParameterArray3f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples3);
936#else
937                cgGLSetParameterArray2f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples2);
938#endif
939        }
940
941
942        Vector3 tl, tr, bl, br;
943        ComputeViewVectors(tl, tr, bl, br);
944       
945        const Vector3 pos = mCamera->GetPosition() / mScaleFactor;
946        cgGLSetParameter3f(sEyePosGiParam, pos.x, pos.y, pos.z);
947
948        cgGLSetParameter3f(sBLGiParam, bl.x, bl.y, bl.z);
949        cgGLSetParameter3f(sBRGiParam, br.x, br.y, br.z);
950        cgGLSetParameter3f(sTLGiParam, tl.x, tl.y, tl.z);
951        cgGLSetParameter3f(sTRGiParam, tr.x, tr.y, tr.z);
952
953
954        glBegin(GL_QUADS);
955
956        // note: slightly larger texture hides ambient occlusion error on border but costs resolution
957        //const float new_offs = 0.55f;
958        const float new_offs = 0.5f;
959               
960        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f(-new_offs, -new_offs, -0.5f);
961        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f( new_offs, -new_offs, -0.5f);
962        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f( new_offs,  new_offs, -0.5f);
963        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f(-new_offs,  new_offs, -0.5f);
964
965        glEnd();
966
967        cgGLDisableTextureParameter(sColorsTexGiParam);
968        cgGLDisableTextureParameter(sPositionsTexGiParam);
969        cgGLDisableTextureParameter(sNormalsTexGiParam);
970        cgGLDisableTextureParameter(sNoiseTexGiParam);
971        cgGLDisableTextureParameter(sOldSsaoTexGiParam);
972        cgGLDisableTextureParameter(sOldIllumTexGiParam);
973
974        FrameBufferObject::Release();
975
976        PrintGLerror("globillum first pass");
977}
978
979
980void DeferredRenderer::CombineIllum(FrameBufferObject *fbo)
981{
982        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
983
984        GLuint ssaoTex = mFbo->GetColorBuffer(mFboIndex)->GetTexture();
985        GLuint illumTex = mFbo->GetColorBuffer(mFboIndex + 1)->GetTexture();
986
987
988        fbo->Bind();
989
990        // overwrite old color texture
991        colorBufferIdx = 3 - colorBufferIdx;
992
993        glDrawBuffers(1, mrt + colorBufferIdx);
994
995        cgGLEnableProfile(RenderState::sCgFragmentProfile);
996
997        cgGLBindProgram(sCgCombinedIllumProgram);
998
999        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1000       
1001
1002        cgGLSetTextureParameter(sColorsTexCombinedIllumParam, colorsTex);
1003        cgGLEnableTextureParameter(sColorsTexCombinedIllumParam);
1004
1005        cgGLSetTextureParameter(sSsaoTexCombinedIllumParam, ssaoTex);
1006        cgGLEnableTextureParameter(sSsaoTexCombinedIllumParam);
1007
1008        cgGLSetTextureParameter(sIllumTexCombinedIllumParam, illumTex);
1009        cgGLEnableTextureParameter(sIllumTexCombinedIllumParam);
1010       
1011        glColor3f(1.0f, 1.0f, 1.0f);
1012
1013        const float offs = 0.5f;
1014
1015        glBegin(GL_QUADS);
1016
1017        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
1018        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
1019        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
1020        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
1021
1022        glEnd();
1023
1024        cgGLDisableTextureParameter(sColorsTexCombinedIllumParam);
1025        cgGLDisableTextureParameter(sSsaoTexCombinedIllumParam);
1026        cgGLDisableTextureParameter(sIllumTexCombinedIllumParam);
1027
1028        cgGLDisableProfile(RenderState::sCgFragmentProfile);
1029
1030        FrameBufferObject::Release();
1031
1032        PrintGLerror("combine");
1033}
1034
1035
1036void DeferredRenderer::CombineSsao(FrameBufferObject *fbo)
1037{
1038        fbo->Bind();
1039
1040        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
1041        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
1042        GLuint ssaoTex = mFbo->GetColorBuffer(mFboIndex)->GetTexture();
1043
1044        // overwrite old color texture
1045        colorBufferIdx = 3 - colorBufferIdx;
1046        glDrawBuffers(1, mrt + colorBufferIdx);
1047
1048        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1049       
1050        cgGLEnableProfile(RenderState::sCgFragmentProfile);
1051
1052        cgGLBindProgram(sCgCombinedSsaoProgram);
1053
1054        cgGLSetTextureParameter(sColorsTexCombinedSsaoParam, colorsTex);
1055        cgGLEnableTextureParameter(sColorsTexCombinedSsaoParam);
1056
1057        cgGLSetTextureParameter(sSsaoTexCombinedSsaoParam, ssaoTex);
1058        cgGLEnableTextureParameter(sSsaoTexCombinedSsaoParam);
1059
1060        cgGLSetTextureParameter(sPositionsTexCombinedSsaoParam, positionsTex);
1061        cgGLEnableTextureParameter(sPositionsTexCombinedSsaoParam);
1062       
1063        glColor3f(1.0f, 1.0f, 1.0f);
1064
1065        const float offs = 0.5f;
1066
1067        glBegin(GL_QUADS);
1068
1069        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
1070        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
1071        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
1072        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
1073
1074        glEnd();
1075
1076        cgGLDisableTextureParameter(sColorsTexCombinedSsaoParam);
1077        cgGLDisableTextureParameter(sSsaoTexCombinedSsaoParam);
1078        cgGLDisableTextureParameter(sPositionsTexCombinedSsaoParam);
1079       
1080        cgGLDisableProfile(RenderState::sCgFragmentProfile);
1081
1082        FrameBufferObject::Release();
1083
1084        PrintGLerror("combine ssao");
1085}
1086
1087
1088void DeferredRenderer::FirstPassShadow(FrameBufferObject *fbo,
1089                                                                           DirectionalLight *light,
1090                                                                           ShadowMap *shadowMap)
1091{
1092        fbo->Bind();
1093
1094        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
1095
1096        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
1097        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
1098        GLuint shadowTex = shadowMap->GetDepthTexture();
1099
1100        Matrix4x4 shadowMatrix;
1101        shadowMap->GetTextureMatrix(shadowMatrix);
1102
1103        colorBufferIdx = 3 - colorBufferIdx;
1104        glDrawBuffers(1, mrt + colorBufferIdx);
1105
1106       
1107        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1108
1109        cgGLBindProgram(sCgDeferredShadowProgram);
1110
1111        cgGLSetTextureParameter(sColorsTexShadowParam, colorsTex);
1112        cgGLEnableTextureParameter(sColorsTexShadowParam);
1113
1114        cgGLSetTextureParameter(sPositionsTexShadowParam, positionsTex);
1115        cgGLEnableTextureParameter(sPositionsTexShadowParam);
1116
1117        cgGLSetTextureParameter(sNormalsTexShadowParam, normalsTex);
1118        cgGLEnableTextureParameter(sNormalsTexShadowParam);
1119       
1120        cgGLSetTextureParameter(sShadowMapParam, shadowTex);
1121        cgGLEnableTextureParameter(sShadowMapParam);
1122
1123        cgGLSetParameter1f(sMaxDepthShadowParam, mScaleFactor);
1124
1125        cgGLSetParameter1f(sSampleWidthParam, 2.0f / shadowMap->GetSize());
1126       
1127         
1128        cgGLSetMatrixParameterfc(sShadowMatrixParam, (const float *)shadowMatrix.x);
1129
1130        cgGLSetTextureParameter(sNoiseTexShadowParam, noiseTex);
1131        cgGLEnableTextureParameter(sNoiseTexShadowParam);
1132
1133        Vector3 lightDir = -light->GetDirection();
1134        cgGLSetParameter3f(sLightDirShadowParam, lightDir.x, lightDir.y, lightDir.z);
1135
1136
1137        glColor3f(1.0f, 1.0f, 1.0f);
1138       
1139        glBegin(GL_QUADS);
1140
1141        float offs2 = 0.5f;
1142
1143        glTexCoord2f(0, 0); glVertex3f(-offs2, -offs2, -0.5f);
1144        glTexCoord2f(1, 0); glVertex3f( offs2, -offs2, -0.5f);
1145        glTexCoord2f(1, 1); glVertex3f( offs2,  offs2, -0.5f);
1146        glTexCoord2f(0, 1); glVertex3f(-offs2,  offs2, -0.5f);
1147
1148        glEnd();
1149
1150        cgGLDisableTextureParameter(sColorsTexShadowParam);
1151        cgGLDisableTextureParameter(sPositionsTexShadowParam);
1152        cgGLDisableTextureParameter(sNormalsTexShadowParam);
1153        cgGLDisableTextureParameter(sShadowMapParam);
1154        cgGLDisableTextureParameter(sNoiseTexShadowParam);
1155
1156        FrameBufferObject::Release();
1157
1158        PrintGLerror("deferred shading + shadows");
1159}
1160
1161
1162void DeferredRenderer::SetSamplingMethod(SAMPLING_METHOD s)
1163{
1164        if (s != mSamplingMethod)
1165        {
1166                mSamplingMethod = s;
1167                mRegenerateSamples = true;
1168        }
1169}
1170
1171
1172void DeferredRenderer::SetShadingMethod(SHADING_METHOD s)
1173{
1174        if (s != mShadingMethod)
1175        {
1176                mShadingMethod = s;
1177                mRegenerateSamples = true;
1178        }
1179}
1180
1181
1182void DeferredRenderer::ComputeToneParameters(FrameBufferObject *fbo,
1183                                                                                         DirectionalLight *light,
1184                                                                                         float &imageKey,
1185                                                                                         float &whiteLum,
1186                                                                                         float &middleGrey)
1187{
1188        // hack: estimate value where sky burns out
1189        whiteLum = log(1e4f);
1190       
1191        ////////////////////
1192        //-- linear interpolate brightness key depending on the current sun position
1193
1194        const float minKey = 0.09f;
1195        const float maxKey = 0.5f;
1196
1197        const float lightIntensity = DotProd(-light->GetDirection(), Vector3::UNIT_Z());
1198        middleGrey = lightIntensity * maxKey + (1.0f - lightIntensity) * minKey;
1199
1200
1201#if 1
1202
1203        //////////
1204        //-- compute avg loglum
1205
1206        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
1207        GLuint colorsTex = colorBuffer->GetTexture();
1208
1209        fbo->Bind();
1210
1211        colorBufferIdx = 3 - colorBufferIdx;
1212        glDrawBuffers(1, mrt + colorBufferIdx);
1213       
1214
1215        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1216
1217        cgGLEnableProfile(RenderState::sCgFragmentProfile);
1218        cgGLBindProgram(sCgLogLumProgram);
1219       
1220        cgGLSetTextureParameter(sColorsTexLogLumParam, colorsTex);
1221        cgGLEnableTextureParameter(sColorsTexLogLumParam);
1222       
1223        const float offs = 0.5f;
1224
1225        glBegin(GL_QUADS);
1226
1227        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
1228        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
1229        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
1230        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
1231
1232        glEnd();
1233
1234        cgGLDisableTextureParameter(sColorsTexLogLumParam);
1235        FrameBufferObject::Release();
1236
1237        PrintGLerror("ToneMapParams");
1238
1239#endif
1240
1241        ///////////////////
1242        //-- compute avg loglum in scene using mipmapping
1243
1244        glBindTexture(GL_TEXTURE_2D, fbo->GetColorBuffer(colorBufferIdx)->GetTexture());
1245        glGenerateMipmapEXT(GL_TEXTURE_2D);
1246}
1247
1248
1249void DeferredRenderer::DownSample(FrameBufferObject *fbo)
1250{
1251        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
1252        GLuint colorsTex = colorBuffer->GetTexture();
1253       
1254        cgGLEnableProfile(RenderState::sCgFragmentProfile);
1255        cgGLBindProgram(sCgDownSampleProgram);
1256       
1257        cgGLSetTextureParameter(sColorsTexDownSampleParam, colorsTex);
1258        cgGLEnableTextureParameter(sColorsTexDownSampleParam);
1259
1260        mDownSampleFbo->Bind();
1261
1262        glDrawBuffers(1, mrt);
1263       
1264        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1265
1266        cgGLEnableProfile(RenderState::sCgFragmentProfile);
1267        cgGLBindProgram(sCgDownSampleProgram);
1268
1269        const float offs = 0.5f;
1270
1271        glBegin(GL_QUADS);
1272
1273        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
1274        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
1275        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
1276        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
1277
1278        glEnd();
1279
1280        cgGLDisableTextureParameter(sColorsTexDownSampleParam);
1281
1282        FrameBufferObject::Release();
1283
1284        PrintGLerror("ToneMapParams");
1285}
1286
1287
1288void DeferredRenderer::ToneMap(FrameBufferObject *fbo,
1289                                                           DirectionalLight *light,
1290                                                           float imageKey,
1291                                                           float whiteLum,
1292                                                           float middleGrey)
1293{
1294        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
1295        GLuint colorsTex = colorBuffer->GetTexture();
1296
1297        fbo->Bind();
1298
1299        colorBufferIdx = 3 - colorBufferIdx;
1300        glDrawBuffers(1, mrt + colorBufferIdx);
1301       
1302        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1303
1304        cgGLEnableProfile(RenderState::sCgFragmentProfile);
1305        cgGLBindProgram(sCgToneProgram);
1306       
1307        cgGLSetTextureParameter(sColorsTexToneParam, colorsTex);
1308        cgGLEnableTextureParameter(sColorsTexToneParam);
1309
1310        cgGLSetParameter1f(sImageKeyParam, imageKey);
1311        cgGLSetParameter1f(sWhiteLumParam, whiteLum);
1312        cgGLSetParameter1f(sMiddleGreyParam, middleGrey);
1313
1314        glColor3f(1.0f, 1.0f, 1.0f);
1315
1316        glBegin(GL_QUADS);
1317
1318        // the neighbouring texels
1319        const float x_offs = 1.0f / mWidth;
1320        const float y_offs = 1.0f / mHeight;
1321
1322        SetVertex(0, 0, x_offs, y_offs);
1323        SetVertex(1, 0, x_offs, y_offs);
1324        SetVertex(1, 1, x_offs, y_offs);
1325        SetVertex(0, 1, x_offs, y_offs);
1326
1327        glEnd();
1328
1329        cgGLDisableTextureParameter(sColorsTexToneParam);
1330        FrameBufferObject::Release();
1331
1332        PrintGLerror("ToneMap");
1333}
1334
1335
1336
1337
1338} // namespace
Note: See TracBrowser for help on using the repository browser.