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

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