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

Revision 2977, 35.7 KB checked in by mattausch, 16 years ago (diff)

tonemapping working but suddenly slow!

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