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

Revision 3005, 41.2 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;
[2859]74static CGparameter sSamplesParam;
75static CGparameter sOldTexParam;
76static CGparameter sNoiseTexParam;
[2897]77static CGparameter sTemporalCoherenceParam;
[2859]78
[2873]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;
[2897]94static CGparameter sTemporalCoherenceGiParam;
[2873]95
96
[2880]97static CGparameter sColorsTexCombinedIllumParam;
98static CGparameter sSsaoTexCombinedIllumParam;
99static CGparameter sIllumTexCombinedIllumParam;
100
101static CGparameter sColorsTexCombinedSsaoParam;
102static CGparameter sSsaoTexCombinedSsaoParam;
103
[2987]104static CGparameter sTLParam;
105static CGparameter sTRParam;
106static CGparameter sBRParam;
107static CGparameter sBLParam;
[2880]108
[2990]109
110static CGparameter sTLGiParam;
111static CGparameter sTRGiParam;
112static CGparameter sBRGiParam;
113static CGparameter sBLGiParam;
114
115static CGparameter sEyePosGiParam;
116
117
118
[2873]119////////////
120
[2865]121static CGparameter sColorsTexAntiAliasingParam;
122static CGparameter sNormalsTexAntiAliasingParam;
123
[2895]124
125static CGparameter sShadowMapParam;
126static CGparameter sPositionsTexShadowParam; 
127static CGparameter sColorsTexShadowParam; 
128static CGparameter sNormalsTexShadowParam;
129
130static CGparameter sShadowMatrixParam;
131static CGparameter sMaxDepthShadowParam;
132static CGparameter sSampleWidthParam;
133
[2944]134static CGparameter sNoiseTexShadowParam;
135static CGparameter sSamplesShadowParam;
136
[2952]137static CGparameter sLightDirParam;
138static CGparameter sLightDirShadowParam;
[2966]139static CGparameter sImageKeyParam;
[2970]140static CGparameter sMiddleGreyParam;
[2968]141static CGparameter sWhiteLumParam;
[2952]142
[2972]143
144static CGparameter sColorsTexInitialParam;
145static CGparameter sColorsTexToneParam;
146
[2994]147static CGparameter sColorsTexDownSampleParam;
148
[2903]149//#define USE_3D_SSAO
[2895]150
151
[2879]152static GLuint noiseTex = 0;
[2865]153
[2859]154// ssao random spherical samples
[2903]155#ifdef USE_3D_SSAO
[2900]156static Sample2 samples3[NUM_SAMPLES];
[2903]157#else
158static Sample2 samples2[NUM_SAMPLES];
159#endif
160
[2966]161// number of pcf tabs
162Sample2 pcfSamples[NUM_PCF_TABS];
163
[2976]164int DeferredRenderer::colorBufferIdx = 0;
[2859]165
[2992]166
[2859]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
[2976]180
[2859]181/** Generate poisson disc distributed sample points on the unit disc
182*/
[2887]183static void GenerateSamples(int sampling)
[2859]184{
[2903]185#ifdef USE_3D_SSAO
186
187        SphericalSampleGenerator sph(NUM_SAMPLES, 1.0f);
188        sph.Generate((float *)samples3);
189
190#else
[2887]191        switch (sampling)
192        {
[2930]193        case DeferredRenderer::SAMPLING_POISSON:
[2887]194                {
[2930]195                        PoissonDiscSampleGenerator2 poisson(NUM_SAMPLES, 1.0f);
[2900]196                        poisson.Generate((float *)samples2);
[2887]197                }
198                break;
[2930]199        case DeferredRenderer::SAMPLING_QUADRATIC:
[2887]200                {
[2930]201                        QuadraticDiscSampleGenerator2 g(NUM_SAMPLES, 1.0f);
202                        g.Generate((float *)samples2);
[2887]203                }
204                break;
[2930]205        default: // SAMPLING_DEFAULT
206
207                RandomSampleGenerator2 g(NUM_SAMPLES, 1.0f);
208                g.Generate((float *)samples2);
[2903]209        }
210#endif
[2859]211}
212
213
[2879]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
[2900]219        static HaltonSequence halton;
220        float r[2];
221
[2879]222        for (int i = 0; i < w * h * 3; i += 3)
223        {
[2901]224               
[2903]225#ifdef USE_3D_SSAO
226                //halton.GetNext(2, r);
227                r[0] = RandomValue(0, 1);
228                r[1] = RandomValue(0, 1);
[2879]229
[2900]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);
[2903]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
[2879]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
[2896]271DeferredRenderer::DeferredRenderer(int w, int h, Camera *cam, float scaleFactor):
[2860]272mWidth(w), mHeight(h),
273mCamera(cam),
[2875]274mScaleFactor(scaleFactor),
275mUseTemporalCoherence(true),
[2895]276mRegenerateSamples(true),
[2930]277mSamplingMethod(SAMPLING_POISSON),
[2895]278mShadingMethod(DEFAULT),
[2891]279mFboIndex(0)
[2861]280{
[2879]281        // create noise texture for ssao
282        CreateNoiseTex2D(w, h);
283
[2965]284
[2861]285        ///////////
286        //-- the flip-flop fbos
[2859]287
[2891]288        mFbo = new FrameBufferObject(w, h, FrameBufferObject::DEPTH_NONE);
289
[3001]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);
[3002]294
295        mDownSampleFbo = new FrameBufferObject(w / 2, h / 2, FrameBufferObject::DEPTH_NONE);
[3003]296        //mDownSampleFbo = new FrameBufferObject(w, h, FrameBufferObject::DEPTH_NONE);
[3002]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);
[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");
[2873]408                sMaxDepthGiParam = cgGetNamedParameter(sCgGiProgram, "maxDepth");
[2897]409                sTemporalCoherenceGiParam = cgGetNamedParameter(sCgGiProgram, "temporalCoherence");
[2873]410
[2944]411                sNoiseTexGiParam = cgGetNamedParameter(sCgGiProgram, "noiseTexture");
[2873]412                sSamplesGiParam = cgGetNamedParameter(sCgGiProgram, "samples");
413               
414                sOldSsaoTexGiParam = cgGetNamedParameter(sCgGiProgram, "oldSsaoTex"); 
[2990]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");
[2873]423        }
424        else
425                cerr << "globillum program failed to load" << endl;
426
[2880]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       
[2865]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
[2895]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");
[2928]505
[2944]506                sNoiseTexShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "noiseTexture");
507                sSamplesShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "samples");
[2952]508                sLightDirShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "lightDir");
[2966]509
510                PoissonDiscSampleGenerator2 poisson(NUM_PCF_TABS, 1.0f);
[2944]511                poisson.Generate((float *)pcfSamples);
[2928]512
[2966]513                cgGLSetParameterArray2f(sSamplesShadowParam, 0, NUM_PCF_TABS, (const float *)pcfSamples);
[2928]514        }
515        else
[2944]516                cerr << "deferred program failed to load" << endl;
[2928]517
[2992]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
[2973]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
[3005]556
[2994]557        sCgDownSampleProgram =
[2973]558                cgCreateProgramFromFile(context,
559                                                                CG_SOURCE,
560                                                                "src/shaders/tonemap.cg",
561                                                                RenderState::sCgFragmentProfile,
[3002]562                                                                "DownSample",
[2973]563                                                                NULL);
564
[2994]565        if (sCgDownSampleProgram != NULL)
[2973]566        {
[2994]567                cgGLLoadProgram(sCgDownSampleProgram);
[2973]568
569                // we need size of texture for scaling
[3002]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);
[2973]587        }
588        else
[3005]589                cerr << "downsample program failed to load" << endl;
[2973]590
[2859]591        PrintGLerror("init");
592}
593
594
[2896]595void DeferredRenderer::Render(FrameBufferObject *fbo,
[2897]596                                                          const Matrix4x4 &oldProjViewMatrix,
[2900]597                                                          const Matrix4x4 &projViewMatrix,
[2901]598                                                          float tempCohFactor,
[2952]599                                                          DirectionalLight *light,
[2991]600                                                          bool useToneMapping,
601                                                          ShadowMap *shadowMap
602                                                          )
[2859]603{
[2868]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
[2897]608
609        mFboIndex = 2 - mFboIndex;
[2976]610       
[2868]611        FrameBufferObject::Release();
[2867]612        cgGLEnableProfile(RenderState::sCgFragmentProfile);
613
614        glDisable(GL_ALPHA_TEST);
615        glDisable(GL_TEXTURE_2D);
616        glDisable(GL_LIGHTING);
617
[2880]618        glPushAttrib(GL_VIEWPORT_BIT);
619        glViewport(0, 0, mWidth, mHeight);
620
[2867]621        glMatrixMode(GL_PROJECTION);
622        glPushMatrix();
623        glLoadIdentity();
624
[2897]625        const float offs = 0.5f;
626        glOrtho(-offs, offs, -offs, offs, 0, 1);
627
[2867]628        glMatrixMode(GL_MODELVIEW);
629        glPushMatrix();
630        glLoadIdentity();
631
[2944]632        if (shadowMap)
[2952]633                FirstPassShadow(fbo, light, shadowMap);
[2895]634        else
[2952]635                FirstPass(fbo, light);
[2944]636
637        switch (mShadingMethod)
[2880]638        {
[2944]639        case SSAO:
640                ComputeSsao(fbo, tempCohFactor, oldProjViewMatrix, projViewMatrix);
641                CombineSsao(fbo);
642                break;
643        case GI:
[3002]644                DownSample(fbo);
[2944]645                ComputeGlobIllum(fbo, tempCohFactor, oldProjViewMatrix);
646                CombineIllum(fbo);
647                break;
648        default: // DEFAULT
649                // do nothing: standard deferred shading
650                break;
651        }
[2884]652
[2991]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
[2970]661        AntiAliasing(fbo, light);
[2867]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);
[2859]675}
676
677
[2896]678void DeferredRenderer::ComputeSsao(FrameBufferObject *fbo,
[2901]679                                                                   float tempCohFactor,
[2900]680                                                                   const Matrix4x4 &oldProjViewMatrix,
681                                                                   const Matrix4x4 &projViewMatrix
682                                                                   )
[2859]683{
[3005]684#ifdef USE_3D_SSAO
[2975]685        // bias from [-1, 1] to [0, 1]
[2900]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,
[2975]689                                                                0.0f, 0.0f, 0.0f, 1.0f);
[2900]690
691        Matrix4x4 m = projViewMatrix * biasMatrix;
692        cgGLSetMatrixParameterfc(sModelViewProjMatrixParam, (const float *)m.x);
[3005]693#else
694        cgGLSetMatrixParameterfc(sModelViewProjMatrixParam, (const float *)projViewMatrix.x);
695#endif
[2874]696
[3005]697
[2903]698        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixParam, (const float *)oldProjViewMatrix.x);
699
[2975]700        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[2861]701        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
702        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
[2859]703
[2992]704        // generate mip map levels of position in order to improve texture lookup performance
705        //glBindTexture(GL_TEXTURE_2D, positionsTex); glGenerateMipmapEXT(GL_TEXTURE_2D);
[2993]706        //glBindTexture(GL_TEXTURE_2D, colorsTex); glGenerateMipmapEXT(GL_TEXTURE_2D);
707
[2861]708        // read the second buffer, write to the first buffer
[2891]709        mFbo->Bind();
[2899]710        glDrawBuffers(1, mrt + mFboIndex);
[2868]711
[2891]712        GLuint oldTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
[2860]713
[2859]714        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
715
[2868]716        cgGLEnableProfile(RenderState::sCgFragmentProfile);
[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
[2880]784
[2861]785        FrameBufferObject::Release();
[2859]786
787        PrintGLerror("ssao first pass");
788}
789
790
[2896]791void DeferredRenderer::ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
[2860]792{
793        Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
[2859]794
[2860]795        mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
796
[2888]797        bl = Normalize(nbl - fbl);
798        br = Normalize(nbr - fbr);
799        tl = Normalize(ntl - ftl);
800        tr = Normalize(ntr - ftr);
[2860]801}
802
803
[2865]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
[2970]819void DeferredRenderer::AntiAliasing(FrameBufferObject *fbo, DirectionalLight *light)
[2865]820{
[2968]821        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
[2967]822
[2968]823        GLuint colorsTex = colorBuffer->GetTexture();
[2865]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);
[2868]830       
[2865]831        cgGLSetTextureParameter(sColorsTexAntiAliasingParam, colorsTex);
832        cgGLEnableTextureParameter(sColorsTexAntiAliasingParam);
833
834        cgGLSetTextureParameter(sNormalsTexAntiAliasingParam, normalsTex);
835        cgGLEnableTextureParameter(sNormalsTexAntiAliasingParam);
[2868]836
[2967]837
[2865]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
[2867]856        PrintGLerror("antialiasing");
[2865]857}
858
859
[2952]860void DeferredRenderer::FirstPass(FrameBufferObject *fbo, DirectionalLight *light)
[2868]861{
[2973]862        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[2868]863        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
864        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
865
[2879]866        fbo->Bind();
[2868]867
[2973]868        colorBufferIdx = 3 - colorBufferIdx;
[2899]869        glDrawBuffers(1, mrt + colorBufferIdx);
[2879]870
[2868]871        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
872        cgGLEnableProfile(RenderState::sCgFragmentProfile);
873
[2873]874        cgGLBindProgram(sCgDeferredProgram);
[2868]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       
[2952]885        Vector3 lightDir = -light->GetDirection();
886        cgGLSetParameter3f(sLightDirParam, lightDir.x, lightDir.y, lightDir.z);
887
[2966]888
[2868]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
[2869]913
[2928]914
[2896]915void DeferredRenderer::ComputeGlobIllum(FrameBufferObject *fbo,
[2901]916                                                                                float tempCohFactor,
917                                                                                const Matrix4x4 &oldProjViewMatrix)
[2869]918{
[2874]919        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixGiParam, (const float *)oldProjViewMatrix.x);
920
[3003]921//      GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
922        GLuint colorsTex = mDownSampleFbo->GetColorBuffer(0)->GetTexture();
[2873]923        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
924        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
[2869]925
[2974]926        // generate mip map levels for position texture
[2991]927        //glBindTexture(GL_TEXTURE_2D, positionsTex); glGenerateMipmapEXT(GL_TEXTURE_2D);
[2869]928
[2873]929        // read the second buffer, write to the first buffer
[2891]930        mFbo->Bind();
[2873]931
[2899]932        glDrawBuffers(2, mrt + mFboIndex);
[2873]933
[2891]934        GLuint oldSsaoTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
935        GLuint oldIllumTex = mFbo->GetColorBuffer(2 - mFboIndex + 1)->GetTexture();
936
[2869]937        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
938
939        cgGLEnableProfile(RenderState::sCgFragmentProfile);
[2873]940        cgGLBindProgram(sCgGiProgram);
[2869]941
[2873]942        cgGLSetTextureParameter(sPositionsTexGiParam, positionsTex);
943        cgGLEnableTextureParameter(sPositionsTexGiParam);
[2869]944
[2873]945        cgGLSetTextureParameter(sColorsTexGiParam, colorsTex);
946        cgGLEnableTextureParameter(sColorsTexGiParam);
[2869]947
[2873]948        cgGLSetTextureParameter(sNormalsTexGiParam, normalsTex);
949        cgGLEnableTextureParameter(sNormalsTexGiParam);
[2869]950
[2873]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
[2990]962
[2901]963        cgGLSetParameter1f(sTemporalCoherenceGiParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
[2873]964
[2897]965
[2895]966        if (mUseTemporalCoherence || mRegenerateSamples)
[2875]967        {
[2895]968                mRegenerateSamples = false;
[2873]969
[2875]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
[2895]973                GenerateSamples(mSamplingMethod);
[2903]974
975#ifdef USE_3D_SSAO
976                cgGLSetParameterArray3f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples3);
977#else
[2900]978                cgGLSetParameterArray2f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples2);
[2903]979#endif
[2875]980        }
981
[2895]982
[2873]983        Vector3 tl, tr, bl, br;
984        ComputeViewVectors(tl, tr, bl, br);
[2990]985       
986        const Vector3 pos = mCamera->GetPosition() / mScaleFactor;
987        cgGLSetParameter3f(sEyePosGiParam, pos.x, pos.y, pos.z);
[2873]988
[2990]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
[2869]995        glBegin(GL_QUADS);
996
[2873]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;
[2891]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);
[2869]1005
1006        glEnd();
1007
[2873]1008        cgGLDisableTextureParameter(sColorsTexGiParam);
1009        cgGLDisableTextureParameter(sPositionsTexGiParam);
1010        cgGLDisableTextureParameter(sNormalsTexGiParam);
1011        cgGLDisableTextureParameter(sNoiseTexGiParam);
1012        cgGLDisableTextureParameter(sOldSsaoTexGiParam);
1013        cgGLDisableTextureParameter(sOldIllumTexGiParam);
[2869]1014
1015        FrameBufferObject::Release();
1016
[2873]1017        PrintGLerror("globillum first pass");
[2869]1018}
1019
1020
[2896]1021void DeferredRenderer::CombineIllum(FrameBufferObject *fbo)
[2880]1022{
[2973]1023        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[2884]1024
[2891]1025        GLuint ssaoTex = mFbo->GetColorBuffer(mFboIndex)->GetTexture();
1026        GLuint illumTex = mFbo->GetColorBuffer(mFboIndex + 1)->GetTexture();
[2880]1027
[2891]1028
[2880]1029        fbo->Bind();
1030
[2884]1031        // overwrite old color texture
[2973]1032        colorBufferIdx = 3 - colorBufferIdx;
1033
[2899]1034        glDrawBuffers(1, mrt + colorBufferIdx);
[2880]1035
1036        cgGLEnableProfile(RenderState::sCgFragmentProfile);
1037
1038        cgGLBindProgram(sCgCombinedIllumProgram);
1039
[2881]1040        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1041       
1042
[2880]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
[2896]1077void DeferredRenderer::CombineSsao(FrameBufferObject *fbo)
[2880]1078{
[2973]1079        fbo->Bind();
1080
1081        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[2974]1082        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
[2891]1083        GLuint ssaoTex = mFbo->GetColorBuffer(mFboIndex)->GetTexture();
[2880]1084
[2895]1085        // overwrite old color texture
[2973]1086        colorBufferIdx = 3 - colorBufferIdx;
[2899]1087        glDrawBuffers(1, mrt + colorBufferIdx);
[2880]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);
[2974]1117       
[2880]1118        cgGLDisableProfile(RenderState::sCgFragmentProfile);
1119
1120        FrameBufferObject::Release();
1121
1122        PrintGLerror("combine ssao");
1123}
1124
1125
[2952]1126void DeferredRenderer::FirstPassShadow(FrameBufferObject *fbo,
1127                                                                           DirectionalLight *light,
1128                                                                           ShadowMap *shadowMap)
[2895]1129{
[2973]1130        fbo->Bind();
[2880]1131
[2973]1132        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
1133
[2895]1134        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
1135        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
[2928]1136        GLuint shadowTex = shadowMap->GetDepthTexture();
[2895]1137
1138        Matrix4x4 shadowMatrix;
1139        shadowMap->GetTextureMatrix(shadowMatrix);
1140
[2973]1141        colorBufferIdx = 3 - colorBufferIdx;
[2899]1142        glDrawBuffers(1, mrt + colorBufferIdx);
[2895]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);
[2973]1162
[2946]1163        cgGLSetParameter1f(sSampleWidthParam, 2.0f / shadowMap->GetSize());
[2973]1164       
[2895]1165         
1166        cgGLSetMatrixParameterfc(sShadowMatrixParam, (const float *)shadowMatrix.x);
1167
[2944]1168        cgGLSetTextureParameter(sNoiseTexShadowParam, noiseTex);
1169        cgGLEnableTextureParameter(sNoiseTexShadowParam);
1170
[2952]1171        Vector3 lightDir = -light->GetDirection();
1172        cgGLSetParameter3f(sLightDirShadowParam, lightDir.x, lightDir.y, lightDir.z);
[2944]1173
[2952]1174
[2895]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);
[2944]1192        cgGLDisableTextureParameter(sNoiseTexShadowParam);
1193
[2895]1194        FrameBufferObject::Release();
1195
1196        PrintGLerror("deferred shading + shadows");
1197}
1198
1199
[2896]1200void DeferredRenderer::SetSamplingMethod(SAMPLING_METHOD s)
[2895]1201{
1202        if (s != mSamplingMethod)
1203        {
1204                mSamplingMethod = s;
1205                mRegenerateSamples = true;
1206        }
1207}
1208
[2897]1209
1210void DeferredRenderer::SetShadingMethod(SHADING_METHOD s)
1211{
1212        if (s != mShadingMethod)
1213        {
1214                mShadingMethod = s;
1215                mRegenerateSamples = true;
1216        }
1217}
1218
[2965]1219
[2973]1220void DeferredRenderer::ComputeToneParameters(FrameBufferObject *fbo,
1221                                                                                         DirectionalLight *light,
1222                                                                                         float &imageKey,
1223                                                                                         float &whiteLum,
1224                                                                                         float &middleGrey)
[2972]1225{
[2975]1226        // hack: estimate value where sky burns out
1227        whiteLum = log(1e4f);
[2973]1228       
[2975]1229        ////////////////////
1230        //-- linear interpolate brightness key depending on the current sun position
[2973]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;
[2991]1237
[2993]1238
[2992]1239#if 1
[2991]1240
1241        //////////
1242        //-- compute avg loglum
1243
1244        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
[2992]1245        GLuint colorsTex = colorBuffer->GetTexture();
[2991]1246
1247        fbo->Bind();
1248
1249        colorBufferIdx = 3 - colorBufferIdx;
1250        glDrawBuffers(1, mrt + colorBufferIdx);
1251       
[2992]1252
[2991]1253        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1254
1255        cgGLEnableProfile(RenderState::sCgFragmentProfile);
[2992]1256        cgGLBindProgram(sCgLogLumProgram);
[2991]1257       
1258        cgGLSetTextureParameter(sColorsTexLogLumParam, colorsTex);
[2992]1259        cgGLEnableTextureParameter(sColorsTexLogLumParam);
[2991]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
[2992]1277#endif
[2991]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);
[2972]1284}
1285
1286
[3003]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
[2972]1316void DeferredRenderer::DownSample(FrameBufferObject *fbo)
1317{
[2994]1318        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
1319        GLuint colorsTex = colorBuffer->GetTexture();
[2972]1320       
1321        cgGLEnableProfile(RenderState::sCgFragmentProfile);
1322        cgGLBindProgram(sCgDownSampleProgram);
1323       
[2994]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
[3005]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
[2994]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
[3003]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
[3005]1375        //glPopAttrib();
1376        glViewport(0, 0, mWidth, mHeight);
1377        PrintGLerror("downsample");
1378
[3003]1379        delete [] data;
[2972]1380}
1381
1382
[2973]1383void DeferredRenderer::ToneMap(FrameBufferObject *fbo,
1384                                                           DirectionalLight *light,
1385                                                           float imageKey,
1386                                                           float whiteLum,
1387                                                           float middleGrey)
[2972]1388{
1389        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
[2994]1390        GLuint colorsTex = colorBuffer->GetTexture();
[2972]1391
[2973]1392        fbo->Bind();
[2972]1393
[2973]1394        colorBufferIdx = 3 - colorBufferIdx;
1395        glDrawBuffers(1, mrt + colorBufferIdx);
[2972]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
[2974]1414        const float x_offs = 1.0f / mWidth;
1415        const float y_offs = 1.0f / mHeight;
[2972]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);
[2973]1425        FrameBufferObject::Release();
[2972]1426
[2973]1427        PrintGLerror("ToneMap");
[2972]1428}
1429
1430
1431
1432
[2858]1433} // namespace
Note: See TracBrowser for help on using the repository browser.