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

Revision 2967, 31.2 KB checked in by mattausch, 16 years ago (diff)
RevLine 
[2896]1#include "DeferredRenderer.h"
[2859]2#include "FrameBufferObject.h"
3#include "RenderState.h"
4#include "SampleGenerator.h"
[2860]5#include "Vector3.h"
6#include "Camera.h"
[2884]7#include "shaderenv.h"
[2886]8#include "Halton.h"
[2895]9#include "ShadowMapping.h"
[2952]10#include "Light.h"
[2966]11#include "ToneMapper.h"
[2858]12
[2859]13
[2858]14using namespace std;
15
16
17namespace CHCDemoEngine
18{
19
[2859]20static CGprogram sCgSsaoProgram = NULL;
[2873]21static CGprogram sCgGiProgram = NULL;
22
23static CGprogram sCgDeferredProgram = NULL;
[2868]24static CGprogram sCgAntiAliasingProgram = NULL;
[2895]25static CGprogram sCgDeferredShadowProgram = NULL;
[2859]26
[2869]27static CGparameter sColorsTexCombineParam;
28static CGparameter sSsaoTexCombineParam;
29
[2868]30static CGparameter sColorsTexDeferredParam;
31static CGparameter sPositionsTexDeferredParam;
32static CGparameter sNormalsTexDeferredParam;
33
[2880]34static CGprogram sCgCombinedSsaoProgram = NULL;
35static CGprogram sCgCombinedIllumProgram = NULL;
36
[2967]37
[2944]38///////////////////////////////////////
[2873]39
40
[2859]41static CGparameter sColorsTexParam;
42static CGparameter sPositionsTexParam;
43static CGparameter sNormalsTexParam;
[2868]44
[2859]45static CGparameter sOldModelViewProjMatrixParam;
[2900]46static CGparameter sModelViewProjMatrixParam;
[2859]47static CGparameter sMaxDepthParam;
48static CGparameter sSamplesParam;
49static CGparameter sOldTexParam;
50static CGparameter sNoiseTexParam;
[2897]51static CGparameter sTemporalCoherenceParam;
[2859]52
[2873]53
54///////////////////////////////////////
55
56
57static CGparameter sColorsTexGiParam;
58static CGparameter sPositionsTexGiParam;
59static CGparameter sNormalsTexGiParam;
60
61
62static CGparameter sOldModelViewProjMatrixGiParam;
63static CGparameter sMaxDepthGiParam;
64static CGparameter sSamplesGiParam;
65static CGparameter sOldSsaoTexGiParam;
66static CGparameter sOldIllumTexGiParam;
67static CGparameter sNoiseTexGiParam;
[2897]68static CGparameter sTemporalCoherenceGiParam;
[2873]69
70
[2880]71static CGparameter sColorsTexCombinedIllumParam;
72static CGparameter sSsaoTexCombinedIllumParam;
73static CGparameter sIllumTexCombinedIllumParam;
74
75static CGparameter sColorsTexCombinedSsaoParam;
76static CGparameter sSsaoTexCombinedSsaoParam;
77
78
[2873]79////////////
80
[2865]81static CGparameter sColorsTexAntiAliasingParam;
82static CGparameter sNormalsTexAntiAliasingParam;
83
[2895]84
85static CGparameter sShadowMapParam;
86static CGparameter sPositionsTexShadowParam; 
87static CGparameter sColorsTexShadowParam; 
88static CGparameter sNormalsTexShadowParam;
89
90static CGparameter sShadowMatrixParam;
91static CGparameter sMaxDepthShadowParam;
92static CGparameter sSampleWidthParam;
93
[2944]94static CGparameter sNoiseTexShadowParam;
95static CGparameter sSamplesShadowParam;
96
[2952]97static CGparameter sLightDirParam;
98static CGparameter sLightDirShadowParam;
[2944]99
[2966]100static CGparameter sImageKeyParam;
[2952]101
[2903]102//#define USE_3D_SSAO
[2895]103
104
[2879]105static GLuint noiseTex = 0;
[2865]106
[2859]107// ssao random spherical samples
[2903]108#ifdef USE_3D_SSAO
[2900]109static Sample2 samples3[NUM_SAMPLES];
[2903]110#else
111static Sample2 samples2[NUM_SAMPLES];
112#endif
113
[2966]114// number of pcf tabs
115Sample2 pcfSamples[NUM_PCF_TABS];
116
[2895]117static int colorBufferIdx = 0;
[2859]118
119static void PrintGLerror(char *msg)
120{
121        GLenum errCode;
122        const GLubyte *errStr;
123       
124        if ((errCode = glGetError()) != GL_NO_ERROR)
125        {
126                errStr = gluErrorString(errCode);
127                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
128        }
129}
130
131
132/** Generate poisson disc distributed sample points on the unit disc
133*/
[2887]134static void GenerateSamples(int sampling)
[2859]135{
[2903]136#ifdef USE_3D_SSAO
137
138        SphericalSampleGenerator sph(NUM_SAMPLES, 1.0f);
139        sph.Generate((float *)samples3);
140
141#else
[2887]142        switch (sampling)
143        {
[2930]144        case DeferredRenderer::SAMPLING_POISSON:
[2887]145                {
[2930]146                        PoissonDiscSampleGenerator2 poisson(NUM_SAMPLES, 1.0f);
[2900]147                        poisson.Generate((float *)samples2);
[2887]148                }
149                break;
[2930]150        case DeferredRenderer::SAMPLING_QUADRATIC:
[2887]151                {
[2930]152                        QuadraticDiscSampleGenerator2 g(NUM_SAMPLES, 1.0f);
153                        g.Generate((float *)samples2);
[2887]154                }
155                break;
[2930]156        default: // SAMPLING_DEFAULT
157
158                RandomSampleGenerator2 g(NUM_SAMPLES, 1.0f);
159                g.Generate((float *)samples2);
[2903]160        }
161#endif
[2859]162}
163
164
[2879]165static void CreateNoiseTex2D(int w, int h)
166{
167        //GLubyte *randomNormals = new GLubyte[mWidth * mHeight * 3];
168        float *randomNormals = new float[w * h * 3];
169
[2900]170        static HaltonSequence halton;
171        float r[2];
172
[2879]173        for (int i = 0; i < w * h * 3; i += 3)
174        {
[2901]175               
[2903]176#ifdef USE_3D_SSAO
177                //halton.GetNext(2, r);
178                r[0] = RandomValue(0, 1);
179                r[1] = RandomValue(0, 1);
[2879]180
[2900]181                const float theta = 2.0f * acos(sqrt(1.0f - r[0]));
182                const float phi = 2.0f * M_PI * r[1];
183
184                randomNormals[i + 0] = sin(theta) * cos(phi);
185                randomNormals[i + 1] = sin(theta) * sin(phi);
186                randomNormals[i + 2] = cos(theta);
[2903]187#else
188                // create random samples on a circle
189                r[0] = RandomValue(0, 1);
190                //halton.GetNext(1, r);
191
192                const float theta = 2.0f * acos(sqrt(1.0f - r[0]));
193               
194                randomNormals[i + 0] = cos(theta);
195                randomNormals[i + 1] = sin(theta);
196                randomNormals[i + 2] = 0;
197#endif
[2879]198        }
199
200        glEnable(GL_TEXTURE_2D);
201        glGenTextures(1, &noiseTex);
202        glBindTexture(GL_TEXTURE_2D, noiseTex);
203               
204        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
205        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
206        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
207        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
208
[2884]209        //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, randomNormals);
[2879]210        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, w, h, 0, GL_RGB, GL_FLOAT, randomNormals);
211
212        glBindTexture(GL_TEXTURE_2D, 0);
213        glDisable(GL_TEXTURE_2D);
214
215        delete [] randomNormals;
216
217        cout << "created noise texture" << endl;
218
219        PrintGLerror("noisetexture");
220}
221
222
[2896]223DeferredRenderer::DeferredRenderer(int w, int h, Camera *cam, float scaleFactor):
[2860]224mWidth(w), mHeight(h),
225mCamera(cam),
[2875]226mScaleFactor(scaleFactor),
227mUseTemporalCoherence(true),
[2895]228mRegenerateSamples(true),
[2930]229mSamplingMethod(SAMPLING_POISSON),
[2895]230mShadingMethod(DEFAULT),
[2891]231mFboIndex(0)
[2861]232{
[2879]233        // create noise texture for ssao
234        CreateNoiseTex2D(w, h);
235
[2965]236
[2861]237        ///////////
238        //-- the flip-flop fbos
[2859]239
[2891]240        mFbo = new FrameBufferObject(w, h, FrameBufferObject::DEPTH_NONE);
241
[2965]242        mFbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
243        mFbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
244        mFbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
245        mFbo->AddColorBuffer(ColorBufferObject::BUFFER_FLOAT_32, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR);
[2861]246}
247
248
[2896]249DeferredRenderer::~DeferredRenderer()
[2861]250{
[2879]251        if (sCgSsaoProgram)     cgDestroyProgram(sCgSsaoProgram);
252        if (sCgDeferredProgram) cgDestroyProgram(sCgDeferredProgram);
253        if (sCgSsaoProgram)     cgDestroyProgram(sCgSsaoProgram);
254        if (sCgGiProgram) cgDestroyProgram(sCgGiProgram);
255        if (sCgAntiAliasingProgram) cgDestroyProgram(sCgAntiAliasingProgram);
[2861]256
[2891]257        DEL_PTR(mFbo);
[2861]258
259        glDeleteTextures(1, &noiseTex);
260}
261
262
[2896]263void DeferredRenderer::SetUseTemporalCoherence(bool temporal)
[2875]264{
265        mUseTemporalCoherence = temporal;
266}
267
268
[2896]269void DeferredRenderer::Init(CGcontext context)
[2861]270{       
[2873]271        sCgDeferredProgram =
[2868]272                cgCreateProgramFromFile(context,
273                                                                CG_SOURCE,
274                                                                "src/shaders/deferred.cg",
275                                                                RenderState::sCgFragmentProfile,
[2873]276                                                                "main",
[2868]277                                                                NULL);
278
[2873]279        if (sCgDeferredProgram != NULL)
[2868]280        {
[2873]281                cgGLLoadProgram(sCgDeferredProgram);
[2868]282
283                // we need size of texture for scaling
[2873]284                sPositionsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "positions"); 
285                sColorsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "colors"); 
[2944]286                sNormalsTexDeferredParam = cgGetNamedParameter(sCgDeferredProgram, "normals");
[2952]287                sLightDirParam = cgGetNamedParameter(sCgDeferredProgram, "lightDir");
[2868]288        }
289        else
290                cerr << "deferred program failed to load" << endl;
291
292
[2859]293        ///////////////
294
295        sCgSsaoProgram =
296                cgCreateProgramFromFile(context,
297                                                                CG_SOURCE,
[2903]298#ifdef USE_3D_SSAO
[2932]299                                                                "src/shaders/ssao3d.cg",
[2903]300#else
301                                                                "src/shaders/ssao.cg",
302#endif
[2859]303                                                                RenderState::sCgFragmentProfile,
[2868]304                                                                "main",
[2859]305                                                                NULL);
306
307        if (sCgSsaoProgram != NULL)
308        {
309                cgGLLoadProgram(sCgSsaoProgram);
310
311                sPositionsTexParam = cgGetNamedParameter(sCgSsaoProgram, "positions"); 
312                sColorsTexParam = cgGetNamedParameter(sCgSsaoProgram, "colors"); 
313                sNormalsTexParam = cgGetNamedParameter(sCgSsaoProgram, "normals"); 
314                sNoiseTexParam = cgGetNamedParameter(sCgSsaoProgram, "noiseTexture");
[2868]315               
[2859]316                sOldModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "oldModelViewProj");
[2900]317                sModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "mymodelViewProj");
[2859]318                sMaxDepthParam = cgGetNamedParameter(sCgSsaoProgram, "maxDepth");
[2897]319                sTemporalCoherenceParam = cgGetNamedParameter(sCgSsaoProgram, "temporalCoherence");
[2859]320
321                sOldTexParam = cgGetNamedParameter(sCgSsaoProgram, "oldTex"); 
[2884]322                sSamplesParam = cgGetNamedParameter(sCgSsaoProgram, "samples");
[2859]323        }
324        else
325                cerr << "ssao program failed to load" << endl;
326
[2873]327        sCgGiProgram =
328                cgCreateProgramFromFile(context,
329                                                                CG_SOURCE,
330                                                                "src/shaders/globillum.cg",
331                                                                RenderState::sCgFragmentProfile,
332                                                                "main",
333                                                                NULL);
334
335        if (sCgGiProgram != NULL)
336        {
337                cgGLLoadProgram(sCgGiProgram);
338
339                // we need size of texture for scaling
340                sPositionsTexGiParam = cgGetNamedParameter(sCgGiProgram, "positions"); 
341                sColorsTexGiParam = cgGetNamedParameter(sCgGiProgram, "colors"); 
342                sNormalsTexGiParam = cgGetNamedParameter(sCgGiProgram, "normals"); 
343               
[2874]344                sOldModelViewProjMatrixGiParam = cgGetNamedParameter(sCgGiProgram, "oldModelViewProj");
[2873]345                sMaxDepthGiParam = cgGetNamedParameter(sCgGiProgram, "maxDepth");
[2897]346                sTemporalCoherenceGiParam = cgGetNamedParameter(sCgGiProgram, "temporalCoherence");
[2873]347
[2944]348                sNoiseTexGiParam = cgGetNamedParameter(sCgGiProgram, "noiseTexture");
[2873]349                sSamplesGiParam = cgGetNamedParameter(sCgGiProgram, "samples");
350               
351                sOldSsaoTexGiParam = cgGetNamedParameter(sCgGiProgram, "oldSsaoTex"); 
352                sOldIllumTexGiParam = cgGetNamedParameter(sCgGiProgram, "oldIllumTex"); 
353        }
354        else
355                cerr << "globillum program failed to load" << endl;
356
[2880]357        sCgCombinedIllumProgram =
358                cgCreateProgramFromFile(context,
359                                                                CG_SOURCE,
360                                                                "src/shaders/globillum.cg",
361                                                                RenderState::sCgFragmentProfile,
362                                                                "combine",
363                                                                NULL);
364
365        if (sCgCombinedIllumProgram != NULL)
366        {
367                cgGLLoadProgram(sCgCombinedIllumProgram);
368
369                sColorsTexCombinedIllumParam = cgGetNamedParameter(sCgCombinedIllumProgram, "colors"); 
370                sSsaoTexCombinedIllumParam = cgGetNamedParameter(sCgCombinedIllumProgram, "ssaoTex");
371                sIllumTexCombinedIllumParam = cgGetNamedParameter(sCgCombinedIllumProgram, "illumTex");
372        }
373        else
374                cerr << "combined illum program failed to load" << endl;
375
376
377        sCgCombinedSsaoProgram =
378                cgCreateProgramFromFile(context,
379                                                                CG_SOURCE,
380                                                                "src/shaders/ssao.cg",
381                                                                RenderState::sCgFragmentProfile,
382                                                                "combine",
383                                                                NULL);
384
385        if (sCgCombinedSsaoProgram != NULL)
386        {
387                cgGLLoadProgram(sCgCombinedSsaoProgram);
388
389                sColorsTexCombinedSsaoParam = cgGetNamedParameter(sCgCombinedSsaoProgram, "colors"); 
390                sSsaoTexCombinedSsaoParam = cgGetNamedParameter(sCgCombinedSsaoProgram, "ssaoTex");
391        }
392        else
393                cerr << "combied illum program failed to load" << endl;
394
395       
[2865]396        sCgAntiAliasingProgram =
397                cgCreateProgramFromFile(context,
398                                                                CG_SOURCE,
399                                                                "src/shaders/antialiasing.cg",
400                                                                RenderState::sCgFragmentProfile,
401                                                                "main",
402                                                                NULL);
403
404        if (sCgAntiAliasingProgram != NULL)
405        {
406                cgGLLoadProgram(sCgAntiAliasingProgram);
407
[2967]408                sImageKeyParam = cgGetNamedParameter(sCgAntiAliasingProgram, "imageKey");
409
[2865]410                sColorsTexAntiAliasingParam = cgGetNamedParameter(sCgAntiAliasingProgram, "colors"); 
411                sNormalsTexAntiAliasingParam = cgGetNamedParameter(sCgAntiAliasingProgram, "normals");
412        }
413        else
414                cerr << "antialiasing program failed to load" << endl;
415
[2895]416        sCgDeferredShadowProgram =
417                cgCreateProgramFromFile(context,
418                                                                CG_SOURCE,
419                                                                "src/shaders/deferred.cg",
420                                                                RenderState::sCgFragmentProfile,
421                                                                "main_shadow",
422                                                                NULL);
423
424        if (sCgDeferredShadowProgram != NULL)
425        {
426                cgGLLoadProgram(sCgDeferredShadowProgram);
427
428                // we need size of texture for scaling
429                sPositionsTexShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "positions"); 
430                sColorsTexShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "colors"); 
431                sNormalsTexShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "normals");
432
433                sShadowMapParam = cgGetNamedParameter(sCgDeferredShadowProgram, "shadowMap"); 
434                sMaxDepthShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "maxDepth");
435                sSampleWidthParam = cgGetNamedParameter(sCgDeferredShadowProgram, "sampleWidth");
436                sShadowMatrixParam = cgGetNamedParameter(sCgDeferredShadowProgram, "shadowMatrix");
[2928]437
[2944]438                sNoiseTexShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "noiseTexture");
439                sSamplesShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "samples");
[2952]440                sLightDirShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "lightDir");
[2928]441
[2966]442
443                PoissonDiscSampleGenerator2 poisson(NUM_PCF_TABS, 1.0f);
[2944]444                poisson.Generate((float *)pcfSamples);
[2928]445
[2966]446                cgGLSetParameterArray2f(sSamplesShadowParam, 0, NUM_PCF_TABS, (const float *)pcfSamples);
[2928]447        }
448        else
[2944]449                cerr << "deferred program failed to load" << endl;
[2928]450
[2859]451        PrintGLerror("init");
452}
453
454
[2896]455void DeferredRenderer::Render(FrameBufferObject *fbo,
[2897]456                                                          const Matrix4x4 &oldProjViewMatrix,
[2900]457                                                          const Matrix4x4 &projViewMatrix,
[2901]458                                                          float tempCohFactor,
[2952]459                                                          DirectionalLight *light,
[2897]460                                                          ShadowMap *shadowMap)
[2859]461{
[2868]462        // switch roles of old and new fbo
463        // the algorihm uses two input fbos, where the one
464        // contais the color buffer from the last frame,
465        // the other one will be written
[2897]466
467        mFboIndex = 2 - mFboIndex;
[2891]468        //swap(mNewFbo, mOldFbo);       
[2897]469
[2868]470        FrameBufferObject::Release();
471
[2867]472        cgGLEnableProfile(RenderState::sCgFragmentProfile);
473
474        glDisable(GL_ALPHA_TEST);
475        glDisable(GL_TEXTURE_2D);
476        glDisable(GL_LIGHTING);
477
[2880]478        glPushAttrib(GL_VIEWPORT_BIT);
479        glViewport(0, 0, mWidth, mHeight);
480
[2867]481        glMatrixMode(GL_PROJECTION);
482        glPushMatrix();
483        glLoadIdentity();
484
[2897]485        const float offs = 0.5f;
486        glOrtho(-offs, offs, -offs, offs, 0, 1);
487
[2867]488        glMatrixMode(GL_MODELVIEW);
489        glPushMatrix();
490        glLoadIdentity();
491
[2944]492        if (shadowMap)
[2952]493                FirstPassShadow(fbo, light, shadowMap);
[2895]494        else
[2952]495                FirstPass(fbo, light);
[2944]496
497        switch (mShadingMethod)
[2880]498        {
[2944]499        case SSAO:
500                ComputeSsao(fbo, tempCohFactor, oldProjViewMatrix, projViewMatrix);
501                CombineSsao(fbo);
502                break;
503        case GI:
504                ComputeGlobIllum(fbo, tempCohFactor, oldProjViewMatrix);
505                CombineIllum(fbo);
506                break;
507        default: // DEFAULT
508                // do nothing: standard deferred shading
509                break;
510        }
[2884]511
[2944]512        AntiAliasing(fbo);
[2867]513
514        glEnable(GL_LIGHTING);
515        glDisable(GL_TEXTURE_2D);
516
517        glMatrixMode(GL_PROJECTION);
518        glPopMatrix();
519
520        glMatrixMode(GL_MODELVIEW);
521        glPopMatrix();
522
523        glPopAttrib();
524
525        cgGLDisableProfile(RenderState::sCgFragmentProfile);
[2859]526}
527
528
[2896]529void DeferredRenderer::ComputeSsao(FrameBufferObject *fbo,
[2901]530                                                                   float tempCohFactor,
[2900]531                                                                   const Matrix4x4 &oldProjViewMatrix,
532                                                                   const Matrix4x4 &projViewMatrix
533                                                                   )
[2859]534{
[2903]535#ifdef USE_3D_SSAO
[2900]536        static Matrix4x4 biasMatrix(0.5f, 0.0f, 0.0f, 0.5f,
537                                                                0.0f, 0.5f, 0.0f, 0.5f,
538                                                                0.0f, 0.0f, 0.5f, 0.5f,
539                                                                0.0f, 0.0f, 0.0f, 1.0f); //bias from [-1, 1] to [0, 1]
540
541        Matrix4x4 m = projViewMatrix * biasMatrix;
542
543        cgGLSetMatrixParameterfc(sModelViewProjMatrixParam, (const float *)m.x);
[2903]544#endif
[2874]545
[2903]546        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixParam, (const float *)oldProjViewMatrix.x);
547
[2879]548        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
[2861]549        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
550        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
[2859]551
[2867]552        if (1)
553        {
554                // generate mip map levels for position texture
555                glBindTexture(GL_TEXTURE_2D, positionsTex);
556                glGenerateMipmapEXT(GL_TEXTURE_2D);
557        }
558
559
[2861]560        // read the second buffer, write to the first buffer
[2891]561        //mNewFbo->Bind();
562        mFbo->Bind();
[2899]563        glDrawBuffers(1, mrt + mFboIndex);
[2868]564
[2880]565
[2891]566        //GLuint oldTex = mOldFbo->GetColorBuffer(0)->GetTexture();
567        GLuint oldTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
[2860]568
[2859]569        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
570
[2868]571        cgGLEnableProfile(RenderState::sCgFragmentProfile);
[2859]572        cgGLBindProgram(sCgSsaoProgram);
573
574        cgGLSetTextureParameter(sPositionsTexParam, positionsTex);
575        cgGLEnableTextureParameter(sPositionsTexParam);
576
577        cgGLSetTextureParameter(sColorsTexParam, colorsTex);
578        cgGLEnableTextureParameter(sColorsTexParam);
579
580        cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
581        cgGLEnableTextureParameter(sNormalsTexParam);
582
583        cgGLSetTextureParameter(sNoiseTexParam, noiseTex);
584        cgGLEnableTextureParameter(sNoiseTexParam);
585
586        cgGLSetTextureParameter(sOldTexParam, oldTex);
587        cgGLEnableTextureParameter(sOldTexParam);
588       
589        cgGLSetParameter1f(sMaxDepthParam, mScaleFactor);
[2875]590       
[2901]591        cgGLSetParameter1f(sTemporalCoherenceParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
[2893]592
[2895]593        if (mUseTemporalCoherence || mRegenerateSamples)
[2875]594        {
[2895]595                mRegenerateSamples = false;
[2859]596
[2875]597                // q: should we generate new samples or only rotate the old ones?
598                // in the first case, the sample patterns look nicer, but the kernel
599                // needs longer to converge
[2895]600                GenerateSamples(mSamplingMethod);
[2900]601
[2903]602#ifdef USE_3D_SSAO
[2900]603                cgGLSetParameterArray3f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples3);
[2903]604#else
605                cgGLSetParameterArray2f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples2);
606#endif
[2875]607        }
[2859]608
609        Vector3 tl, tr, bl, br;
610        ComputeViewVectors(tl, tr, bl, br);
611
612        glBegin(GL_QUADS);
613
614        // note: slightly larger texture hides ambient occlusion error on border but costs resolution
[2860]615        //const float new_offs = 0.55f;
616        const float new_offs = 0.5f;
[2891]617       
[2890]618        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f(-new_offs, -new_offs, -0.5f);
619        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f( new_offs, -new_offs, -0.5f);
620        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f( new_offs,  new_offs, -0.5f);
621        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f(-new_offs,  new_offs, -0.5f);
[2859]622
623        glEnd();
624
[2860]625        cgGLDisableTextureParameter(sColorsTexParam);
626        cgGLDisableTextureParameter(sPositionsTexParam);
627        cgGLDisableTextureParameter(sNormalsTexParam);
628        cgGLDisableTextureParameter(sNoiseTexParam);
629        cgGLDisableTextureParameter(sOldTexParam);
[2859]630
[2880]631
[2861]632        FrameBufferObject::Release();
[2859]633
634        PrintGLerror("ssao first pass");
635}
636
637
[2896]638void DeferredRenderer::ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
[2860]639{
640        Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
[2859]641
[2860]642        mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
643
[2888]644        bl = Normalize(nbl - fbl);
645        br = Normalize(nbr - fbr);
646        tl = Normalize(ntl - ftl);
647        tr = Normalize(ntr - ftr);
[2860]648}
649
650
651
[2865]652static void SetVertex(float x, float y, float x_offs, float y_offs)
653{
654        glMultiTexCoord2fARB(GL_TEXTURE0_ARB, x, y); // center
655        glMultiTexCoord2fARB(GL_TEXTURE1_ARB, x - x_offs, y + y_offs); // left top
656        glMultiTexCoord2fARB(GL_TEXTURE2_ARB, x + x_offs, y - y_offs); // right bottom
657        glMultiTexCoord2fARB(GL_TEXTURE3_ARB, x + x_offs, y + y_offs); // right top
658        glMultiTexCoord2fARB(GL_TEXTURE4_ARB, x - x_offs, y - y_offs); // left bottom
659
660        glMultiTexCoord4fARB(GL_TEXTURE5_ARB, x - x_offs, y, x + x_offs, y); // left right
661        glMultiTexCoord4fARB(GL_TEXTURE6_ARB, x, y + y_offs, x, y - y_offs); // top bottom
662
663        glVertex3f(x - 0.5f, y - 0.5f, -0.5f);
664}
665
666
[2896]667void DeferredRenderer::AntiAliasing(FrameBufferObject *fbo)
[2865]668{
[2967]669        const float imageKey = ToneMapper().CalcImageKey(fbo->GetColorBuffer(colorBufferIdx));
670
[2895]671        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
[2865]672        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
673       
674        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
675
676        cgGLEnableProfile(RenderState::sCgFragmentProfile);
677        cgGLBindProgram(sCgAntiAliasingProgram);
[2868]678       
[2865]679        cgGLSetTextureParameter(sColorsTexAntiAliasingParam, colorsTex);
680        cgGLEnableTextureParameter(sColorsTexAntiAliasingParam);
681
682        cgGLSetTextureParameter(sNormalsTexAntiAliasingParam, normalsTex);
683        cgGLEnableTextureParameter(sNormalsTexAntiAliasingParam);
[2868]684
[2967]685        cgGLSetParameter1f(sImageKeyParam, imageKey);
686
[2865]687        glColor3f(1.0f, 1.0f, 1.0f);
688
689        float offs2 = 0.5f;
690
691        glBegin(GL_QUADS);
692
693        // the neighbouring texels
694        float x_offs = 1.0f / mWidth;
695        float y_offs = 1.0f / mHeight;
696
697        SetVertex(0, 0, x_offs, y_offs);
698        SetVertex(1, 0, x_offs, y_offs);
699        SetVertex(1, 1, x_offs, y_offs);
700        SetVertex(0, 1, x_offs, y_offs);
701
702        glEnd();
703
704        cgGLDisableTextureParameter(sColorsTexAntiAliasingParam);
705        cgGLDisableTextureParameter(sNormalsTexAntiAliasingParam);
706
[2867]707        PrintGLerror("antialiasing");
[2865]708}
709
710
[2952]711void DeferredRenderer::FirstPass(FrameBufferObject *fbo, DirectionalLight *light)
[2868]712{
713        GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
714        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
715        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
716
[2879]717        fbo->Bind();
[2868]718
[2895]719        colorBufferIdx = 3;
[2899]720        glDrawBuffers(1, mrt + colorBufferIdx);
[2879]721
[2868]722        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
723       
724        cgGLEnableProfile(RenderState::sCgFragmentProfile);
725
[2873]726        cgGLBindProgram(sCgDeferredProgram);
[2868]727
728        cgGLSetTextureParameter(sColorsTexDeferredParam, colorsTex);
729        cgGLEnableTextureParameter(sColorsTexDeferredParam);
730
731        cgGLSetTextureParameter(sPositionsTexDeferredParam, positionsTex);
732        cgGLEnableTextureParameter(sPositionsTexDeferredParam);
733
734        cgGLSetTextureParameter(sNormalsTexDeferredParam, normalsTex);
735        cgGLEnableTextureParameter(sNormalsTexDeferredParam);
736       
[2952]737        Vector3 lightDir = -light->GetDirection();
738        cgGLSetParameter3f(sLightDirParam, lightDir.x, lightDir.y, lightDir.z);
739
[2966]740
[2868]741        glColor3f(1.0f, 1.0f, 1.0f);
742
743        const float offs = 0.5f;
744
745        glBegin(GL_QUADS);
746
747        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
748        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
749        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
750        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
751
752        glEnd();
753
754        cgGLDisableTextureParameter(sColorsTexDeferredParam);
755        cgGLDisableTextureParameter(sPositionsTexDeferredParam);
756        cgGLDisableTextureParameter(sNormalsTexDeferredParam);
757
758        cgGLDisableProfile(RenderState::sCgFragmentProfile);
759
760        FrameBufferObject::Release();
761
762        PrintGLerror("deferred shading");
763}
764
[2869]765
[2928]766
[2896]767void DeferredRenderer::ComputeGlobIllum(FrameBufferObject *fbo,
[2901]768                                                                                float tempCohFactor,
769                                                                                const Matrix4x4 &oldProjViewMatrix)
[2869]770{
[2874]771        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixGiParam, (const float *)oldProjViewMatrix.x);
772
[2879]773        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
[2873]774        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
775        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
[2869]776
[2873]777        if (1)
778        {
779                // generate mip map levels for position texture
780                glBindTexture(GL_TEXTURE_2D, positionsTex);
781                glGenerateMipmapEXT(GL_TEXTURE_2D);
[2869]782
[2873]783                // generate mip map levels for position texture
784                glBindTexture(GL_TEXTURE_2D, colorsTex);
785                glGenerateMipmapEXT(GL_TEXTURE_2D);
786        }
787
788
789        // read the second buffer, write to the first buffer
[2891]790        mFbo->Bind();
[2873]791
[2899]792        glDrawBuffers(2, mrt + mFboIndex);
[2873]793
[2891]794        GLuint oldSsaoTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
795        GLuint oldIllumTex = mFbo->GetColorBuffer(2 - mFboIndex + 1)->GetTexture();
796
[2869]797        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
798
799        cgGLEnableProfile(RenderState::sCgFragmentProfile);
[2873]800        cgGLBindProgram(sCgGiProgram);
[2869]801
[2873]802        cgGLSetTextureParameter(sPositionsTexGiParam, positionsTex);
803        cgGLEnableTextureParameter(sPositionsTexGiParam);
[2869]804
[2873]805        cgGLSetTextureParameter(sColorsTexGiParam, colorsTex);
806        cgGLEnableTextureParameter(sColorsTexGiParam);
[2869]807
[2873]808        cgGLSetTextureParameter(sNormalsTexGiParam, normalsTex);
809        cgGLEnableTextureParameter(sNormalsTexGiParam);
[2869]810
[2873]811        cgGLSetTextureParameter(sNoiseTexGiParam, noiseTex);
812        cgGLEnableTextureParameter(sNoiseTexGiParam);
813
814        cgGLSetTextureParameter(sOldSsaoTexGiParam, oldSsaoTex);
815        cgGLEnableTextureParameter(sOldSsaoTexGiParam);
816
817        cgGLSetTextureParameter(sOldIllumTexGiParam, oldIllumTex);
818        cgGLEnableTextureParameter(sOldIllumTexGiParam);
819
820        cgGLSetParameter1f(sMaxDepthGiParam, mScaleFactor);
821
[2901]822        cgGLSetParameter1f(sTemporalCoherenceGiParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
[2873]823
[2897]824
[2895]825        if (mUseTemporalCoherence || mRegenerateSamples)
[2875]826        {
[2895]827                mRegenerateSamples = false;
[2873]828
[2875]829                // q: should we generate new samples or only rotate the old ones?
830                // in the first case, the sample patterns look nicer, but the kernel
831                // needs longer to converge
[2895]832                GenerateSamples(mSamplingMethod);
[2903]833
834#ifdef USE_3D_SSAO
835                cgGLSetParameterArray3f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples3);
836#else
[2900]837                cgGLSetParameterArray2f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples2);
[2903]838#endif
[2875]839        }
840
[2895]841
[2873]842        Vector3 tl, tr, bl, br;
843        ComputeViewVectors(tl, tr, bl, br);
844
[2869]845        glBegin(GL_QUADS);
846
[2873]847        // note: slightly larger texture hides ambient occlusion error on border but costs resolution
848        //const float new_offs = 0.55f;
849        const float new_offs = 0.5f;
[2891]850               
851        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f(-new_offs, -new_offs, -0.5f);
852        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f( new_offs, -new_offs, -0.5f);
853        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f( new_offs,  new_offs, -0.5f);
854        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f(-new_offs,  new_offs, -0.5f);
[2869]855
856        glEnd();
857
[2873]858        cgGLDisableTextureParameter(sColorsTexGiParam);
859        cgGLDisableTextureParameter(sPositionsTexGiParam);
860        cgGLDisableTextureParameter(sNormalsTexGiParam);
861        cgGLDisableTextureParameter(sNoiseTexGiParam);
862        cgGLDisableTextureParameter(sOldSsaoTexGiParam);
863        cgGLDisableTextureParameter(sOldIllumTexGiParam);
[2869]864
865        FrameBufferObject::Release();
866
[2873]867        PrintGLerror("globillum first pass");
[2869]868}
869
870
[2896]871void DeferredRenderer::CombineIllum(FrameBufferObject *fbo)
[2880]872{
873        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
[2884]874
[2891]875        //GLuint ssaoTex = mNewFbo->GetColorBuffer(0)->GetTexture();
876        //GLuint illumTex = mNewFbo->GetColorBuffer(1)->GetTexture();
877        GLuint ssaoTex = mFbo->GetColorBuffer(mFboIndex)->GetTexture();
878        GLuint illumTex = mFbo->GetColorBuffer(mFboIndex + 1)->GetTexture();
[2880]879
[2891]880
[2880]881        fbo->Bind();
882
[2884]883        // overwrite old color texture
[2895]884        colorBufferIdx = 0;
[2899]885        glDrawBuffers(1, mrt + colorBufferIdx);
[2880]886
887        cgGLEnableProfile(RenderState::sCgFragmentProfile);
888
889        cgGLBindProgram(sCgCombinedIllumProgram);
890
[2881]891        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
892       
893
[2880]894        cgGLSetTextureParameter(sColorsTexCombinedIllumParam, colorsTex);
895        cgGLEnableTextureParameter(sColorsTexCombinedIllumParam);
896
897        cgGLSetTextureParameter(sSsaoTexCombinedIllumParam, ssaoTex);
898        cgGLEnableTextureParameter(sSsaoTexCombinedIllumParam);
899
900        cgGLSetTextureParameter(sIllumTexCombinedIllumParam, illumTex);
901        cgGLEnableTextureParameter(sIllumTexCombinedIllumParam);
902       
903        glColor3f(1.0f, 1.0f, 1.0f);
904
905        const float offs = 0.5f;
906
907        glBegin(GL_QUADS);
908
909        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
910        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
911        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
912        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
913
914        glEnd();
915
916        cgGLDisableTextureParameter(sColorsTexCombinedIllumParam);
917        cgGLDisableTextureParameter(sSsaoTexCombinedIllumParam);
918        cgGLDisableTextureParameter(sIllumTexCombinedIllumParam);
919
920        cgGLDisableProfile(RenderState::sCgFragmentProfile);
921
922        FrameBufferObject::Release();
923
924        PrintGLerror("combine");
925}
926
927
[2896]928void DeferredRenderer::CombineSsao(FrameBufferObject *fbo)
[2880]929{
930        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
[2891]931        GLuint ssaoTex = mFbo->GetColorBuffer(mFboIndex)->GetTexture();
[2880]932
933        fbo->Bind();
934
[2895]935        // overwrite old color texture
936        colorBufferIdx = 0;
[2899]937        glDrawBuffers(1, mrt + colorBufferIdx);
[2880]938
939        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
940       
941        cgGLEnableProfile(RenderState::sCgFragmentProfile);
942
943        cgGLBindProgram(sCgCombinedSsaoProgram);
944
945        cgGLSetTextureParameter(sColorsTexCombinedSsaoParam, colorsTex);
946        cgGLEnableTextureParameter(sColorsTexCombinedSsaoParam);
947
948        cgGLSetTextureParameter(sSsaoTexCombinedSsaoParam, ssaoTex);
949        cgGLEnableTextureParameter(sSsaoTexCombinedSsaoParam);
950
951       
952        glColor3f(1.0f, 1.0f, 1.0f);
953
954        const float offs = 0.5f;
955
956        glBegin(GL_QUADS);
957
958        glTexCoord2f(0, 0); glVertex3f(-offs, -offs, -0.5f);
959        glTexCoord2f(1, 0); glVertex3f( offs, -offs, -0.5f);
960        glTexCoord2f(1, 1); glVertex3f( offs,  offs, -0.5f);
961        glTexCoord2f(0, 1); glVertex3f(-offs,  offs, -0.5f);
962
963        glEnd();
964
965        cgGLDisableTextureParameter(sColorsTexCombinedSsaoParam);
966        cgGLDisableTextureParameter(sSsaoTexCombinedSsaoParam);
967
968        cgGLDisableProfile(RenderState::sCgFragmentProfile);
969
970        FrameBufferObject::Release();
971
972        PrintGLerror("combine ssao");
973}
974
975
[2952]976void DeferredRenderer::FirstPassShadow(FrameBufferObject *fbo,
977                                                                           DirectionalLight *light,
978                                                                           ShadowMap *shadowMap)
[2895]979{
980        GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
[2880]981
[2895]982        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
983        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
[2928]984        GLuint shadowTex = shadowMap->GetDepthTexture();
[2895]985
986        Matrix4x4 shadowMatrix;
987        shadowMap->GetTextureMatrix(shadowMatrix);
988
989        fbo->Bind();
990
991        colorBufferIdx = 3;
[2899]992        glDrawBuffers(1, mrt + colorBufferIdx);
[2895]993
994       
995        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
996
997        cgGLBindProgram(sCgDeferredShadowProgram);
998
999        cgGLSetTextureParameter(sColorsTexShadowParam, colorsTex);
1000        cgGLEnableTextureParameter(sColorsTexShadowParam);
1001
1002        cgGLSetTextureParameter(sPositionsTexShadowParam, positionsTex);
1003        cgGLEnableTextureParameter(sPositionsTexShadowParam);
1004
1005        cgGLSetTextureParameter(sNormalsTexShadowParam, normalsTex);
1006        cgGLEnableTextureParameter(sNormalsTexShadowParam);
1007       
1008        cgGLSetTextureParameter(sShadowMapParam, shadowTex);
1009        cgGLEnableTextureParameter(sShadowMapParam);
1010
1011        cgGLSetParameter1f(sMaxDepthShadowParam, mScaleFactor);
[2944]1012        //cgGLSetParameter1f(sSampleWidthParam, 10.0f / shadowMap->GetSize());
[2946]1013        cgGLSetParameter1f(sSampleWidthParam, 2.0f / shadowMap->GetSize());
1014        //cgGLSetParameter1f(sSampleWidthParam, 2.0f / 2048);
[2895]1015         
1016        cgGLSetMatrixParameterfc(sShadowMatrixParam, (const float *)shadowMatrix.x);
1017
[2944]1018        cgGLSetTextureParameter(sNoiseTexShadowParam, noiseTex);
1019        cgGLEnableTextureParameter(sNoiseTexShadowParam);
1020
[2952]1021        Vector3 lightDir = -light->GetDirection();
1022        cgGLSetParameter3f(sLightDirShadowParam, lightDir.x, lightDir.y, lightDir.z);
[2944]1023
[2952]1024
[2895]1025        glColor3f(1.0f, 1.0f, 1.0f);
1026       
1027        glBegin(GL_QUADS);
1028
1029        float offs2 = 0.5f;
1030
1031        glTexCoord2f(0, 0); glVertex3f(-offs2, -offs2, -0.5f);
1032        glTexCoord2f(1, 0); glVertex3f( offs2, -offs2, -0.5f);
1033        glTexCoord2f(1, 1); glVertex3f( offs2,  offs2, -0.5f);
1034        glTexCoord2f(0, 1); glVertex3f(-offs2,  offs2, -0.5f);
1035
1036        glEnd();
1037
1038        cgGLDisableTextureParameter(sColorsTexShadowParam);
1039        cgGLDisableTextureParameter(sPositionsTexShadowParam);
1040        cgGLDisableTextureParameter(sNormalsTexShadowParam);
1041        cgGLDisableTextureParameter(sShadowMapParam);
1042
[2944]1043        cgGLDisableTextureParameter(sNoiseTexShadowParam);
1044
[2895]1045        FrameBufferObject::Release();
1046
1047        PrintGLerror("deferred shading + shadows");
1048}
1049
1050
[2896]1051void DeferredRenderer::SetSamplingMethod(SAMPLING_METHOD s)
[2895]1052{
1053        if (s != mSamplingMethod)
1054        {
1055                mSamplingMethod = s;
1056                mRegenerateSamples = true;
1057        }
1058}
1059
[2897]1060
1061void DeferredRenderer::SetShadingMethod(SHADING_METHOD s)
1062{
1063        if (s != mShadingMethod)
1064        {
1065                mShadingMethod = s;
1066                mRegenerateSamples = true;
1067        }
1068}
1069
[2965]1070
1071
1072
1073
[2858]1074} // namespace
Note: See TracBrowser for help on using the repository browser.