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

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