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

Revision 3175, 32.7 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"
[3057]11#include "ShaderManager.h"
[2858]12
[3003]13#include <IL/il.h>
14#include <assert.h>
[2859]15
[3003]16
[3021]17#ifdef _CRT_SET
18        #define _CRTDBG_MAP_ALLOC
19        #include <stdlib.h>
20        #include <crtdbg.h>
21
22        // redefine new operator
23        #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
24        #define new DEBUG_NEW
25#endif
26
27
[2858]28using namespace std;
29
30
[3003]31static void startil()
32{
33        ilInit();
34        assert(ilGetError() == IL_NO_ERROR);
35}
36
37
38static void stopil()
39{
40        ilShutDown();
41        assert(ilGetError() == IL_NO_ERROR);
42}
43
[2858]44namespace CHCDemoEngine
45{
46
[3026]47static ShaderProgram *sCgSsaoProgram = NULL;
48static ShaderProgram *sCgGiProgram = NULL;
[2873]49
[3026]50static ShaderProgram *sCgDeferredProgram = NULL;
51static ShaderProgram *sCgAntiAliasingProgram = NULL;
52static ShaderProgram *sCgDeferredShadowProgram = NULL;
[2859]53
[3026]54static ShaderProgram *sCgCombineSsaoProgram = NULL;
55static ShaderProgram *sCgCombineIllumProgram = NULL;
56static ShaderProgram *sCgLogLumProgram = NULL;
57static ShaderProgram *sCgToneProgram = NULL;
58static ShaderProgram *sCgDownSampleProgram = NULL;
[3137]59static ShaderProgram *sCgScaleDepthProgram = NULL;
[3155]60static ShaderProgram *sCgPrepareSsaoProgram = NULL;
[2869]61
[2992]62
[3129]63static GLuint noiseTex2D = 0;
64static GLuint noiseTex1D = 0;
[2865]65
[3128]66
[2859]67// ssao random spherical samples
[2903]68static Sample2 samples2[NUM_SAMPLES];
[2966]69// number of pcf tabs
[3103]70static Sample2 pcfSamples[NUM_PCF_TABS];
[2966]71
[3026]72
[3167]73static float ssaoFilterOffsets[NUM_SSAO_FILTER_SAMPLES * 2];
74static float ssaoFilterWeights[NUM_SSAO_FILTER_SAMPLES];
[3103]75
76
[3118]77int DeferredRenderer::colorBufferIdx = 0;
[2859]78
[2992]79
[3085]80/** Helper method that computes the view vectors in the corners of the current view frustum.
81*/
82static void ComputeViewVectors(PerspectiveCamera *cam, Vector3 &bl, Vector3 &br, Vector3 &tl, Vector3 &tr)
83{
84        Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
85        cam->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
86
87        bl = Normalize(nbl - fbl);
88        br = Normalize(nbr - fbr);
89        tl = Normalize(ntl - ftl);
90        tr = Normalize(ntr - ftr);
91}
92
93
[3025]94static float GaussianDistribution(float x, float y, float rho)
95{
[3110]96        float g = 1.0f / sqrtf(2.0f * M_PI * rho * rho);
[3133]97    g *= expf( -(x * x + y * y) / (2.0f * rho * rho));
[3025]98
99    return g;
100}
101
102
[2859]103static void PrintGLerror(char *msg)
104{
105        GLenum errCode;
106        const GLubyte *errStr;
107       
108        if ((errCode = glGetError()) != GL_NO_ERROR)
109        {
110                errStr = gluErrorString(errCode);
111                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
112        }
113}
114
115
[3134]116static void ComputeSampleOffsets(float *sampleOffsets,
117                                                                 int imageW, int imageH,
118                                                                 float width,
119                                                                 int samples)
120{
121        const float xoffs = width / (float)imageW;
122        const float yoffs = width / (float)imageH;
[3017]123       
[3134]124        const int numSamples = (int)sqrt((float)samples);
125        const int startSamples = -numSamples / 2;
126        const int endSamples = numSamples + startSamples - 1;
127        //cout << startSamples << " " << endSamples << endl;
[2976]128
[3134]129        int idx = 0;
[3017]130
[3134]131        for (int x = startSamples; x <= endSamples; ++ x)
[3017]132        {
[3134]133                for (int y = startSamples; y <= endSamples; ++ y)
[3017]134                {
[3134]135                        sampleOffsets[idx + 0] = (float)x * xoffs;
136                        sampleOffsets[idx + 1] = (float)y * yoffs;
[3017]137                        idx += 2;
138                }
139        }
140}
141
[3026]142
[3132]143void DeferredRenderer::FlipFbos(FrameBufferObject *fbo)
144{
145        fbo->Bind();
146        colorBufferIdx = 3 - colorBufferIdx;
147        glDrawBuffers(1, mrt + colorBufferIdx);
148}
149
150
[3026]151void DeferredRenderer::DrawQuad(ShaderProgram *p)
152{
[3132]153        if (p) p->Bind();
[3026]154
[3089]155        // interpolate the view vector
[3085]156        Vector3 bl = mCornersView[0];
157        Vector3 br = mCornersView[1];
158        Vector3 tl = mCornersView[2];
159        Vector3 tr = mCornersView[3];
160
[3026]161        // note: slightly larger texture could hide ambient occlusion error on border but costs resolution
162        glBegin(GL_QUADS);
163
[3093]164        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex2f( .0f,  .0f);
165        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex2f(1.0f,  .0f);
166        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex2f(1.0f, 1.0f);
167        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex2f( .0f, 1.0f);
[3026]168
169        glEnd();
170}
171
172
[2859]173/** Generate poisson disc distributed sample points on the unit disc
174*/
[2887]175static void GenerateSamples(int sampling)
[2859]176{
[2887]177        switch (sampling)
178        {
[2930]179        case DeferredRenderer::SAMPLING_POISSON:
[2887]180                {
[2930]181                        PoissonDiscSampleGenerator2 poisson(NUM_SAMPLES, 1.0f);
[2900]182                        poisson.Generate((float *)samples2);
[2887]183                }
184                break;
[2930]185        case DeferredRenderer::SAMPLING_QUADRATIC:
[2887]186                {
[2930]187                        QuadraticDiscSampleGenerator2 g(NUM_SAMPLES, 1.0f);
188                        g.Generate((float *)samples2);
[2887]189                }
190                break;
[2930]191        default: // SAMPLING_DEFAULT
[3026]192                {
193                        RandomSampleGenerator2 g(NUM_SAMPLES, 1.0f);
194                        g.Generate((float *)samples2);
195                }
[2903]196        }
[2859]197}
198
199
[2879]200static void CreateNoiseTex2D(int w, int h)
201{
202        //GLubyte *randomNormals = new GLubyte[mWidth * mHeight * 3];
203        float *randomNormals = new float[w * h * 3];
204
[2900]205        static HaltonSequence halton;
206        float r[2];
207
[2879]208        for (int i = 0; i < w * h * 3; i += 3)
209        {
[2903]210                // create random samples on a circle
211                r[0] = RandomValue(0, 1);
212                //halton.GetNext(1, r);
213
214                const float theta = 2.0f * acos(sqrt(1.0f - r[0]));
215               
216                randomNormals[i + 0] = cos(theta);
217                randomNormals[i + 1] = sin(theta);
218                randomNormals[i + 2] = 0;
[2879]219        }
220
221        glEnable(GL_TEXTURE_2D);
[3129]222        glGenTextures(1, &noiseTex2D);
223        glBindTexture(GL_TEXTURE_2D, noiseTex2D);
[2879]224               
225        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
226        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
227        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
228        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
229
230        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGB, GL_FLOAT, randomNormals);
231
232        glBindTexture(GL_TEXTURE_2D, 0);
233        glDisable(GL_TEXTURE_2D);
234
235        delete [] randomNormals;
236
237        cout << "created noise texture" << endl;
238
239        PrintGLerror("noisetexture");
240}
241
242
[3129]243static void CreateNoiseTex1D(int w)
244{
245        float *randomValues = new float[w * 3];
246
247        static HaltonSequence halton;
248       
249        randomValues[0] = randomValues[1] = randomValues[2] = 0;
250
251        for (int i = 3; i < w * 3; i += 3)
252        {
253                // create random samples on a circle
254                randomValues[i + 0] = 20.0f * RandomValue(0, 1) / 512.0f;
255                randomValues[i + 1] = 20.0f * RandomValue(0, 1) / 384.0f;
256                randomValues[i + 2] = 0;
257        }
258
259        glEnable(GL_TEXTURE_2D);
260        glGenTextures(1, &noiseTex1D);
261        glBindTexture(GL_TEXTURE_2D, noiseTex1D);
262               
263        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
264        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
265        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
266        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
267
268        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, 1, 0, GL_RGB, GL_FLOAT, randomValues);
269
270        glBindTexture(GL_TEXTURE_2D, 0);
271        glDisable(GL_TEXTURE_2D);
272
273        delete [] randomValues;
274
275        cout << "created noise texture 1D" << endl;
276
277        PrintGLerror("noisetexture 1D");
278}
279
280
281
[3068]282DeferredRenderer::DeferredRenderer(int w, int h, PerspectiveCamera *cam):
[2860]283mWidth(w), mHeight(h),
284mCamera(cam),
[2875]285mUseTemporalCoherence(true),
[2895]286mRegenerateSamples(true),
[2930]287mSamplingMethod(SAMPLING_POISSON),
[2895]288mShadingMethod(DEFAULT),
[3135]289mIllumFboIndex(0)
[2861]290{
291        ///////////
292        //-- the flip-flop fbos
[2859]293
[3155]294        const int dsw = w / 2; const int dsh = h / 2;
295        //const int dsw = w; const int dsh = h;
[3103]296
297        mIllumFbo = new FrameBufferObject(dsw, dsh, FrameBufferObject::DEPTH_NONE);
[3094]298        //mIllumFbo = new FrameBufferObject(w, h, FrameBufferObject::DEPTH_NONE);
299
[3019]300        mFBOs.push_back(mIllumFbo);
[2891]301
[3019]302        for (int i = 0; i < 4; ++ i)
303        {
[3088]304                mIllumFbo->AddColorBuffer(ColorBufferObject::RGBA_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
[3117]305                FrameBufferObject::InitBuffer(mIllumFbo, i);
[3019]306        }
[3002]307
[3117]308
309        ///////////////
310        //-- the downsampled ssao + color bleeding textures: as gi is inherently low frequency, we can use these to improve performance
311
[3103]312        mDownSampleFbo = new FrameBufferObject(dsw, dsh, FrameBufferObject::DEPTH_NONE);
[3094]313        //mDownSampleFbo = new FrameBufferObject(w, h, FrameBufferObject::DEPTH_NONE);
[3002]314        mDownSampleFbo->AddColorBuffer(ColorBufferObject::RGBA_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
[3087]315        // downsample buffer for the normal texture
[3017]316        mDownSampleFbo->AddColorBuffer(ColorBufferObject::RGB_FLOAT_16, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
[3117]317        // downsample buffer for the offset texture
318        mDownSampleFbo->AddColorBuffer(ColorBufferObject::RGB_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
[3019]319
[3117]320        for (int i = 0; i < 3; ++ i)
321        {
322                FrameBufferObject::InitBuffer(mDownSampleFbo, i);
323        }
324
[3019]325        mFBOs.push_back(mDownSampleFbo);
[3038]326
[3084]327        // create noise texture for ssao
[3150]328        // for performance reasons we use a smaller texture and repeat it over the screen
329        CreateNoiseTex2D(mIllumFbo->GetWidth() / 4, mIllumFbo->GetWidth() / 4);
330        //CreateNoiseTex1D(mIllumFbo->GetWidth() / 4);
[3084]331
[3085]332        mProjViewMatrix = IdentityMatrix();
333        mOldProjViewMatrix = IdentityMatrix();
334
335        for (int i = 0; i < 4; ++ i)
336        {
337                mCornersView[i] = mOldCornersView[i] = Vector3::UNIT_X();
338        }
339
340        mEyePos = mOldEyePos = Vector3::ZERO();
341
[3038]342        InitCg();
[2861]343}
344
345
[2896]346DeferredRenderer::~DeferredRenderer()
[2861]347{
[3019]348        CLEAR_CONTAINER(mFBOs);
[3129]349        glDeleteTextures(1, &noiseTex2D);
350        glDeleteTextures(1, &noiseTex1D);
[2861]351}
352
353
[2896]354void DeferredRenderer::SetUseTemporalCoherence(bool temporal)
[2875]355{
356        mUseTemporalCoherence = temporal;
357}
358
359
[3021]360
[3038]361void DeferredRenderer::InitCg()
[3026]362{       
[3057]363        ShaderManager *sm = ShaderManager::GetSingleton();
[2873]364
[3057]365        sCgDeferredProgram = sm->CreateFragmentProgram("deferred", "main", "deferredFrag");
366        sCgDeferredShadowProgram = sm->CreateFragmentProgram("deferred", "main_shadow", "deferredFragShader");
367        sCgSsaoProgram = sm->CreateFragmentProgram("ssao", "main", "ssaoFrag");
368        sCgGiProgram = sm->CreateFragmentProgram("globillum", "main", "giFrag");
369        sCgCombineIllumProgram = sm->CreateFragmentProgram("globillum", "combine", "combineGi");
[3120]370        sCgCombineSsaoProgram = sm->CreateFragmentProgram("combineSsao", "combine", "combineSsao");
[3057]371        sCgAntiAliasingProgram = sm->CreateFragmentProgram("antialiasing", "main", "antiAliasing");
372        sCgToneProgram = sm->CreateFragmentProgram("tonemap", "ToneMap", "toneMap");
[3137]373        sCgDownSampleProgram = sm->CreateFragmentProgram("deferred", "Output", "Output");
374        sCgScaleDepthProgram = sm->CreateFragmentProgram("deferred", "ScaleDepth", "ScaleDepth");
[3057]375        sCgLogLumProgram = sm->CreateFragmentProgram("tonemap", "CalcAvgLogLum", "avgLogLum");
[3155]376        sCgPrepareSsaoProgram = sm->CreateFragmentProgram("deferred", "PrepareSsao", "PrepareSsao");
[3038]377
[3034]378
[3104]379        ///////////////////
380        //-- initialize program parameters
[3034]381
[3104]382        string ssaoParams[] =
383                {"colors", "normals", "oldTex", "noiseTex", "temporalCoherence",
[3111]384                 "samples", "bl", "br", "tl", "tr",
385                 "modelViewProj", "oldModelViewProj", "oldEyePos", "oldbl", "oldbr",
[3150]386                 "oldtl", "oldtr", "attribsTex"};
387        sCgSsaoProgram->AddParameters(ssaoParams, 0, 18);
[3085]388       
[3104]389        string giParams[] =
390                {"colors", "normals", "noiseTex", "oldSsaoTex", "oldIllumTex",
[3111]391                 "temporalCoherence", "samples", "bl", "br", "tl",
392                 "tr", "oldModelViewProj", "modelViewProj"};
[3104]393        sCgGiProgram->AddParameters(giParams, 0, 13);
[3034]394
[3104]395        string toneParams[] = {"colors", "imageKey", "whiteLum", "middleGrey"};
396        sCgToneProgram->AddParameters(toneParams, 0, 4);
[3034]397
398
[3104]399        ////////////////
400
401        string deferredShadowParams[] =
402                {"colors", "normals", "shadowMap", "noiseTex", "shadowMatrix",
403                 "sampleWidth", "lightDir", "eyePos", "samples", "weights"};
[3035]404       
[3104]405        sCgDeferredShadowProgram->AddParameters(deferredShadowParams, 0, 10);
406       
407        ////////////////
[3034]408
[3104]409        string combineIllumParams[] = {"colorsTex", "ssaoTex", "illumTex"};
410        sCgCombineIllumProgram->AddParameters(combineIllumParams, 0, 3);
[3035]411
[3104]412        ////////////////
[3035]413
[3155]414        string combineSsaoParams[] =
415                {"colorsTex", "normalsTex", "ssaoTex", "filterOffs",
[3163]416                 "filterWeights", "modelViewProj", "bl", "br", "tl", "tr"};
417        sCgCombineSsaoProgram->AddParameters(combineSsaoParams, 0, 10);
[3035]418
[3104]419        //////////////
[3036]420
[3104]421        string deferredParams[] = {"colors", "normals", "lightDir"};
422        sCgDeferredProgram->AddParameters(deferredParams, 0, 3);
423
424        ///////////////////
425
[3136]426        string aaParams[] = {"colors", "normals", "offsets"};
427        sCgAntiAliasingProgram->AddParameters(aaParams, 0, 3);
[3104]428
429        /////////////////////
430
[3137]431        string downSampleParams[] = {"colors"};
432        sCgDownSampleProgram->AddParameters(downSampleParams, 0, 1);
[3104]433
[3137]434        /////////////////////
435
436        string scaleDepthParams[] = {"colors"};
437        sCgScaleDepthProgram->AddParameters(scaleDepthParams, 0, 1);
438
[3104]439        ////////////
440
441        sCgLogLumProgram->AddParameter("colors", 0);
[3128]442
443        ////////////////
444
[3155]445       
446        string prepareSsaoParams[] =
[3167]447                {"colorsTex", "normalsTex", "diffVals", "oldTex",
448                 "oldEyePos", "modelViewProj", "oldModelViewProj",
449                 "oldbl", "oldbr", "oldtl", "oldtr"};
[3104]450
[3167]451        sCgPrepareSsaoProgram->AddParameters(prepareSsaoParams, 0, 11);
[3155]452
453
454        ////////////////
455
[3167]456        const float filterWidth = 1.0f;
[3155]457
[3167]458        PoissonDiscSampleGenerator2 poisson(NUM_SSAO_FILTER_SAMPLES, 1.0f);
[3103]459        poisson.Generate((float *)ssaoFilterOffsets);
[3036]460
[3105]461        const float xoffs = (float)filterWidth / mWidth;
462        const float yoffs = (float)filterWidth / mHeight;
[3103]463
[3167]464        for (int i = 0; i < NUM_SSAO_FILTER_SAMPLES; ++ i)
[3103]465        {
466                float x = ssaoFilterOffsets[2 * i + 0];
467                float y = ssaoFilterOffsets[2 * i + 1];
468
[3140]469                ssaoFilterWeights[i] = GaussianDistribution(x, y, 1.0f);
470                //ssaoFilterWeights[i] = 1.0f;
[3120]471
[3103]472                ssaoFilterOffsets[2 * i + 0] *= xoffs;
473                ssaoFilterOffsets[2 * i + 1] *= yoffs;
474        }
475
[3133]476
[3144]477        /////////
[3133]478        //-- pcf tabs for shadowing
479
[3026]480        float filterWeights[NUM_PCF_TABS];
[3103]481        PoissonDiscSampleGenerator2 poisson2(NUM_PCF_TABS, 1.0f);
482        poisson2.Generate((float *)pcfSamples);
[2990]483
[3026]484        for (int i = 0; i < NUM_PCF_TABS; ++ i)
[2880]485        {
[3026]486                filterWeights[i] = GaussianDistribution(pcfSamples[i].x, pcfSamples[i].y, 1.0f);
[2880]487        }
488
[3035]489        sCgDeferredShadowProgram->SetArray2f(8, (float *)pcfSamples, NUM_PCF_TABS);
490        sCgDeferredShadowProgram->SetArray1f(9, (float *)filterWeights, NUM_PCF_TABS);
[2880]491
[2859]492        PrintGLerror("init");
493}
494
495
[2896]496void DeferredRenderer::Render(FrameBufferObject *fbo,
[2901]497                                                          float tempCohFactor,
[2952]498                                                          DirectionalLight *light,
[2991]499                                                          bool useToneMapping,
[3175]500                                                          bool useAntiAliasing,
[2991]501                                                          ShadowMap *shadowMap
502                                                          )
[2859]503{
[3085]504        InitFrame();
505
[2944]506        if (shadowMap)
[2952]507                FirstPassShadow(fbo, light, shadowMap);
[2895]508        else
[2952]509                FirstPass(fbo, light);
[2944]510
[3103]511        if (mShadingMethod != 0)
[2880]512        {
[3133]513                // downsample fbo buffers
[3155]514                PrepareSsao(fbo);
[3103]515        }
[3006]516
[3133]517        // antialiasing of the color buffer
[3168]518        //AntiAliasing(fbo, light);
[3132]519
[3103]520        switch (mShadingMethod)
521        {
522        case SSAO:
[3085]523                ComputeSsao(fbo, tempCohFactor);
[2944]524                CombineSsao(fbo);
525                break;
526        case GI:
[3085]527                ComputeGlobIllum(fbo, tempCohFactor);
[2944]528                CombineIllum(fbo);
529                break;
530        default: // DEFAULT
531                // do nothing: standard deferred shading
532                break;
533        }
[2884]534
[2991]535        if (useToneMapping)
536        {
537                float imageKey, whiteLum, middleGrey;
538
539                ComputeToneParameters(fbo, light, imageKey, whiteLum, middleGrey);
[3007]540                ToneMap(fbo, imageKey, whiteLum, middleGrey);
[2991]541        }
542
[3175]543        // multisampling is difficult / costly with deferred shading
544        // at least do some edge blurring
[3135]545
[3175]546        if (useAntiAliasing)
547                AntiAliasing(fbo, light);
548        else
549                Output(fbo); // just output the latest buffer
[2867]550
551        glEnable(GL_LIGHTING);
552        glDisable(GL_TEXTURE_2D);
553
554        glMatrixMode(GL_PROJECTION);
555        glPopMatrix();
556
557        glMatrixMode(GL_MODELVIEW);
558        glPopMatrix();
559
[3089]560        // viewport
[2867]561        glPopAttrib();
562
[3007]563        FrameBufferObject::Release();
[3057]564        ShaderManager::GetSingleton()->DisableFragmentProfile();
[2859]565}
566
567
[3167]568
569static inline float SqrMag(const Sample2 &s)
570{
571        return (s.x * s.x + s.y * s.y);
572}
573
574
575static inline float SqrDist(const Sample2 &a, const Sample2 &b)
576{
577        float x = a.x - b.x;
578        float y = a.y - b.y;
579       
580        return x * x + y * y;
581}
582
583
584static inline bool lt(const Sample2 &a, const Sample2 &b)
585{
586        return SqrMag(a) < SqrMag(b);
587}
588
589
590void DeferredRenderer::SortSamples()
591{
592        //for (int i = 0; i < NUM_SAMPLES; ++ i)cout << SqrDist(samples2[i-1], samples2[i]) << "|";
593        float dist = 0;
594        for (int i = 1; i < NUM_SAMPLES; ++ i)
595                dist += SqrDist(samples2[i-1], samples2[i]);
596                //cout << samples2[i].x << " " << samples2[i].y
597
598        //cout << "\nbefore: " << dist << endl;
599
600        //sort(samples2, samples2 + sizeof(samples2) / sizeof(Sample2), lt2);
601
602
603        static Sample2 tempSamples[NUM_SAMPLES];
604        static bool checked[NUM_SAMPLES];
605
606        for (int i = 0; i < NUM_SAMPLES; ++ i)
607                checked[i] = false;
608
609        Sample2 currentSample;
610        currentSample.x = 0; currentSample.y = 0;
611        int ns = 0; // the next sample index
612
613        for (int i = 0; i < NUM_SAMPLES; ++ i)
614        {
615                float minLen = 1e20f;
616
617                for (int j = 0; j < NUM_SAMPLES; ++ j)
618                {
619                        if (checked[j]) continue;
620
621                        Sample2 s = samples2[j];
622                        const float len = SqrDist(s, currentSample);
623
624                        if (len < minLen)
625                        {
626                                minLen = len;
627                                ns = j;
628                        }
629                }
630
631                tempSamples[i] = samples2[ns];
632                currentSample = samples2[ns];
633                checked[ns] = true;
634        }
635
636        for (int i = 0; i < NUM_SAMPLES; ++ i)
637                samples2[i] = tempSamples[i];
638
639        dist = 0;
640        for (int i = 1; i < NUM_SAMPLES; ++ i)
641                dist += SqrDist(samples2[i-1], samples2[i]);
642                //cout << samples2[i].x << " " << samples2[i].y << " " << SqrDist(samples2[i-1], samples2[i]) << "|";
643
644        //cout << "after:  " << dist << endl;
645}
646
647
[2896]648void DeferredRenderer::ComputeSsao(FrameBufferObject *fbo,
[3087]649                                                                   float tempCohFactor)
[2859]650{
[3117]651        GLuint colorsTex, normalsTex, attribsTex;
[3015]652
[3133]653        if (0)
[3117]654        {
655                colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
656                normalsTex = fbo->GetColorBuffer(1)->GetTexture();
657                attribsTex = fbo->GetColorBuffer(2)->GetTexture();
658        }
659        else
660        {
661                colorsTex = mDownSampleFbo->GetColorBuffer(0)->GetTexture();
662                normalsTex = mDownSampleFbo->GetColorBuffer(1)->GetTexture();
663                attribsTex = mDownSampleFbo->GetColorBuffer(2)->GetTexture();
[3132]664                //attribsTex = fbo->GetColorBuffer(2)->GetTexture();
[3117]665        }
666
[3087]667        // flip flop between illumination buffers
[3019]668        GLuint oldTex = mIllumFbo->GetColorBuffer(2 - mIllumFboIndex)->GetTexture();
[2993]669
[3006]670        glPushAttrib(GL_VIEWPORT_BIT);
[3019]671        glViewport(0, 0, mIllumFbo->GetWidth(), mIllumFbo->GetHeight());
[3006]672
[2861]673        // read the second buffer, write to the first buffer
[3019]674        mIllumFbo->Bind();
675        glDrawBuffers(1, mrt + mIllumFboIndex);
[2868]676
[3095]677        int i = 0;
[3034]678
[3095]679        sCgSsaoProgram->SetTexture(i ++, colorsTex);
680        sCgSsaoProgram->SetTexture(i ++, normalsTex);
681        sCgSsaoProgram->SetTexture(i ++, oldTex);
[3129]682        sCgSsaoProgram->SetTexture(i ++, noiseTex2D);
[3095]683
684        sCgSsaoProgram->SetValue1f(i ++, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
[3035]685       
[3129]686        if (mUseTemporalCoherence || mRegenerateSamples)
[2875]687        {
[2895]688                mRegenerateSamples = false;
[2859]689
[2875]690                // q: should we generate new samples or only rotate the old ones?
691                // in the first case, the sample patterns look nicer, but the kernel
692                // needs longer to converge
[3129]693                GenerateSamples(mSamplingMethod);
[3167]694
695                SortSamples();
[3095]696                sCgSsaoProgram->SetArray2f(i, (float *)samples2, NUM_SAMPLES);
[2875]697        }
[3085]698       
[3095]699        ++ i;
[2859]700
[3095]701        for (int j = 0; j < 4; ++ j, ++ i)
702                sCgSsaoProgram->SetValue3f(i, mCornersView[j].x, mCornersView[j].y, mCornersView[j].z);
[2987]703
[3095]704        sCgSsaoProgram->SetMatrix(i ++, mProjViewMatrix);
705        sCgSsaoProgram->SetMatrix(i ++, mOldProjViewMatrix);
[3062]706
[3105]707        Vector3 de;
708        de.x = mOldEyePos.x - mEyePos.x;
709        de.y = mOldEyePos.y - mEyePos.y;
710        de.z = mOldEyePos.z - mEyePos.z;
[3035]711
[3095]712        sCgSsaoProgram->SetValue3f(i ++, de.x, de.y, de.z);
[3093]713
[3095]714        for (int j = 0; j < 4; ++ j, ++ i)
715                sCgSsaoProgram->SetValue3f(i, mOldCornersView[j].x, mOldCornersView[j].y, mOldCornersView[j].z);
[3085]716
[3110]717        sCgSsaoProgram->SetTexture(i ++, attribsTex);
718
[3129]719
[3026]720        DrawQuad(sCgSsaoProgram);
[2987]721
[3006]722        glPopAttrib();
[2859]723
724        PrintGLerror("ssao first pass");
725}
726
727
[2865]728static void SetVertex(float x, float y, float x_offs, float y_offs)
729{
730        glMultiTexCoord2fARB(GL_TEXTURE0_ARB, x, y); // center
731        glMultiTexCoord2fARB(GL_TEXTURE1_ARB, x - x_offs, y + y_offs); // left top
732        glMultiTexCoord2fARB(GL_TEXTURE2_ARB, x + x_offs, y - y_offs); // right bottom
733        glMultiTexCoord2fARB(GL_TEXTURE3_ARB, x + x_offs, y + y_offs); // right top
734        glMultiTexCoord2fARB(GL_TEXTURE4_ARB, x - x_offs, y - y_offs); // left bottom
735
736        glMultiTexCoord4fARB(GL_TEXTURE5_ARB, x - x_offs, y, x + x_offs, y); // left right
737        glMultiTexCoord4fARB(GL_TEXTURE6_ARB, x, y + y_offs, x, y - y_offs); // top bottom
738
[3089]739        //glVertex3f(x - 0.5f, y - 0.5f, -0.5f);
740        glVertex2f(x, y);
[2865]741}
742
743
[2970]744void DeferredRenderer::AntiAliasing(FrameBufferObject *fbo, DirectionalLight *light)
[2865]745{
[2968]746        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
747        GLuint colorsTex = colorBuffer->GetTexture();
[3136]748        GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
[3007]749
[3132]750        // read the second buffer, write to the first buffer
[3142]751        //FlipFbos(fbo);
[3162]752        // end of the pipeline => just draw image to screen
753        FrameBufferObject::Release();
[3132]754
[3136]755        // the neighbouring texels
756        float xOffs = 1.0f / fbo->GetWidth();
757        float yOffs = 1.0f / fbo->GetHeight();
758
[3034]759        sCgAntiAliasingProgram->SetTexture(0, colorsTex);
760        sCgAntiAliasingProgram->SetTexture(1, normalsTex);
[2865]761
[3136]762        float offsets[16];
763        int i = 0;
[2868]764
[3136]765        offsets[i] = -xOffs; offsets[i + 1] =  yOffs; i += 2; // left top
766        offsets[i] =  xOffs; offsets[i + 1] = -yOffs; i += 2; // right bottom
767        offsets[i] =  xOffs; offsets[i + 1] =  yOffs; i += 2; // right top
768        offsets[i] = -xOffs; offsets[i + 1] = -yOffs; i += 2; // left bottom
769        offsets[i] = -xOffs; offsets[i + 1] =    .0f; i += 2; // left
770        offsets[i] =  xOffs; offsets[i + 1] =    .0f; i += 2; // right
771        offsets[i] =    .0f; offsets[i + 1] =  yOffs; i += 2; // top
772        offsets[i] =    .0f; offsets[i + 1] = -yOffs; i += 2; // bottom
[2865]773
[3136]774        sCgAntiAliasingProgram->SetArray2f(2, offsets, 8);
[2865]775
[3136]776        DrawQuad(sCgAntiAliasingProgram);
[2865]777
[2867]778        PrintGLerror("antialiasing");
[2865]779}
780
781
[2952]782void DeferredRenderer::FirstPass(FrameBufferObject *fbo, DirectionalLight *light)
[2868]783{
[2973]784        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[3009]785        GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
[2868]786
[3132]787        FlipFbos(fbo);
[2868]788
[3026]789        const Vector3 lightDir = -light->GetDirection();
[2868]790
[3034]791        sCgDeferredProgram->SetTexture(0, colorsTex);
792        sCgDeferredProgram->SetTexture(1, normalsTex);
793        sCgDeferredProgram->SetValue3f(2, lightDir.x, lightDir.y, lightDir.z);
[2868]794       
[3026]795        DrawQuad(sCgDeferredProgram);
[2952]796
[2868]797        PrintGLerror("deferred shading");
798}
799
[2869]800
[2896]801void DeferredRenderer::ComputeGlobIllum(FrameBufferObject *fbo,
[3085]802                                                                                float tempCohFactor)
[2869]803{
[3016]804#if 0
805        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
806        GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
807#else
[3003]808        GLuint colorsTex = mDownSampleFbo->GetColorBuffer(0)->GetTexture();
[3009]809        GLuint normalsTex = mDownSampleFbo->GetColorBuffer(1)->GetTexture();
[3016]810#endif
[2869]811
[3006]812        glPushAttrib(GL_VIEWPORT_BIT);
[3019]813        glViewport(0, 0, mIllumFbo->GetWidth(), mIllumFbo->GetHeight());
[2869]814
[2873]815        // read the second buffer, write to the first buffer
[3019]816        mIllumFbo->Bind();
[2873]817
[3019]818        glDrawBuffers(2, mrt + mIllumFboIndex);
[2873]819
[3019]820        GLuint oldSsaoTex = mIllumFbo->GetColorBuffer(2 - mIllumFboIndex)->GetTexture();
821        GLuint oldIllumTex = mIllumFbo->GetColorBuffer(2 - mIllumFboIndex + 1)->GetTexture();
[2869]822
[3160]823        int i = 0;
[2869]824
[3160]825        sCgGiProgram->SetTexture(i ++, colorsTex);
826        sCgGiProgram->SetTexture(i ++, normalsTex);
827        sCgGiProgram->SetTexture(i ++, noiseTex2D);
828        sCgGiProgram->SetTexture(i ++, oldSsaoTex);
829        sCgGiProgram->SetTexture(i ++, oldIllumTex);
830
831        sCgGiProgram->SetValue1f(i ++,
[3026]832                (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
[2869]833
[2895]834        if (mUseTemporalCoherence || mRegenerateSamples)
[2875]835        {
[2895]836                mRegenerateSamples = false;
[2873]837
[2875]838                // q: should we generate new samples or only rotate the old ones?
839                // in the first case, the sample patterns look nicer, but the kernel
840                // needs longer to converge
[2895]841                GenerateSamples(mSamplingMethod);
[2903]842
[3160]843                sCgGiProgram->SetArray2f(i ++, (float *)samples2, NUM_SAMPLES);
[2875]844        }
845
[3085]846        Vector3 bl = mCornersView[0];
847        Vector3 br = mCornersView[1];
848        Vector3 tl = mCornersView[2];
849        Vector3 tr = mCornersView[3];
[2895]850
[3160]851        sCgGiProgram->SetValue3f(i ++, bl.x, bl.y, bl.z);
852        sCgGiProgram->SetValue3f(i ++, br.x, br.y, br.z);
853        sCgGiProgram->SetValue3f(i ++, tl.x, tl.y, tl.z);
854        sCgGiProgram->SetValue3f(i ++, tr.x, tr.y, tr.z);
[2873]855
[3160]856        sCgGiProgram->SetMatrix(i ++, mOldProjViewMatrix);
857        sCgGiProgram->SetMatrix(i ++, mProjViewMatrix);
[3035]858
859
[3026]860        DrawQuad(sCgGiProgram);
[2990]861
[3006]862        glPopAttrib();
863
[2873]864        PrintGLerror("globillum first pass");
[2869]865}
866
867
[2896]868void DeferredRenderer::CombineIllum(FrameBufferObject *fbo)
[2880]869{
[2973]870        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[2884]871
[3019]872        GLuint ssaoTex = mIllumFbo->GetColorBuffer(mIllumFboIndex)->GetTexture();
873        GLuint illumTex = mIllumFbo->GetColorBuffer(mIllumFboIndex + 1)->GetTexture();
[2880]874
[3132]875        FlipFbos(fbo);
[2891]876
[3036]877        sCgCombineIllumProgram->SetTexture(0, colorsTex);
878        sCgCombineIllumProgram->SetTexture(1, ssaoTex);
879        sCgCombineIllumProgram->SetTexture(2, illumTex);
[2880]880       
[3026]881        DrawQuad(sCgCombineIllumProgram);
[2880]882
883        PrintGLerror("combine");
884}
885
886
[2896]887void DeferredRenderer::CombineSsao(FrameBufferObject *fbo)
[2880]888{
[2973]889        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[3103]890        GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
[3144]891        GLuint ssaoTex = mIllumFbo->GetColorBuffer(mIllumFboIndex)->GetTexture();
[3132]892       
893        FlipFbos(fbo);
[2880]894
[3104]895        int i = 0;
[3148]896
[3104]897        sCgCombineSsaoProgram->SetTexture(i ++, colorsTex);
[3120]898        sCgCombineSsaoProgram->SetTexture(i ++, normalsTex);
[3104]899        sCgCombineSsaoProgram->SetTexture(i ++, ssaoTex);
[3017]900
[3167]901        sCgCombineSsaoProgram->SetArray2f(i ++, (float *)ssaoFilterOffsets, NUM_SSAO_FILTER_SAMPLES);
902        sCgCombineSsaoProgram->SetArray1f(i ++, (float *)ssaoFilterWeights, NUM_SSAO_FILTER_SAMPLES);
[2880]903       
[3160]904        sCgCombineSsaoProgram->SetMatrix(i++, mProjViewMatrix);
[3134]905
[3163]906        for (int j = 0; j < 4; ++ j, ++ i)
907                sCgCombineSsaoProgram->SetValue3f(i, mCornersView[j].x, mCornersView[j].y, mCornersView[j].z);
[3134]908
[3026]909        DrawQuad(sCgCombineSsaoProgram);
[2974]910       
[2880]911        PrintGLerror("combine ssao");
912}
913
914
[2952]915void DeferredRenderer::FirstPassShadow(FrameBufferObject *fbo,
916                                                                           DirectionalLight *light,
917                                                                           ShadowMap *shadowMap)
[2895]918{
[2973]919        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[3009]920        GLuint normalsTex = fbo->GetColorBuffer(1)->GetTexture();
[2973]921
[2928]922        GLuint shadowTex = shadowMap->GetDepthTexture();
[2895]923
924        Matrix4x4 shadowMatrix;
925        shadowMap->GetTextureMatrix(shadowMatrix);
926
927
[3132]928        FlipFbos(fbo);
929
[3035]930        sCgDeferredShadowProgram->SetTexture(0, colorsTex);
931        sCgDeferredShadowProgram->SetTexture(1, normalsTex);
932        sCgDeferredShadowProgram->SetTexture(2, shadowTex);
[3129]933        sCgDeferredShadowProgram->SetTexture(3, noiseTex2D);
[3035]934        sCgDeferredShadowProgram->SetMatrix(4, shadowMatrix);
935        sCgDeferredShadowProgram->SetValue1f(5, 2.0f / shadowMap->GetSize());
[3027]936
[3026]937        const Vector3 lightDir = -light->GetDirection();
[3035]938        sCgDeferredShadowProgram->SetValue3f(6, lightDir.x, lightDir.y, lightDir.z);
[3085]939        sCgDeferredShadowProgram->SetValue3f(7, mEyePos.x, mEyePos.y, mEyePos.z);
[2952]940
[3026]941        DrawQuad(sCgDeferredShadowProgram);
[2895]942
943        PrintGLerror("deferred shading + shadows");
944}
945
946
[2896]947void DeferredRenderer::SetSamplingMethod(SAMPLING_METHOD s)
[2895]948{
949        if (s != mSamplingMethod)
950        {
951                mSamplingMethod = s;
952                mRegenerateSamples = true;
953        }
954}
955
[2897]956
957void DeferredRenderer::SetShadingMethod(SHADING_METHOD s)
958{
959        if (s != mShadingMethod)
960        {
961                mShadingMethod = s;
962                mRegenerateSamples = true;
963        }
964}
965
[2965]966
[2973]967void DeferredRenderer::ComputeToneParameters(FrameBufferObject *fbo,
968                                                                                         DirectionalLight *light,
969                                                                                         float &imageKey,
970                                                                                         float &whiteLum,
971                                                                                         float &middleGrey)
[2972]972{
[2975]973        // hack: estimate value where sky burns out
[3010]974        whiteLum = log(WHITE_LUMINANCE);
[2973]975       
[2975]976        ////////////////////
977        //-- linear interpolate brightness key depending on the current sun position
[2973]978
979        const float minKey = 0.09f;
[3020]980        const float maxKey = 0.36f;
[2973]981
982        const float lightIntensity = DotProd(-light->GetDirection(), Vector3::UNIT_Z());
983        middleGrey = lightIntensity * maxKey + (1.0f - lightIntensity) * minKey;
[2991]984
[2993]985
[2991]986        //////////
987        //-- compute avg loglum
988
989        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
[2992]990        GLuint colorsTex = colorBuffer->GetTexture();
[2991]991
[3132]992        FlipFbos(fbo);
[2991]993       
[3035]994        sCgLogLumProgram->SetTexture(0, colorsTex);
[3026]995        DrawQuad(sCgLogLumProgram);
[2991]996       
997        PrintGLerror("ToneMapParams");
998
999
1000        ///////////////////
1001        //-- compute avg loglum in scene using mipmapping
1002
[3008]1003        glBindTexture(GL_TEXTURE_2D, fbo->GetColorBuffer(colorBufferIdx)->GetTexture());
1004        glGenerateMipmapEXT(GL_TEXTURE_2D);
[2972]1005}
1006
1007
[3003]1008static void ExportData(float *data, int w, int h)
1009{
1010        startil();
1011
1012        cout << "w: " << w << " h: " << h << endl;
1013        ILstring filename = ILstring("downsample2.jpg");
1014        ilRegisterType(IL_FLOAT);
1015
1016        const int depth = 1;
1017        const int bpp = 4;
1018
1019        if (!ilTexImage(w, h, depth, bpp, IL_RGBA, IL_FLOAT, data))
1020        {
1021                cerr << "IL error " << ilGetError() << endl;
1022                stopil();
1023                return;
1024        }
1025
1026        if (!ilSaveImage(filename))
1027        {
1028                cerr << "TGA write error " << ilGetError() << endl;
1029        }
1030
1031        stopil();
1032}
1033
1034
[3155]1035void DeferredRenderer::PrepareSsao(FrameBufferObject *fbo)
1036{
[3167]1037        GLuint colorsTex, normalsTex, diffVals, oldTex;
[3155]1038
1039        colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[3167]1040        normalsTex = fbo->GetColorBuffer(1)->GetTexture();
[3155]1041        diffVals = fbo->GetColorBuffer(2)->GetTexture();
1042        //diffVals = mDownSampleFbo->GetColorBuffer(2)->GetTexture();
1043
1044        // flip flop between illumination buffers
1045        oldTex = mIllumFbo->GetColorBuffer(2 - mIllumFboIndex)->GetTexture();
1046
1047        int i = 0;
1048
1049        sCgPrepareSsaoProgram->SetTexture(i ++, colorsTex);
[3167]1050        sCgPrepareSsaoProgram->SetTexture(i ++, normalsTex);
1051        sCgPrepareSsaoProgram->SetTexture(i ++, diffVals);
[3155]1052        sCgPrepareSsaoProgram->SetTexture(i ++, oldTex);
1053
1054        Vector3 de;
1055        de.x = mOldEyePos.x - mEyePos.x;
1056        de.y = mOldEyePos.y - mEyePos.y;
1057        de.z = mOldEyePos.z - mEyePos.z;
1058
1059        sCgPrepareSsaoProgram->SetValue3f(i ++, de.x, de.y, de.z);
1060
[3156]1061        sCgPrepareSsaoProgram->SetMatrix(i ++, mProjViewMatrix);
1062        sCgPrepareSsaoProgram->SetMatrix(i ++, mOldProjViewMatrix);
1063
1064        for (int j = 0; j < 4; ++ j, ++ i)
1065                sCgPrepareSsaoProgram->SetValue3f(i, mOldCornersView[j].x, mOldCornersView[j].y, mOldCornersView[j].z);
1066
[3155]1067        glPushAttrib(GL_VIEWPORT_BIT);
1068        glViewport(0, 0, mDownSampleFbo->GetWidth(), mDownSampleFbo->GetHeight());
1069       
1070        mDownSampleFbo->Bind();
1071
[3167]1072        glDrawBuffers(3, mrt + 0);
[3155]1073
1074        DrawQuad(sCgPrepareSsaoProgram);
1075       
1076        glPopAttrib();
1077        PrintGLerror("prepareSsao");
1078}
1079
1080
1081
[3103]1082void DeferredRenderer::DownSample(FrameBufferObject *fbo,
1083                                                                  int bufferIdx,
[3006]1084                                                                  FrameBufferObject *downSampleFbo,
[3137]1085                                                                  int downSampleBufferIdx,
1086                                                                  ShaderProgram *program)
[2972]1087{
[3137]1088        ColorBufferObject *buffer = fbo->GetColorBuffer(bufferIdx);
1089        GLuint tex = buffer->GetTexture();
[3006]1090
1091        glPushAttrib(GL_VIEWPORT_BIT);
1092        glViewport(0, 0, downSampleFbo->GetWidth(), downSampleFbo->GetHeight());
[2972]1093       
[3137]1094        downSampleFbo->Bind();
[2994]1095
[3137]1096        program->SetTexture(0, tex);
[3006]1097        glDrawBuffers(1, mrt + downSampleBufferIdx);
[2994]1098
[3137]1099        DrawQuad(program);
[3005]1100       
[3006]1101        glPopAttrib();
[3005]1102        PrintGLerror("downsample");
[2972]1103}
1104
1105
[2973]1106void DeferredRenderer::ToneMap(FrameBufferObject *fbo,
1107                                                           float imageKey,
1108                                                           float whiteLum,
1109                                                           float middleGrey)
[2972]1110{
1111        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
[2994]1112        GLuint colorsTex = colorBuffer->GetTexture();
[3132]1113        //FrameBufferObject::Release();
[2972]1114
[3132]1115        FlipFbos(fbo);
[3007]1116
[3035]1117        sCgToneProgram->SetTexture(0, colorsTex);
1118        sCgToneProgram->SetValue1f(1, imageKey);
1119        sCgToneProgram->SetValue1f(2, whiteLum);
1120        sCgToneProgram->SetValue1f(3, middleGrey);
[3007]1121
[3026]1122        DrawQuad(sCgToneProgram);
[2972]1123
[2973]1124        PrintGLerror("ToneMap");
[2972]1125}
1126
1127
[3132]1128void DeferredRenderer::Output(FrameBufferObject *fbo)
1129{
1130        glPushAttrib(GL_VIEWPORT_BIT);
1131        glViewport(0, 0, fbo->GetWidth(), fbo->GetHeight());
1132       
1133        ColorBufferObject *colorBuffer = fbo->GetColorBuffer(colorBufferIdx);
1134        GLuint colorsTex = colorBuffer->GetTexture();
1135
1136        sCgDownSampleProgram->SetTexture(0, colorsTex);
1137
1138        FrameBufferObject::Release();
1139        DrawQuad(sCgDownSampleProgram);
1140
[3134]1141        PrintGLerror("output");
[3132]1142}
1143
1144
[3085]1145void DeferredRenderer::InitFrame()
1146{
[3095]1147        for (int i = 0; i < 4; ++ i)
1148                mOldCornersView[i] = mCornersView[i];
1149
[3085]1150        mOldProjViewMatrix = mProjViewMatrix;
[3095]1151        mOldEyePos = mEyePos;
[3106]1152        mEyePos = mCamera->GetPosition();
[3081]1153
[3104]1154        // hack: temporarily change far to improve precision
1155        const float oldFar = mCamera->GetFar();
[3106]1156        const float oldNear = mCamera->GetNear();
[3132]1157       
[3104]1158
[3106]1159        Matrix4x4 matViewing, matProjection;
[3104]1160
[3106]1161
1162        ///////////////////
1163
1164
[3093]1165        mCamera->GetViewOrientationMatrix(matViewing);
[3085]1166        mCamera->GetProjectionMatrix(matProjection);
1167
1168        mProjViewMatrix = matViewing * matProjection;
[3095]1169        ComputeViewVectors(mCamera, mCornersView[0], mCornersView[1], mCornersView[2], mCornersView[3]);
[3106]1170       
[3085]1171
[3095]1172        // switch roles of old and new fbo
1173        // the algorihm uses two input fbos, where the one
1174        // contais the color buffer from the last frame,
1175        // the other one will be written
[3085]1176
[3095]1177        mIllumFboIndex = 2 - mIllumFboIndex;
1178       
1179        // enable fragment shading
1180        ShaderManager::GetSingleton()->EnableFragmentProfile();
1181
1182        glDisable(GL_ALPHA_TEST);
1183        glDisable(GL_TEXTURE_2D);
1184        glDisable(GL_LIGHTING);
1185        glDisable(GL_BLEND);
1186        glDisable(GL_DEPTH_TEST);
1187
1188        glPolygonMode(GL_FRONT, GL_FILL);
1189
1190        glMatrixMode(GL_PROJECTION);
1191        glPushMatrix();
1192        glLoadIdentity();
1193
1194        gluOrtho2D(0, 1, 0, 1);
1195
1196
1197        glMatrixMode(GL_MODELVIEW);
1198        glPushMatrix();
1199        glLoadIdentity();
1200
1201       
1202        glPushAttrib(GL_VIEWPORT_BIT);
1203        glViewport(0, 0, mWidth, mHeight);
[3128]1204
1205        // revert to old far and near plane
[3104]1206        mCamera->SetFar(oldFar);
[3106]1207        mCamera->SetNear(oldNear);
[3085]1208}
1209
1210
[2858]1211} // namespace
Note: See TracBrowser for help on using the repository browser.