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

Revision 3010, 40.8 KB checked in by mattausch, 16 years ago (diff)
RevLine 
[2896]1#include "DeferredRenderer.h"
[2859]2#include "FrameBufferObject.h"
3#include "RenderState.h"
4#include "SampleGenerator.h"
[2860]5#include "Vector3.h"
6#include "Camera.h"
[2884]7#include "shaderenv.h"
[2886]8#include "Halton.h"
[2895]9#include "ShadowMapping.h"
[2952]10#include "Light.h"
[2858]11
[3003]12#include <IL/il.h>
13#include <assert.h>
[2859]14
[3003]15
[2858]16using namespace std;
17
18
[3003]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
[2858]32namespace CHCDemoEngine
33{
34
[2859]35static CGprogram sCgSsaoProgram = NULL;
[2873]36static CGprogram sCgGiProgram = NULL;
37
38static CGprogram sCgDeferredProgram = NULL;
[2868]39static CGprogram sCgAntiAliasingProgram = NULL;
[2895]40static CGprogram sCgDeferredShadowProgram = NULL;
[2859]41
[2869]42static CGparameter sColorsTexCombineParam;
43static CGparameter sSsaoTexCombineParam;
44
[2868]45static CGparameter sColorsTexDeferredParam;
46static CGparameter sPositionsTexDeferredParam;
47static CGparameter sNormalsTexDeferredParam;
48
[2880]49static CGprogram sCgCombinedSsaoProgram = NULL;
50static CGprogram sCgCombinedIllumProgram = NULL;
51
[2992]52static CGparameter sColorsTexLogLumParam;
[2967]53
[3002]54static CGparameter sDownSampleOffsetParam;
[2992]55
56
[2972]57static CGprogram sCgDownSampleProgram;
58static CGprogram sCgToneProgram;
[2992]59static CGprogram sCgLogLumProgram;
[2972]60
61
[2992]62
[2944]63///////////////////////////////////////
[2873]64
65
[2859]66static CGparameter sColorsTexParam;
67static CGparameter sPositionsTexParam;
68static CGparameter sNormalsTexParam;
[2868]69
[2859]70static CGparameter sOldModelViewProjMatrixParam;
[2900]71static CGparameter sModelViewProjMatrixParam;
[2859]72static CGparameter sMaxDepthParam;
[2985]73static CGparameter sEyePosParam;
[3009]74static CGparameter sEyePosShadowParam;
[2859]75static CGparameter sSamplesParam;
76static CGparameter sOldTexParam;
77static CGparameter sNoiseTexParam;
[2897]78static CGparameter sTemporalCoherenceParam;
[2859]79
[2873]80
81///////////////////////////////////////
82
83
84static CGparameter sColorsTexGiParam;
85static CGparameter sPositionsTexGiParam;
86static CGparameter sNormalsTexGiParam;
87
88
89static CGparameter sOldModelViewProjMatrixGiParam;
[3006]90static CGparameter sModelViewProjMatrixGiParam;
[2873]91static CGparameter sMaxDepthGiParam;
92static CGparameter sSamplesGiParam;
93static CGparameter sOldSsaoTexGiParam;
94static CGparameter sOldIllumTexGiParam;
95static CGparameter sNoiseTexGiParam;
[2897]96static CGparameter sTemporalCoherenceGiParam;
[2873]97
98
[2880]99static CGparameter sColorsTexCombinedIllumParam;
100static CGparameter sSsaoTexCombinedIllumParam;
101static CGparameter sIllumTexCombinedIllumParam;
102
103static CGparameter sColorsTexCombinedSsaoParam;
104static CGparameter sSsaoTexCombinedSsaoParam;
105
[2987]106static CGparameter sTLParam;
107static CGparameter sTRParam;
108static CGparameter sBRParam;
109static CGparameter sBLParam;
[2880]110
[2990]111
112static CGparameter sTLGiParam;
113static CGparameter sTRGiParam;
114static CGparameter sBRGiParam;
115static CGparameter sBLGiParam;
116
117static CGparameter sEyePosGiParam;
118
119
120
[2873]121////////////
122
[2865]123static CGparameter sColorsTexAntiAliasingParam;
124static CGparameter sNormalsTexAntiAliasingParam;
125
[2895]126
127static CGparameter sShadowMapParam;
128static CGparameter sPositionsTexShadowParam; 
129static CGparameter sColorsTexShadowParam; 
130static CGparameter sNormalsTexShadowParam;
131
132static CGparameter sShadowMatrixParam;
133static CGparameter sMaxDepthShadowParam;
134static CGparameter sSampleWidthParam;
135
[2944]136static CGparameter sNoiseTexShadowParam;
137static CGparameter sSamplesShadowParam;
138
[2952]139static CGparameter sLightDirParam;
140static CGparameter sLightDirShadowParam;
[2966]141static CGparameter sImageKeyParam;
[2970]142static CGparameter sMiddleGreyParam;
[2968]143static CGparameter sWhiteLumParam;
[2952]144
[2972]145
146static CGparameter sColorsTexInitialParam;
147static CGparameter sColorsTexToneParam;
148
[2994]149static CGparameter sColorsTexDownSampleParam;
150
[2903]151//#define USE_3D_SSAO
[2895]152
153
[2879]154static GLuint noiseTex = 0;
[2865]155
[2859]156// ssao random spherical samples
[2903]157#ifdef USE_3D_SSAO
[2900]158static Sample2 samples3[NUM_SAMPLES];
[2903]159#else
160static Sample2 samples2[NUM_SAMPLES];
161#endif
162
[2966]163// number of pcf tabs
164Sample2 pcfSamples[NUM_PCF_TABS];
165
[2976]166int DeferredRenderer::colorBufferIdx = 0;
[2859]167
[2992]168
[2859]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
[2976]182
[2859]183/** Generate poisson disc distributed sample points on the unit disc
184*/
[2887]185static void GenerateSamples(int sampling)
[2859]186{
[2903]187#ifdef USE_3D_SSAO
188
189        SphericalSampleGenerator sph(NUM_SAMPLES, 1.0f);
190        sph.Generate((float *)samples3);
191
192#else
[2887]193        switch (sampling)
194        {
[2930]195        case DeferredRenderer::SAMPLING_POISSON:
[2887]196                {
[2930]197                        PoissonDiscSampleGenerator2 poisson(NUM_SAMPLES, 1.0f);
[2900]198                        poisson.Generate((float *)samples2);
[2887]199                }
200                break;
[2930]201        case DeferredRenderer::SAMPLING_QUADRATIC:
[2887]202                {
[2930]203                        QuadraticDiscSampleGenerator2 g(NUM_SAMPLES, 1.0f);
204                        g.Generate((float *)samples2);
[2887]205                }
206                break;
[2930]207        default: // SAMPLING_DEFAULT
208
209                RandomSampleGenerator2 g(NUM_SAMPLES, 1.0f);
210                g.Generate((float *)samples2);
[2903]211        }
212#endif
[2859]213}
214
215
[2879]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
[2900]221        static HaltonSequence halton;
222        float r[2];
223
[2879]224        for (int i = 0; i < w * h * 3; i += 3)
225        {
[2901]226               
[2903]227#ifdef USE_3D_SSAO
228                //halton.GetNext(2, r);
229                r[0] = RandomValue(0, 1);
230                r[1] = RandomValue(0, 1);
[2879]231
[2900]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);
[2903]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
[2879]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
[2896]273DeferredRenderer::DeferredRenderer(int w, int h, Camera *cam, float scaleFactor):
[2860]274mWidth(w), mHeight(h),
275mCamera(cam),
[2875]276mScaleFactor(scaleFactor),
277mUseTemporalCoherence(true),
[2895]278mRegenerateSamples(true),
[2930]279mSamplingMethod(SAMPLING_POISSON),
[2895]280mShadingMethod(DEFAULT),
[2891]281mFboIndex(0)
[2861]282{
[2879]283        // create noise texture for ssao
284        CreateNoiseTex2D(w, h);
285
[2965]286
[2861]287        ///////////
288        //-- the flip-flop fbos
[2859]289
[3006]290        mFbo = new FrameBufferObject(w / 2, h / 2, FrameBufferObject::DEPTH_NONE);
[2891]291
[3001]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);
[3002]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);
[3009]299        mDownSampleFbo->AddColorBuffer(ColorBufferObject::RGBA_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
[3002]300        mDownSampleFbo->AddColorBuffer(ColorBufferObject::RGBA_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
[2861]301}
302
303
[3002]304
[2896]305DeferredRenderer::~DeferredRenderer()
[2861]306{
[2879]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);
[2861]312
[2891]313        DEL_PTR(mFbo);
[2861]314
315        glDeleteTextures(1, &noiseTex);
316}
317
318
[2896]319void DeferredRenderer::SetUseTemporalCoherence(bool temporal)
[2875]320{
321        mUseTemporalCoherence = temporal;
322}
323
324
[2896]325void DeferredRenderer::Init(CGcontext context)
[2861]326{       
[2873]327        sCgDeferredProgram =
[2868]328                cgCreateProgramFromFile(context,
329                                                                CG_SOURCE,
330                                                                "src/shaders/deferred.cg",
331                                                                RenderState::sCgFragmentProfile,
[2873]332                                                                "main",
[2868]333                                                                NULL);
334
[2873]335        if (sCgDeferredProgram != NULL)
[2868]336        {
[2873]337                cgGLLoadProgram(sCgDeferredProgram);
[2868]338
339                // we need size of texture for scaling
[2873]340                sPositionsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "positions"); 
341                sColorsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "colors"); 
[2944]342                sNormalsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "normals");
[2968]343               
[2952]344                sLightDirParam = cgGetNamedParameter(sCgDeferredProgram, "lightDir");
[2868]345        }
346        else
347                cerr << "deferred program failed to load" << endl;
348
349
[2859]350        ///////////////
351
352        sCgSsaoProgram =
353                cgCreateProgramFromFile(context,
354                                                                CG_SOURCE,
[2903]355#ifdef USE_3D_SSAO
[2932]356                                                                "src/shaders/ssao3d.cg",
[2903]357#else
358                                                                "src/shaders/ssao.cg",
359#endif
[2859]360                                                                RenderState::sCgFragmentProfile,
[2868]361                                                                "main",
[2859]362                                                                NULL);
363
364        if (sCgSsaoProgram != NULL)
365        {
366                cgGLLoadProgram(sCgSsaoProgram);
367
368                sPositionsTexParam = cgGetNamedParameter(sCgSsaoProgram, "positions"); 
369                sColorsTexParam = cgGetNamedParameter(sCgSsaoProgram, "colors"); 
[2985]370                sEyePosParam = cgGetNamedParameter(sCgSsaoProgram, "eyePos");
[2859]371                sNormalsTexParam = cgGetNamedParameter(sCgSsaoProgram, "normals"); 
372                sNoiseTexParam = cgGetNamedParameter(sCgSsaoProgram, "noiseTexture");
[2868]373               
[2859]374                sOldModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "oldModelViewProj");
[2998]375                sModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "modelViewProj");
[2859]376                sMaxDepthParam = cgGetNamedParameter(sCgSsaoProgram, "maxDepth");
[2897]377                sTemporalCoherenceParam = cgGetNamedParameter(sCgSsaoProgram, "temporalCoherence");
[2859]378
379                sOldTexParam = cgGetNamedParameter(sCgSsaoProgram, "oldTex"); 
[2884]380                sSamplesParam = cgGetNamedParameter(sCgSsaoProgram, "samples");
[2987]381
[2988]382                sTLParam = cgGetNamedParameter(sCgSsaoProgram, "tl");
383                sTRParam = cgGetNamedParameter(sCgSsaoProgram, "tr");
384                sBRParam = cgGetNamedParameter(sCgSsaoProgram, "br");
385                sBLParam = cgGetNamedParameter(sCgSsaoProgram, "bl");
[2859]386        }
387        else
388                cerr << "ssao program failed to load" << endl;
389
[2873]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               
[2874]407                sOldModelViewProjMatrixGiParam = cgGetNamedParameter(sCgGiProgram, "oldModelViewProj");
[3006]408                sModelViewProjMatrixGiParam = cgGetNamedParameter(sCgGiProgram, "modelViewProj");
[2873]409                sMaxDepthGiParam = cgGetNamedParameter(sCgGiProgram, "maxDepth");
[2897]410                sTemporalCoherenceGiParam = cgGetNamedParameter(sCgGiProgram, "temporalCoherence");
[2873]411
[2944]412                sNoiseTexGiParam = cgGetNamedParameter(sCgGiProgram, "noiseTexture");
[2873]413                sSamplesGiParam = cgGetNamedParameter(sCgGiProgram, "samples");
414               
415                sOldSsaoTexGiParam = cgGetNamedParameter(sCgGiProgram, "oldSsaoTex"); 
[2990]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");
[2873]424        }
425        else
426                cerr << "globillum program failed to load" << endl;
427
[2880]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       
[2865]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
[2895]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");
[2928]506
[2944]507                sNoiseTexShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "noiseTexture");
508                sSamplesShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "samples");
[2952]509                sLightDirShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "lightDir");
[2966]510
[3009]511                sEyePosShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "eyePos");
512
[2966]513                PoissonDiscSampleGenerator2 poisson(NUM_PCF_TABS, 1.0f);
[2944]514                poisson.Generate((float *)pcfSamples);
[2928]515
[2966]516                cgGLSetParameterArray2f(sSamplesShadowParam, 0, NUM_PCF_TABS, (const float *)pcfSamples);
[2928]517        }
518        else
[2944]519                cerr << "deferred program failed to load" << endl;
[2928]520
[2992]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
[2973]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
[3005]559
[2994]560        sCgDownSampleProgram =
[2973]561                cgCreateProgramFromFile(context,
562                                                                CG_SOURCE,
563                                                                "src/shaders/tonemap.cg",
564                                                                RenderState::sCgFragmentProfile,
[3002]565                                                                "DownSample",
[2973]566                                                                NULL);
567
[2994]568        if (sCgDownSampleProgram != NULL)
[2973]569        {
[2994]570                cgGLLoadProgram(sCgDownSampleProgram);
[2973]571
572                // we need size of texture for scaling
[3002]573                sColorsTexDownSampleParam = cgGetNamedParameter(sCgDownSampleProgram, "colors");
574                sDownSampleOffsetParam = cgGetNamedParameter(sCgDownSampleProgram, "downSampleOffs");
[2973]575        }
576        else
[3005]577                cerr << "downsample program failed to load" << endl;
[2973]578
[2859]579        PrintGLerror("init");
580}
581
582
[2896]583void DeferredRenderer::Render(FrameBufferObject *fbo,
[2897]584                                                          const Matrix4x4 &oldProjViewMatrix,
[2900]585                                                          const Matrix4x4 &projViewMatrix,
[2901]586                                                          float tempCohFactor,
[2952]587                                                          DirectionalLight *light,
[2991]588                                                          bool useToneMapping,
589                                                          ShadowMap *shadowMap
590                                                          )
[2859]591{
[2868]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
[2897]596
597        mFboIndex = 2 - mFboIndex;
[2976]598       
[3006]599
[2867]600        cgGLEnableProfile(RenderState::sCgFragmentProfile);
601
602        glDisable(GL_ALPHA_TEST);
603        glDisable(GL_TEXTURE_2D);
604        glDisable(GL_LIGHTING);
[3007]605        glDisable(GL_BLEND);
[3008]606        glDisable(GL_DEPTH_TEST);
[2867]607
[2880]608        glPushAttrib(GL_VIEWPORT_BIT);
609        glViewport(0, 0, mWidth, mHeight);
610
[2867]611        glMatrixMode(GL_PROJECTION);
612        glPushMatrix();
613        glLoadIdentity();
614
[2897]615        const float offs = 0.5f;
616        glOrtho(-offs, offs, -offs, offs, 0, 1);
617
[2867]618        glMatrixMode(GL_MODELVIEW);
619        glPushMatrix();
620        glLoadIdentity();
621
[2944]622        if (shadowMap)
[2952]623                FirstPassShadow(fbo, light, shadowMap);
[2895]624        else
[2952]625                FirstPass(fbo, light);
[2944]626
627        switch (mShadingMethod)
[2880]628        {
[2944]629        case SSAO:
[3009]630                // downsample fbo buffers for colors, normals
[3006]631                DownSample(fbo, colorBufferIdx, mDownSampleFbo, 0);
632                DownSample(fbo, 1, mDownSampleFbo, 1);
633                DownSample(fbo, 2, mDownSampleFbo, 2);
634
[2944]635                ComputeSsao(fbo, tempCohFactor, oldProjViewMatrix, projViewMatrix);
636                CombineSsao(fbo);
637                break;
638        case GI:
[3009]639                // downsample fbo buffers for colors, normals
[3006]640                DownSample(fbo, colorBufferIdx, mDownSampleFbo, 0);
[3009]641                DownSample(fbo, 1, mDownSampleFbo, 1);
642
[3006]643                ComputeGlobIllum(fbo, tempCohFactor, projViewMatrix, oldProjViewMatrix);
[2944]644                CombineIllum(fbo);
645                break;
646        default: // DEFAULT
647                // do nothing: standard deferred shading
648                break;
649        }
[2884]650
[2991]651        if (useToneMapping)
652        {
653                float imageKey, whiteLum, middleGrey;
654
655                ComputeToneParameters(fbo, light, imageKey, whiteLum, middleGrey);
[3007]656                ToneMap(fbo, imageKey, whiteLum, middleGrey);
[2991]657        }
658
[2970]659        AntiAliasing(fbo, light);
[2867]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
[3007]672        FrameBufferObject::Release();
[2867]673        cgGLDisableProfile(RenderState::sCgFragmentProfile);
[2859]674}
675
676
[2896]677void DeferredRenderer::ComputeSsao(FrameBufferObject *fbo,
[2901]678                                                                   float tempCohFactor,
[2900]679                                                                   const Matrix4x4 &oldProjViewMatrix,
680                                                                   const Matrix4x4 &projViewMatrix
681                                                                   )
[2859]682{
[3005]683#ifdef USE_3D_SSAO
[2975]684        // bias from [-1, 1] to [0, 1]
[2900]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,
[2975]688                                                                0.0f, 0.0f, 0.0f, 1.0f);
[2900]689
690        Matrix4x4 m = projViewMatrix * biasMatrix;
691        cgGLSetMatrixParameterfc(sModelViewProjMatrixParam, (const float *)m.x);
[3005]692#else
693        cgGLSetMatrixParameterfc(sModelViewProjMatrixParam, (const float *)projViewMatrix.x);
694#endif
[2874]695
[3005]696
[2903]697        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixParam, (const float *)oldProjViewMatrix.x);
698
[3006]699        //GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[3009]700        //GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
701        //GLuint positionsTex = fbo->GetColorBuffer(2)->GetTexture();
[2859]702
[3006]703        GLuint colorsTex = mDownSampleFbo->GetColorBuffer(0)->GetTexture();
[3009]704        GLuint normalsTex = mDownSampleFbo->GetColorBuffer(1)->GetTexture();
705        GLuint positionsTex = mDownSampleFbo->GetColorBuffer(2)->GetTexture();
706       
[3007]707        GLuint oldTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
[2993]708
[3006]709        glPushAttrib(GL_VIEWPORT_BIT);
710        glViewport(0, 0, mFbo->GetWidth(), mFbo->GetHeight());
711
[2861]712        // read the second buffer, write to the first buffer
[2891]713        mFbo->Bind();
[2899]714        glDrawBuffers(1, mrt + mFboIndex);
[2868]715
[3007]716       
[2859]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);
[2985]735
[2988]736        Vector3 pos = mCamera->GetPosition() / mScaleFactor;
[2985]737        cgGLSetParameter3f(sEyePosParam, pos.x, pos.y, pos.z);
[2875]738       
[2901]739        cgGLSetParameter1f(sTemporalCoherenceParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
[2893]740
[2895]741        if (mUseTemporalCoherence || mRegenerateSamples)
[2875]742        {
[2895]743                mRegenerateSamples = false;
[2859]744
[2875]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
[2895]748                GenerateSamples(mSamplingMethod);
[2900]749
[2903]750#ifdef USE_3D_SSAO
[2900]751                cgGLSetParameterArray3f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples3);
[2903]752#else
753                cgGLSetParameterArray2f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples2);
754#endif
[2875]755        }
[2859]756
757        Vector3 tl, tr, bl, br;
758        ComputeViewVectors(tl, tr, bl, br);
759
[2987]760        cgGLSetParameter3f(sBLParam, bl.x, bl.y, bl.z);
761        cgGLSetParameter3f(sBRParam, br.x, br.y, br.z);
[2988]762        cgGLSetParameter3f(sTLParam, tl.x, tl.y, tl.z);
[2987]763        cgGLSetParameter3f(sTRParam, tr.x, tr.y, tr.z);
764
765
[2859]766        glBegin(GL_QUADS);
767
[2975]768        // note: slightly larger texture could hide ambient occlusion error on border but costs resolution
769        const float offs = 0.5f;
[2891]770       
[2975]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);
[2859]775
776        glEnd();
777
[2860]778        cgGLDisableTextureParameter(sColorsTexParam);
779        cgGLDisableTextureParameter(sPositionsTexParam);
780        cgGLDisableTextureParameter(sNormalsTexParam);
781        cgGLDisableTextureParameter(sNoiseTexParam);
782        cgGLDisableTextureParameter(sOldTexParam);
[2859]783
[3006]784        glPopAttrib();
[2859]785
786        PrintGLerror("ssao first pass");
787}
788
789
[2896]790void DeferredRenderer::ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
[2860]791{
792        Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
[2859]793
[2860]794        mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
795
[2888]796        bl = Normalize(nbl - fbl);
797        br = Normalize(nbr - fbr);
798        tl = Normalize(ntl - ftl);
799        tr = Normalize(ntr - ftr);
[2860]800}
801
802
[2865]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
[2970]818void DeferredRenderer::AntiAliasing(FrameBufferObject *fbo, DirectionalLight *light)
[2865]819{
[3007]820        FrameBufferObject::Release();
821
[2968]822        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
[2967]823
[2968]824        GLuint colorsTex = colorBuffer->GetTexture();
[2865]825        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
[3007]826
[2865]827        cgGLBindProgram(sCgAntiAliasingProgram);
[2868]828       
[2865]829        cgGLSetTextureParameter(sColorsTexAntiAliasingParam, colorsTex);
830        cgGLEnableTextureParameter(sColorsTexAntiAliasingParam);
831
832        cgGLSetTextureParameter(sNormalsTexAntiAliasingParam, normalsTex);
833        cgGLEnableTextureParameter(sNormalsTexAntiAliasingParam);
[2868]834
[2967]835
[2865]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
[2867]854        PrintGLerror("antialiasing");
[2865]855}
856
857
[2952]858void DeferredRenderer::FirstPass(FrameBufferObject *fbo, DirectionalLight *light)
[2868]859{
[2973]860        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[3009]861        GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
862        GLuint positionsTex = fbo->GetColorBuffer(2)->GetTexture();
[2868]863
[2879]864        fbo->Bind();
[2868]865
[2973]866        colorBufferIdx = 3 - colorBufferIdx;
[2899]867        glDrawBuffers(1, mrt + colorBufferIdx);
[3006]868       
[2873]869        cgGLBindProgram(sCgDeferredProgram);
[2868]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       
[2952]880        Vector3 lightDir = -light->GetDirection();
881        cgGLSetParameter3f(sLightDirParam, lightDir.x, lightDir.y, lightDir.z);
882
[2966]883
[2868]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
[2869]904
[2928]905
[2896]906void DeferredRenderer::ComputeGlobIllum(FrameBufferObject *fbo,
[2901]907                                                                                float tempCohFactor,
[3006]908                                                                                const Matrix4x4 &projViewMatrix,
[2901]909                                                                                const Matrix4x4 &oldProjViewMatrix)
[2869]910{
[2874]911        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixGiParam, (const float *)oldProjViewMatrix.x);
[3006]912        cgGLSetMatrixParameterfc(sModelViewProjMatrixGiParam, (const float *)projViewMatrix.x);
[2874]913
[3006]914        //GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[3003]915        GLuint colorsTex = mDownSampleFbo->GetColorBuffer(0)->GetTexture();
[3009]916        GLuint normalsTex = mDownSampleFbo->GetColorBuffer(1)->GetTexture();
917        GLuint positionsTex = fbo->GetColorBuffer(2)->GetTexture();
[2869]918
[3006]919        glPushAttrib(GL_VIEWPORT_BIT);
920        glViewport(0, 0, mFbo->GetWidth(), mFbo->GetHeight());
[2869]921
[2873]922        // read the second buffer, write to the first buffer
[2891]923        mFbo->Bind();
[2873]924
[2899]925        glDrawBuffers(2, mrt + mFboIndex);
[2873]926
[2891]927        GLuint oldSsaoTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
928        GLuint oldIllumTex = mFbo->GetColorBuffer(2 - mFboIndex + 1)->GetTexture();
[3006]929       
[2873]930        cgGLBindProgram(sCgGiProgram);
[2869]931
[2873]932        cgGLSetTextureParameter(sPositionsTexGiParam, positionsTex);
933        cgGLEnableTextureParameter(sPositionsTexGiParam);
[2869]934
[2873]935        cgGLSetTextureParameter(sColorsTexGiParam, colorsTex);
936        cgGLEnableTextureParameter(sColorsTexGiParam);
[2869]937
[2873]938        cgGLSetTextureParameter(sNormalsTexGiParam, normalsTex);
939        cgGLEnableTextureParameter(sNormalsTexGiParam);
[2869]940
[2873]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
[2990]952
[2901]953        cgGLSetParameter1f(sTemporalCoherenceGiParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
[2873]954
[2897]955
[2895]956        if (mUseTemporalCoherence || mRegenerateSamples)
[2875]957        {
[2895]958                mRegenerateSamples = false;
[2873]959
[2875]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
[2895]963                GenerateSamples(mSamplingMethod);
[2903]964
965#ifdef USE_3D_SSAO
966                cgGLSetParameterArray3f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples3);
967#else
[2900]968                cgGLSetParameterArray2f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples2);
[2903]969#endif
[2875]970        }
971
[2895]972
[2873]973        Vector3 tl, tr, bl, br;
974        ComputeViewVectors(tl, tr, bl, br);
[2990]975       
976        const Vector3 pos = mCamera->GetPosition() / mScaleFactor;
977        cgGLSetParameter3f(sEyePosGiParam, pos.x, pos.y, pos.z);
[2873]978
[2990]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
[3009]985        // note: slightly larger texture could hide ambient occlusion error on border but costs resolution
986        const float offs = 0.5f;
987       
[2869]988        glBegin(GL_QUADS);
989
[3009]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);
[2869]994
995        glEnd();
996
[2873]997        cgGLDisableTextureParameter(sColorsTexGiParam);
998        cgGLDisableTextureParameter(sPositionsTexGiParam);
999        cgGLDisableTextureParameter(sNormalsTexGiParam);
1000        cgGLDisableTextureParameter(sNoiseTexGiParam);
1001        cgGLDisableTextureParameter(sOldSsaoTexGiParam);
1002        cgGLDisableTextureParameter(sOldIllumTexGiParam);
[2869]1003
[3006]1004        glPopAttrib();
1005
[2873]1006        PrintGLerror("globillum first pass");
[2869]1007}
1008
1009
[2896]1010void DeferredRenderer::CombineIllum(FrameBufferObject *fbo)
[2880]1011{
[2973]1012        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[2884]1013
[2891]1014        GLuint ssaoTex = mFbo->GetColorBuffer(mFboIndex)->GetTexture();
1015        GLuint illumTex = mFbo->GetColorBuffer(mFboIndex + 1)->GetTexture();
[2880]1016
[2891]1017
[2880]1018        fbo->Bind();
1019
[2884]1020        // overwrite old color texture
[2973]1021        colorBufferIdx = 3 - colorBufferIdx;
1022
[2899]1023        glDrawBuffers(1, mrt + colorBufferIdx);
[2880]1024
1025        cgGLBindProgram(sCgCombinedIllumProgram);
1026
[2881]1027
[2880]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
[2896]1058void DeferredRenderer::CombineSsao(FrameBufferObject *fbo)
[2880]1059{
[2973]1060        fbo->Bind();
1061
1062        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[3009]1063        GLuint positionsTex = fbo->GetColorBuffer(2)->GetTexture();
1064       
[2891]1065        GLuint ssaoTex = mFbo->GetColorBuffer(mFboIndex)->GetTexture();
[2880]1066
[2895]1067        // overwrite old color texture
[2973]1068        colorBufferIdx = 3 - colorBufferIdx;
[2899]1069        glDrawBuffers(1, mrt + colorBufferIdx);
[2880]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);
[2974]1095       
[2880]1096        PrintGLerror("combine ssao");
1097}
1098
1099
[2952]1100void DeferredRenderer::FirstPassShadow(FrameBufferObject *fbo,
1101                                                                           DirectionalLight *light,
1102                                                                           ShadowMap *shadowMap)
[2895]1103{
[2973]1104        fbo->Bind();
[2880]1105
[2973]1106        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[3009]1107        GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
1108        GLuint positionsTex = fbo->GetColorBuffer(2)->GetTexture();
[2973]1109
[2928]1110        GLuint shadowTex = shadowMap->GetDepthTexture();
[2895]1111
1112        Matrix4x4 shadowMatrix;
1113        shadowMap->GetTextureMatrix(shadowMatrix);
1114
[2973]1115        colorBufferIdx = 3 - colorBufferIdx;
[2899]1116        glDrawBuffers(1, mrt + colorBufferIdx);
[2895]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);
[2973]1134
[2946]1135        cgGLSetParameter1f(sSampleWidthParam, 2.0f / shadowMap->GetSize());
[2973]1136       
[2895]1137         
1138        cgGLSetMatrixParameterfc(sShadowMatrixParam, (const float *)shadowMatrix.x);
1139
[2944]1140        cgGLSetTextureParameter(sNoiseTexShadowParam, noiseTex);
1141        cgGLEnableTextureParameter(sNoiseTexShadowParam);
1142
[2952]1143        Vector3 lightDir = -light->GetDirection();
1144        cgGLSetParameter3f(sLightDirShadowParam, lightDir.x, lightDir.y, lightDir.z);
[2944]1145
[3009]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);
[2952]1151
[3009]1152        // note: slightly larger texture could hide ambient occlusion error on border but costs resolution
1153        const float offs = 0.5f;
[2895]1154       
1155        glBegin(GL_QUADS);
1156
[3009]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);
[2895]1161
1162        glEnd();
1163
1164        cgGLDisableTextureParameter(sColorsTexShadowParam);
1165        cgGLDisableTextureParameter(sPositionsTexShadowParam);
1166        cgGLDisableTextureParameter(sNormalsTexShadowParam);
1167        cgGLDisableTextureParameter(sShadowMapParam);
[2944]1168        cgGLDisableTextureParameter(sNoiseTexShadowParam);
1169
[2895]1170        PrintGLerror("deferred shading + shadows");
1171}
1172
1173
[2896]1174void DeferredRenderer::SetSamplingMethod(SAMPLING_METHOD s)
[2895]1175{
1176        if (s != mSamplingMethod)
1177        {
1178                mSamplingMethod = s;
1179                mRegenerateSamples = true;
1180        }
1181}
1182
[2897]1183
1184void DeferredRenderer::SetShadingMethod(SHADING_METHOD s)
1185{
1186        if (s != mShadingMethod)
1187        {
1188                mShadingMethod = s;
1189                mRegenerateSamples = true;
1190        }
1191}
1192
[2965]1193
[2973]1194void DeferredRenderer::ComputeToneParameters(FrameBufferObject *fbo,
1195                                                                                         DirectionalLight *light,
1196                                                                                         float &imageKey,
1197                                                                                         float &whiteLum,
1198                                                                                         float &middleGrey)
[2972]1199{
[2975]1200        // hack: estimate value where sky burns out
[3010]1201        whiteLum = log(WHITE_LUMINANCE);
[2973]1202       
[2975]1203        ////////////////////
1204        //-- linear interpolate brightness key depending on the current sun position
[2973]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;
[2991]1211
[2993]1212
[2992]1213#if 1
[2991]1214
1215        //////////
1216        //-- compute avg loglum
1217
1218        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
[2992]1219        GLuint colorsTex = colorBuffer->GetTexture();
[2991]1220
1221        fbo->Bind();
1222
1223        colorBufferIdx = 3 - colorBufferIdx;
1224        glDrawBuffers(1, mrt + colorBufferIdx);
1225       
[2992]1226        cgGLBindProgram(sCgLogLumProgram);
[2991]1227       
1228        cgGLSetTextureParameter(sColorsTexLogLumParam, colorsTex);
[2992]1229        cgGLEnableTextureParameter(sColorsTexLogLumParam);
[2991]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
[2992]1246#endif
[2991]1247
1248        ///////////////////
1249        //-- compute avg loglum in scene using mipmapping
1250
[3008]1251        glBindTexture(GL_TEXTURE_2D, fbo->GetColorBuffer(colorBufferIdx)->GetTexture());
1252        glGenerateMipmapEXT(GL_TEXTURE_2D);
[2972]1253}
1254
1255
[3003]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
[3010]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
[3006]1316void DeferredRenderer::DownSample(FrameBufferObject *fbo, int bufferIdx,
1317                                                                  FrameBufferObject *downSampleFbo,
1318                                                                  int downSampleBufferIdx)
[2972]1319{
[3010]1320        float downSampleOffsets[NUM_DOWNSAMPLES * 2];
1321        ComputeDownsSampleOffsets(downSampleOffsets, fbo->GetWidth(), fbo->GetHeight());
1322
[3006]1323        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(bufferIdx);
[2994]1324        GLuint colorsTex = colorBuffer->GetTexture();
[3006]1325
1326        glPushAttrib(GL_VIEWPORT_BIT);
1327        glViewport(0, 0, downSampleFbo->GetWidth(), downSampleFbo->GetHeight());
1328
[2972]1329        cgGLBindProgram(sCgDownSampleProgram);
1330       
[2994]1331        cgGLSetTextureParameter(sColorsTexDownSampleParam, colorsTex);
1332        cgGLEnableTextureParameter(sColorsTexDownSampleParam);
1333
[3010]1334        cgGLSetParameterArray2f(sDownSampleOffsetParam, 0, NUM_DOWNSAMPLES, (const float *)downSampleOffsets);
1335
[2994]1336        mDownSampleFbo->Bind();
[3006]1337        glDrawBuffers(1, mrt + downSampleBufferIdx);
[2994]1338
1339        cgGLBindProgram(sCgDownSampleProgram);
[3005]1340       
[2994]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
[3006]1354        /*float *data = (float *)mDownSampleFbo->GetColorBuffer(0)->ReadTexture();
[3003]1355        ExportData(data, mWidth / 2, mHeight / 2);
[3006]1356        delete [] data;*/
[3003]1357
[3006]1358        glPopAttrib();
1359       
[3005]1360        PrintGLerror("downsample");
[2972]1361}
1362
1363
[2973]1364void DeferredRenderer::ToneMap(FrameBufferObject *fbo,
1365                                                           float imageKey,
1366                                                           float whiteLum,
1367                                                           float middleGrey)
[2972]1368{
1369        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
[2994]1370        GLuint colorsTex = colorBuffer->GetTexture();
[2972]1371
[2973]1372        fbo->Bind();
[3008]1373#if 1
[2973]1374        colorBufferIdx = 3 - colorBufferIdx;
1375        glDrawBuffers(1, mrt + colorBufferIdx);
[3007]1376
[2972]1377        cgGLBindProgram(sCgToneProgram);
[3007]1378
[2972]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
[3007]1388
[2972]1389        glBegin(GL_QUADS);
1390
[3007]1391        const float offs = 0.5f;
[2972]1392
1393
[3007]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
[2972]1399        glEnd();
[3007]1400#endif
[2972]1401
1402        cgGLDisableTextureParameter(sColorsTexToneParam);
1403
[2973]1404        PrintGLerror("ToneMap");
[2972]1405}
1406
1407
1408
1409
[2858]1410} // namespace
Note: See TracBrowser for help on using the repository browser.