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

Revision 2967, 31.2 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;
99
100static CGparameter sImageKeyParam;
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                sLightDirParam = cgGetNamedParameter(sCgDeferredProgram, "lightDir");
288        }
289        else
290                cerr << "deferred program failed to load" << endl;
291
292
293        ///////////////
294
295        sCgSsaoProgram =
296                cgCreateProgramFromFile(context,
297                                                                CG_SOURCE,
298#ifdef USE_3D_SSAO
299                                                                "src/shaders/ssao3d.cg",
300#else
301                                                                "src/shaders/ssao.cg",
302#endif
303                                                                RenderState::sCgFragmentProfile,
304                                                                "main",
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");
315               
316                sOldModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "oldModelViewProj");
317                sModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "mymodelViewProj");
318                sMaxDepthParam = cgGetNamedParameter(sCgSsaoProgram, "maxDepth");
319                sTemporalCoherenceParam = cgGetNamedParameter(sCgSsaoProgram, "temporalCoherence");
320
321                sOldTexParam = cgGetNamedParameter(sCgSsaoProgram, "oldTex"); 
322                sSamplesParam = cgGetNamedParameter(sCgSsaoProgram, "samples");
323        }
324        else
325                cerr << "ssao program failed to load" << endl;
326
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               
344                sOldModelViewProjMatrixGiParam = cgGetNamedParameter(sCgGiProgram, "oldModelViewProj");
345                sMaxDepthGiParam = cgGetNamedParameter(sCgGiProgram, "maxDepth");
346                sTemporalCoherenceGiParam = cgGetNamedParameter(sCgGiProgram, "temporalCoherence");
347
348                sNoiseTexGiParam = cgGetNamedParameter(sCgGiProgram, "noiseTexture");
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
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       
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
408                sImageKeyParam = cgGetNamedParameter(sCgAntiAliasingProgram, "imageKey");
409
410                sColorsTexAntiAliasingParam = cgGetNamedParameter(sCgAntiAliasingProgram, "colors"); 
411                sNormalsTexAntiAliasingParam = cgGetNamedParameter(sCgAntiAliasingProgram, "normals");
412        }
413        else
414                cerr << "antialiasing program failed to load" << endl;
415
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");
437
438                sNoiseTexShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "noiseTexture");
439                sSamplesShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "samples");
440                sLightDirShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "lightDir");
441
442
443                PoissonDiscSampleGenerator2 poisson(NUM_PCF_TABS, 1.0f);
444                poisson.Generate((float *)pcfSamples);
445
446                cgGLSetParameterArray2f(sSamplesShadowParam, 0, NUM_PCF_TABS, (const float *)pcfSamples);
447        }
448        else
449                cerr << "deferred program failed to load" << endl;
450
451        PrintGLerror("init");
452}
453
454
455void DeferredRenderer::Render(FrameBufferObject *fbo,
456                                                          const Matrix4x4 &oldProjViewMatrix,
457                                                          const Matrix4x4 &projViewMatrix,
458                                                          float tempCohFactor,
459                                                          DirectionalLight *light,
460                                                          ShadowMap *shadowMap)
461{
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
466
467        mFboIndex = 2 - mFboIndex;
468        //swap(mNewFbo, mOldFbo);       
469
470        FrameBufferObject::Release();
471
472        cgGLEnableProfile(RenderState::sCgFragmentProfile);
473
474        glDisable(GL_ALPHA_TEST);
475        glDisable(GL_TEXTURE_2D);
476        glDisable(GL_LIGHTING);
477
478        glPushAttrib(GL_VIEWPORT_BIT);
479        glViewport(0, 0, mWidth, mHeight);
480
481        glMatrixMode(GL_PROJECTION);
482        glPushMatrix();
483        glLoadIdentity();
484
485        const float offs = 0.5f;
486        glOrtho(-offs, offs, -offs, offs, 0, 1);
487
488        glMatrixMode(GL_MODELVIEW);
489        glPushMatrix();
490        glLoadIdentity();
491
492        if (shadowMap)
493                FirstPassShadow(fbo, light, shadowMap);
494        else
495                FirstPass(fbo, light);
496
497        switch (mShadingMethod)
498        {
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        }
511
512        AntiAliasing(fbo);
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);
526}
527
528
529void DeferredRenderer::ComputeSsao(FrameBufferObject *fbo,
530                                                                   float tempCohFactor,
531                                                                   const Matrix4x4 &oldProjViewMatrix,
532                                                                   const Matrix4x4 &projViewMatrix
533                                                                   )
534{
535#ifdef USE_3D_SSAO
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);
544#endif
545
546        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixParam, (const float *)oldProjViewMatrix.x);
547
548        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
549        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
550        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
551
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
560        // read the second buffer, write to the first buffer
561        //mNewFbo->Bind();
562        mFbo->Bind();
563        glDrawBuffers(1, mrt + mFboIndex);
564
565
566        //GLuint oldTex = mOldFbo->GetColorBuffer(0)->GetTexture();
567        GLuint oldTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
568
569        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
570
571        cgGLEnableProfile(RenderState::sCgFragmentProfile);
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);
590       
591        cgGLSetParameter1f(sTemporalCoherenceParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
592
593        if (mUseTemporalCoherence || mRegenerateSamples)
594        {
595                mRegenerateSamples = false;
596
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
600                GenerateSamples(mSamplingMethod);
601
602#ifdef USE_3D_SSAO
603                cgGLSetParameterArray3f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples3);
604#else
605                cgGLSetParameterArray2f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples2);
606#endif
607        }
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
615        //const float new_offs = 0.55f;
616        const float new_offs = 0.5f;
617       
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);
622
623        glEnd();
624
625        cgGLDisableTextureParameter(sColorsTexParam);
626        cgGLDisableTextureParameter(sPositionsTexParam);
627        cgGLDisableTextureParameter(sNormalsTexParam);
628        cgGLDisableTextureParameter(sNoiseTexParam);
629        cgGLDisableTextureParameter(sOldTexParam);
630
631
632        FrameBufferObject::Release();
633
634        PrintGLerror("ssao first pass");
635}
636
637
638void DeferredRenderer::ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
639{
640        Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
641
642        mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
643
644        bl = Normalize(nbl - fbl);
645        br = Normalize(nbr - fbr);
646        tl = Normalize(ntl - ftl);
647        tr = Normalize(ntr - ftr);
648}
649
650
651
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
667void DeferredRenderer::AntiAliasing(FrameBufferObject *fbo)
668{
669        const float imageKey = ToneMapper().CalcImageKey(fbo->GetColorBuffer(colorBufferIdx));
670
671        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
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);
678       
679        cgGLSetTextureParameter(sColorsTexAntiAliasingParam, colorsTex);
680        cgGLEnableTextureParameter(sColorsTexAntiAliasingParam);
681
682        cgGLSetTextureParameter(sNormalsTexAntiAliasingParam, normalsTex);
683        cgGLEnableTextureParameter(sNormalsTexAntiAliasingParam);
684
685        cgGLSetParameter1f(sImageKeyParam, imageKey);
686
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
707        PrintGLerror("antialiasing");
708}
709
710
711void DeferredRenderer::FirstPass(FrameBufferObject *fbo, DirectionalLight *light)
712{
713        GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
714        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
715        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
716
717        fbo->Bind();
718
719        colorBufferIdx = 3;
720        glDrawBuffers(1, mrt + colorBufferIdx);
721
722        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
723       
724        cgGLEnableProfile(RenderState::sCgFragmentProfile);
725
726        cgGLBindProgram(sCgDeferredProgram);
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       
737        Vector3 lightDir = -light->GetDirection();
738        cgGLSetParameter3f(sLightDirParam, lightDir.x, lightDir.y, lightDir.z);
739
740
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
765
766
767void DeferredRenderer::ComputeGlobIllum(FrameBufferObject *fbo,
768                                                                                float tempCohFactor,
769                                                                                const Matrix4x4 &oldProjViewMatrix)
770{
771        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixGiParam, (const float *)oldProjViewMatrix.x);
772
773        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
774        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
775        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
776
777        if (1)
778        {
779                // generate mip map levels for position texture
780                glBindTexture(GL_TEXTURE_2D, positionsTex);
781                glGenerateMipmapEXT(GL_TEXTURE_2D);
782
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
790        mFbo->Bind();
791
792        glDrawBuffers(2, mrt + mFboIndex);
793
794        GLuint oldSsaoTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
795        GLuint oldIllumTex = mFbo->GetColorBuffer(2 - mFboIndex + 1)->GetTexture();
796
797        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
798
799        cgGLEnableProfile(RenderState::sCgFragmentProfile);
800        cgGLBindProgram(sCgGiProgram);
801
802        cgGLSetTextureParameter(sPositionsTexGiParam, positionsTex);
803        cgGLEnableTextureParameter(sPositionsTexGiParam);
804
805        cgGLSetTextureParameter(sColorsTexGiParam, colorsTex);
806        cgGLEnableTextureParameter(sColorsTexGiParam);
807
808        cgGLSetTextureParameter(sNormalsTexGiParam, normalsTex);
809        cgGLEnableTextureParameter(sNormalsTexGiParam);
810
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
822        cgGLSetParameter1f(sTemporalCoherenceGiParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
823
824
825        if (mUseTemporalCoherence || mRegenerateSamples)
826        {
827                mRegenerateSamples = false;
828
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
832                GenerateSamples(mSamplingMethod);
833
834#ifdef USE_3D_SSAO
835                cgGLSetParameterArray3f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples3);
836#else
837                cgGLSetParameterArray2f(sSamplesGiParam, 0, NUM_SAMPLES, (const float *)samples2);
838#endif
839        }
840
841
842        Vector3 tl, tr, bl, br;
843        ComputeViewVectors(tl, tr, bl, br);
844
845        glBegin(GL_QUADS);
846
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;
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);
855
856        glEnd();
857
858        cgGLDisableTextureParameter(sColorsTexGiParam);
859        cgGLDisableTextureParameter(sPositionsTexGiParam);
860        cgGLDisableTextureParameter(sNormalsTexGiParam);
861        cgGLDisableTextureParameter(sNoiseTexGiParam);
862        cgGLDisableTextureParameter(sOldSsaoTexGiParam);
863        cgGLDisableTextureParameter(sOldIllumTexGiParam);
864
865        FrameBufferObject::Release();
866
867        PrintGLerror("globillum first pass");
868}
869
870
871void DeferredRenderer::CombineIllum(FrameBufferObject *fbo)
872{
873        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
874
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();
879
880
881        fbo->Bind();
882
883        // overwrite old color texture
884        colorBufferIdx = 0;
885        glDrawBuffers(1, mrt + colorBufferIdx);
886
887        cgGLEnableProfile(RenderState::sCgFragmentProfile);
888
889        cgGLBindProgram(sCgCombinedIllumProgram);
890
891        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
892       
893
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
928void DeferredRenderer::CombineSsao(FrameBufferObject *fbo)
929{
930        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
931        GLuint ssaoTex = mFbo->GetColorBuffer(mFboIndex)->GetTexture();
932
933        fbo->Bind();
934
935        // overwrite old color texture
936        colorBufferIdx = 0;
937        glDrawBuffers(1, mrt + colorBufferIdx);
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
976void DeferredRenderer::FirstPassShadow(FrameBufferObject *fbo,
977                                                                           DirectionalLight *light,
978                                                                           ShadowMap *shadowMap)
979{
980        GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
981
982        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
983        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
984        GLuint shadowTex = shadowMap->GetDepthTexture();
985
986        Matrix4x4 shadowMatrix;
987        shadowMap->GetTextureMatrix(shadowMatrix);
988
989        fbo->Bind();
990
991        colorBufferIdx = 3;
992        glDrawBuffers(1, mrt + colorBufferIdx);
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);
1012        //cgGLSetParameter1f(sSampleWidthParam, 10.0f / shadowMap->GetSize());
1013        cgGLSetParameter1f(sSampleWidthParam, 2.0f / shadowMap->GetSize());
1014        //cgGLSetParameter1f(sSampleWidthParam, 2.0f / 2048);
1015         
1016        cgGLSetMatrixParameterfc(sShadowMatrixParam, (const float *)shadowMatrix.x);
1017
1018        cgGLSetTextureParameter(sNoiseTexShadowParam, noiseTex);
1019        cgGLEnableTextureParameter(sNoiseTexShadowParam);
1020
1021        Vector3 lightDir = -light->GetDirection();
1022        cgGLSetParameter3f(sLightDirShadowParam, lightDir.x, lightDir.y, lightDir.z);
1023
1024
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
1043        cgGLDisableTextureParameter(sNoiseTexShadowParam);
1044
1045        FrameBufferObject::Release();
1046
1047        PrintGLerror("deferred shading + shadows");
1048}
1049
1050
1051void DeferredRenderer::SetSamplingMethod(SAMPLING_METHOD s)
1052{
1053        if (s != mSamplingMethod)
1054        {
1055                mSamplingMethod = s;
1056                mRegenerateSamples = true;
1057        }
1058}
1059
1060
1061void DeferredRenderer::SetShadingMethod(SHADING_METHOD s)
1062{
1063        if (s != mShadingMethod)
1064        {
1065                mShadingMethod = s;
1066                mRegenerateSamples = true;
1067        }
1068}
1069
1070
1071
1072
1073
1074} // namespace
Note: See TracBrowser for help on using the repository browser.