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

Revision 3021, 42.0 KB checked in by mattausch, 16 years ago (diff)

removed leaks. added class for shaders

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