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

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