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

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