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

Revision 3113, 28.3 KB checked in by mattausch, 16 years ago (diff)

problm with technique system

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