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

Revision 2966, 31.5 KB checked in by mattausch, 16 years ago (diff)

started reinhard tonemapping implementation but slow

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
40static CGparameter sColorsTexParam;
41static CGparameter sPositionsTexParam;
42static CGparameter sNormalsTexParam;
43
44static CGparameter sOldModelViewProjMatrixParam;
45static CGparameter sModelViewProjMatrixParam;
46static CGparameter sMaxDepthParam;
47static CGparameter sSamplesParam;
48static CGparameter sOldTexParam;
49static CGparameter sNoiseTexParam;
50static CGparameter sTemporalCoherenceParam;
51
52
53///////////////////////////////////////
54
55
56static CGparameter sColorsTexGiParam;
57static CGparameter sPositionsTexGiParam;
58static CGparameter sNormalsTexGiParam;
59
60
61static CGparameter sOldModelViewProjMatrixGiParam;
62static CGparameter sMaxDepthGiParam;
63static CGparameter sSamplesGiParam;
64static CGparameter sOldSsaoTexGiParam;
65static CGparameter sOldIllumTexGiParam;
66static CGparameter sNoiseTexGiParam;
67static CGparameter sTemporalCoherenceGiParam;
68
69
70static CGparameter sColorsTexCombinedIllumParam;
71static CGparameter sSsaoTexCombinedIllumParam;
72static CGparameter sIllumTexCombinedIllumParam;
73
74static CGparameter sColorsTexCombinedSsaoParam;
75static CGparameter sSsaoTexCombinedSsaoParam;
76
77
78////////////
79
80static CGparameter sColorsTexAntiAliasingParam;
81static CGparameter sNormalsTexAntiAliasingParam;
82
83
84static CGparameter sShadowMapParam;
85static CGparameter sPositionsTexShadowParam; 
86static CGparameter sColorsTexShadowParam; 
87static CGparameter sNormalsTexShadowParam;
88
89static CGparameter sShadowMatrixParam;
90static CGparameter sMaxDepthShadowParam;
91static CGparameter sSampleWidthParam;
92
93static CGparameter sNoiseTexShadowParam;
94static CGparameter sSamplesShadowParam;
95
96static CGparameter sLightDirParam;
97static CGparameter sLightDirShadowParam;
98
99static CGparameter sImageKeyParam;
100static CGparameter sImageKeyShadowParam;
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                sImageKeyParam = cgGetNamedParameter(sCgDeferredProgram, "imageKey");
290        }
291        else
292                cerr << "deferred program failed to load" << endl;
293
294
295        ///////////////
296
297        sCgSsaoProgram =
298                cgCreateProgramFromFile(context,
299                                                                CG_SOURCE,
300#ifdef USE_3D_SSAO
301                                                                "src/shaders/ssao3d.cg",
302#else
303                                                                "src/shaders/ssao.cg",
304#endif
305                                                                RenderState::sCgFragmentProfile,
306                                                                "main",
307                                                                NULL);
308
309        if (sCgSsaoProgram != NULL)
310        {
311                cgGLLoadProgram(sCgSsaoProgram);
312
313                sPositionsTexParam = cgGetNamedParameter(sCgSsaoProgram, "positions"); 
314                sColorsTexParam = cgGetNamedParameter(sCgSsaoProgram, "colors"); 
315                sNormalsTexParam = cgGetNamedParameter(sCgSsaoProgram, "normals"); 
316                sNoiseTexParam = cgGetNamedParameter(sCgSsaoProgram, "noiseTexture");
317               
318                sOldModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "oldModelViewProj");
319                sModelViewProjMatrixParam = cgGetNamedParameter(sCgSsaoProgram, "mymodelViewProj");
320                sMaxDepthParam = cgGetNamedParameter(sCgSsaoProgram, "maxDepth");
321                sTemporalCoherenceParam = cgGetNamedParameter(sCgSsaoProgram, "temporalCoherence");
322
323                sOldTexParam = cgGetNamedParameter(sCgSsaoProgram, "oldTex"); 
324                sSamplesParam = cgGetNamedParameter(sCgSsaoProgram, "samples");
325        }
326        else
327                cerr << "ssao program failed to load" << endl;
328
329        sCgGiProgram =
330                cgCreateProgramFromFile(context,
331                                                                CG_SOURCE,
332                                                                "src/shaders/globillum.cg",
333                                                                RenderState::sCgFragmentProfile,
334                                                                "main",
335                                                                NULL);
336
337        if (sCgGiProgram != NULL)
338        {
339                cgGLLoadProgram(sCgGiProgram);
340
341                // we need size of texture for scaling
342                sPositionsTexGiParam = cgGetNamedParameter(sCgGiProgram, "positions"); 
343                sColorsTexGiParam = cgGetNamedParameter(sCgGiProgram, "colors"); 
344                sNormalsTexGiParam = cgGetNamedParameter(sCgGiProgram, "normals"); 
345               
346                sOldModelViewProjMatrixGiParam = cgGetNamedParameter(sCgGiProgram, "oldModelViewProj");
347                sMaxDepthGiParam = cgGetNamedParameter(sCgGiProgram, "maxDepth");
348                sTemporalCoherenceGiParam = cgGetNamedParameter(sCgGiProgram, "temporalCoherence");
349
350                sNoiseTexGiParam = cgGetNamedParameter(sCgGiProgram, "noiseTexture");
351                sSamplesGiParam = cgGetNamedParameter(sCgGiProgram, "samples");
352               
353                sOldSsaoTexGiParam = cgGetNamedParameter(sCgGiProgram, "oldSsaoTex"); 
354                sOldIllumTexGiParam = cgGetNamedParameter(sCgGiProgram, "oldIllumTex"); 
355        }
356        else
357                cerr << "globillum program failed to load" << endl;
358
359        sCgCombinedIllumProgram =
360                cgCreateProgramFromFile(context,
361                                                                CG_SOURCE,
362                                                                "src/shaders/globillum.cg",
363                                                                RenderState::sCgFragmentProfile,
364                                                                "combine",
365                                                                NULL);
366
367        if (sCgCombinedIllumProgram != NULL)
368        {
369                cgGLLoadProgram(sCgCombinedIllumProgram);
370
371                sColorsTexCombinedIllumParam = cgGetNamedParameter(sCgCombinedIllumProgram, "colors"); 
372                sSsaoTexCombinedIllumParam = cgGetNamedParameter(sCgCombinedIllumProgram, "ssaoTex");
373                sIllumTexCombinedIllumParam = cgGetNamedParameter(sCgCombinedIllumProgram, "illumTex");
374        }
375        else
376                cerr << "combined illum program failed to load" << endl;
377
378
379        sCgCombinedSsaoProgram =
380                cgCreateProgramFromFile(context,
381                                                                CG_SOURCE,
382                                                                "src/shaders/ssao.cg",
383                                                                RenderState::sCgFragmentProfile,
384                                                                "combine",
385                                                                NULL);
386
387        if (sCgCombinedSsaoProgram != NULL)
388        {
389                cgGLLoadProgram(sCgCombinedSsaoProgram);
390
391                sColorsTexCombinedSsaoParam = cgGetNamedParameter(sCgCombinedSsaoProgram, "colors"); 
392                sSsaoTexCombinedSsaoParam = cgGetNamedParameter(sCgCombinedSsaoProgram, "ssaoTex");
393        }
394        else
395                cerr << "combied illum program failed to load" << endl;
396
397       
398        sCgAntiAliasingProgram =
399                cgCreateProgramFromFile(context,
400                                                                CG_SOURCE,
401                                                                "src/shaders/antialiasing.cg",
402                                                                RenderState::sCgFragmentProfile,
403                                                                "main",
404                                                                NULL);
405
406        if (sCgAntiAliasingProgram != NULL)
407        {
408                cgGLLoadProgram(sCgAntiAliasingProgram);
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                sImageKeyShadowParam = cgGetNamedParameter(sCgDeferredShadowProgram, "imageKey");
443
444                PoissonDiscSampleGenerator2 poisson(NUM_PCF_TABS, 1.0f);
445                poisson.Generate((float *)pcfSamples);
446
447                cgGLSetParameterArray2f(sSamplesShadowParam, 0, NUM_PCF_TABS, (const float *)pcfSamples);
448        }
449        else
450                cerr << "deferred program failed to load" << endl;
451
452        PrintGLerror("init");
453}
454
455
456void DeferredRenderer::Render(FrameBufferObject *fbo,
457                                                          const Matrix4x4 &oldProjViewMatrix,
458                                                          const Matrix4x4 &projViewMatrix,
459                                                          float tempCohFactor,
460                                                          DirectionalLight *light,
461                                                          ShadowMap *shadowMap)
462{
463        // switch roles of old and new fbo
464        // the algorihm uses two input fbos, where the one
465        // contais the color buffer from the last frame,
466        // the other one will be written
467
468        mFboIndex = 2 - mFboIndex;
469        //swap(mNewFbo, mOldFbo);       
470
471        FrameBufferObject::Release();
472
473        cgGLEnableProfile(RenderState::sCgFragmentProfile);
474
475        glDisable(GL_ALPHA_TEST);
476        glDisable(GL_TEXTURE_2D);
477        glDisable(GL_LIGHTING);
478
479        glPushAttrib(GL_VIEWPORT_BIT);
480        glViewport(0, 0, mWidth, mHeight);
481
482        glMatrixMode(GL_PROJECTION);
483        glPushMatrix();
484        glLoadIdentity();
485
486        const float offs = 0.5f;
487        glOrtho(-offs, offs, -offs, offs, 0, 1);
488
489        glMatrixMode(GL_MODELVIEW);
490        glPushMatrix();
491        glLoadIdentity();
492
493        if (shadowMap)
494                FirstPassShadow(fbo, light, shadowMap);
495        else
496                FirstPass(fbo, light);
497
498        switch (mShadingMethod)
499        {
500        case SSAO:
501                ComputeSsao(fbo, tempCohFactor, oldProjViewMatrix, projViewMatrix);
502                CombineSsao(fbo);
503                break;
504        case GI:
505                ComputeGlobIllum(fbo, tempCohFactor, oldProjViewMatrix);
506                CombineIllum(fbo);
507                break;
508        default: // DEFAULT
509                // do nothing: standard deferred shading
510                break;
511        }
512
513        AntiAliasing(fbo);
514
515        glEnable(GL_LIGHTING);
516        glDisable(GL_TEXTURE_2D);
517
518        glMatrixMode(GL_PROJECTION);
519        glPopMatrix();
520
521        glMatrixMode(GL_MODELVIEW);
522        glPopMatrix();
523
524        glPopAttrib();
525
526        cgGLDisableProfile(RenderState::sCgFragmentProfile);
527}
528
529
530void DeferredRenderer::ComputeSsao(FrameBufferObject *fbo,
531                                                                   float tempCohFactor,
532                                                                   const Matrix4x4 &oldProjViewMatrix,
533                                                                   const Matrix4x4 &projViewMatrix
534                                                                   )
535{
536#ifdef USE_3D_SSAO
537        static Matrix4x4 biasMatrix(0.5f, 0.0f, 0.0f, 0.5f,
538                                                                0.0f, 0.5f, 0.0f, 0.5f,
539                                                                0.0f, 0.0f, 0.5f, 0.5f,
540                                                                0.0f, 0.0f, 0.0f, 1.0f); //bias from [-1, 1] to [0, 1]
541
542        Matrix4x4 m = projViewMatrix * biasMatrix;
543
544        cgGLSetMatrixParameterfc(sModelViewProjMatrixParam, (const float *)m.x);
545#endif
546
547        cgGLSetMatrixParameterfc(sOldModelViewProjMatrixParam, (const float *)oldProjViewMatrix.x);
548
549        GLuint colorsTex = fbo->GetColorBuffer(3)->GetTexture();
550        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
551        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
552
553        if (1)
554        {
555                // generate mip map levels for position texture
556                glBindTexture(GL_TEXTURE_2D, positionsTex);
557                glGenerateMipmapEXT(GL_TEXTURE_2D);
558        }
559
560
561        // read the second buffer, write to the first buffer
562        //mNewFbo->Bind();
563        mFbo->Bind();
564        glDrawBuffers(1, mrt + mFboIndex);
565
566
567        //GLuint oldTex = mOldFbo->GetColorBuffer(0)->GetTexture();
568        GLuint oldTex = mFbo->GetColorBuffer(2 - mFboIndex)->GetTexture();
569
570        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
571
572        cgGLEnableProfile(RenderState::sCgFragmentProfile);
573        cgGLBindProgram(sCgSsaoProgram);
574
575        cgGLSetTextureParameter(sPositionsTexParam, positionsTex);
576        cgGLEnableTextureParameter(sPositionsTexParam);
577
578        cgGLSetTextureParameter(sColorsTexParam, colorsTex);
579        cgGLEnableTextureParameter(sColorsTexParam);
580
581        cgGLSetTextureParameter(sNormalsTexParam, normalsTex);
582        cgGLEnableTextureParameter(sNormalsTexParam);
583
584        cgGLSetTextureParameter(sNoiseTexParam, noiseTex);
585        cgGLEnableTextureParameter(sNoiseTexParam);
586
587        cgGLSetTextureParameter(sOldTexParam, oldTex);
588        cgGLEnableTextureParameter(sOldTexParam);
589       
590        cgGLSetParameter1f(sMaxDepthParam, mScaleFactor);
591       
592        cgGLSetParameter1f(sTemporalCoherenceParam, (mUseTemporalCoherence && !mRegenerateSamples) ? tempCohFactor : 0);
593
594        if (mUseTemporalCoherence || mRegenerateSamples)
595        {
596                mRegenerateSamples = false;
597
598                // q: should we generate new samples or only rotate the old ones?
599                // in the first case, the sample patterns look nicer, but the kernel
600                // needs longer to converge
601                GenerateSamples(mSamplingMethod);
602
603#ifdef USE_3D_SSAO
604                cgGLSetParameterArray3f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples3);
605#else
606                cgGLSetParameterArray2f(sSamplesParam, 0, NUM_SAMPLES, (const float *)samples2);
607#endif
608        }
609
610        Vector3 tl, tr, bl, br;
611        ComputeViewVectors(tl, tr, bl, br);
612
613        glBegin(GL_QUADS);
614
615        // note: slightly larger texture hides ambient occlusion error on border but costs resolution
616        //const float new_offs = 0.55f;
617        const float new_offs = 0.5f;
618       
619        glTexCoord2f(0, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, bl.x, bl.y, bl.z); glVertex3f(-new_offs, -new_offs, -0.5f);
620        glTexCoord2f(1, 0); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, br.x, br.y, br.z); glVertex3f( new_offs, -new_offs, -0.5f);
621        glTexCoord2f(1, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tr.x, tr.y, tr.z); glVertex3f( new_offs,  new_offs, -0.5f);
622        glTexCoord2f(0, 1); glMultiTexCoord3fARB(GL_TEXTURE1_ARB, tl.x, tl.y, tl.z); glVertex3f(-new_offs,  new_offs, -0.5f);
623
624        glEnd();
625
626        cgGLDisableTextureParameter(sColorsTexParam);
627        cgGLDisableTextureParameter(sPositionsTexParam);
628        cgGLDisableTextureParameter(sNormalsTexParam);
629        cgGLDisableTextureParameter(sNoiseTexParam);
630        cgGLDisableTextureParameter(sOldTexParam);
631
632
633        FrameBufferObject::Release();
634
635        PrintGLerror("ssao first pass");
636}
637
638
639void DeferredRenderer::ComputeViewVectors(Vector3 &tl, Vector3 &tr, Vector3 &bl, Vector3 &br)
640{
641        Vector3 ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr;
642
643        mCamera->ComputePoints(ftl, ftr, fbl, fbr, ntl, ntr, nbl, nbr);
644
645        bl = Normalize(nbl - fbl);
646        br = Normalize(nbr - fbr);
647        tl = Normalize(ntl - ftl);
648        tr = Normalize(ntr - ftr);
649}
650
651
652
653static void SetVertex(float x, float y, float x_offs, float y_offs)
654{
655        glMultiTexCoord2fARB(GL_TEXTURE0_ARB, x, y); // center
656        glMultiTexCoord2fARB(GL_TEXTURE1_ARB, x - x_offs, y + y_offs); // left top
657        glMultiTexCoord2fARB(GL_TEXTURE2_ARB, x + x_offs, y - y_offs); // right bottom
658        glMultiTexCoord2fARB(GL_TEXTURE3_ARB, x + x_offs, y + y_offs); // right top
659        glMultiTexCoord2fARB(GL_TEXTURE4_ARB, x - x_offs, y - y_offs); // left bottom
660
661        glMultiTexCoord4fARB(GL_TEXTURE5_ARB, x - x_offs, y, x + x_offs, y); // left right
662        glMultiTexCoord4fARB(GL_TEXTURE6_ARB, x, y + y_offs, x, y - y_offs); // top bottom
663
664        glVertex3f(x - 0.5f, y - 0.5f, -0.5f);
665}
666
667
668void DeferredRenderer::AntiAliasing(FrameBufferObject *fbo)
669{
670        GLuint colorsTex = fbo->GetColorBuffer(colorBufferIdx)->GetTexture();
671        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
672       
673        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
674
675        cgGLEnableProfile(RenderState::sCgFragmentProfile);
676        cgGLBindProgram(sCgAntiAliasingProgram);
677       
678        cgGLSetTextureParameter(sColorsTexAntiAliasingParam, colorsTex);
679        cgGLEnableTextureParameter(sColorsTexAntiAliasingParam);
680
681        cgGLSetTextureParameter(sNormalsTexAntiAliasingParam, normalsTex);
682        cgGLEnableTextureParameter(sNormalsTexAntiAliasingParam);
683
684        glColor3f(1.0f, 1.0f, 1.0f);
685
686        float offs2 = 0.5f;
687
688        glBegin(GL_QUADS);
689
690        // the neighbouring texels
691        float x_offs = 1.0f / mWidth;
692        float y_offs = 1.0f / mHeight;
693
694        SetVertex(0, 0, x_offs, y_offs);
695        SetVertex(1, 0, x_offs, y_offs);
696        SetVertex(1, 1, x_offs, y_offs);
697        SetVertex(0, 1, x_offs, y_offs);
698
699        glEnd();
700
701        cgGLDisableTextureParameter(sColorsTexAntiAliasingParam);
702        cgGLDisableTextureParameter(sNormalsTexAntiAliasingParam);
703
704        PrintGLerror("antialiasing");
705}
706
707
708void DeferredRenderer::FirstPass(FrameBufferObject *fbo, DirectionalLight *light)
709{
710        const float imageKey = ToneMapper().CalcImageKey(fbo->GetColorBuffer(0));
711
712        GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
713        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
714        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
715
716        fbo->Bind();
717
718        colorBufferIdx = 3;
719        glDrawBuffers(1, mrt + colorBufferIdx);
720
721        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
722       
723        cgGLEnableProfile(RenderState::sCgFragmentProfile);
724
725        cgGLBindProgram(sCgDeferredProgram);
726
727        cgGLSetTextureParameter(sColorsTexDeferredParam, colorsTex);
728        cgGLEnableTextureParameter(sColorsTexDeferredParam);
729
730        cgGLSetTextureParameter(sPositionsTexDeferredParam, positionsTex);
731        cgGLEnableTextureParameter(sPositionsTexDeferredParam);
732
733        cgGLSetTextureParameter(sNormalsTexDeferredParam, normalsTex);
734        cgGLEnableTextureParameter(sNormalsTexDeferredParam);
735       
736        Vector3 lightDir = -light->GetDirection();
737        cgGLSetParameter3f(sLightDirParam, lightDir.x, lightDir.y, lightDir.z);
738
739        cgGLSetParameter1f(sImageKeyParam, imageKey);
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        const float imageKey = ToneMapper().CalcImageKey(fbo->GetColorBuffer(0));
981
982        GLuint colorsTex = fbo->GetColorBuffer(0)->GetTexture();
983
984        GLuint positionsTex = fbo->GetColorBuffer(1)->GetTexture();
985        GLuint normalsTex = fbo->GetColorBuffer(2)->GetTexture();
986        GLuint shadowTex = shadowMap->GetDepthTexture();
987
988        Matrix4x4 shadowMatrix;
989        shadowMap->GetTextureMatrix(shadowMatrix);
990
991        fbo->Bind();
992
993        colorBufferIdx = 3;
994        glDrawBuffers(1, mrt + colorBufferIdx);
995
996       
997        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
998
999        cgGLBindProgram(sCgDeferredShadowProgram);
1000
1001        cgGLSetTextureParameter(sColorsTexShadowParam, colorsTex);
1002        cgGLEnableTextureParameter(sColorsTexShadowParam);
1003
1004        cgGLSetTextureParameter(sPositionsTexShadowParam, positionsTex);
1005        cgGLEnableTextureParameter(sPositionsTexShadowParam);
1006
1007        cgGLSetTextureParameter(sNormalsTexShadowParam, normalsTex);
1008        cgGLEnableTextureParameter(sNormalsTexShadowParam);
1009       
1010        cgGLSetTextureParameter(sShadowMapParam, shadowTex);
1011        cgGLEnableTextureParameter(sShadowMapParam);
1012
1013        cgGLSetParameter1f(sMaxDepthShadowParam, mScaleFactor);
1014        //cgGLSetParameter1f(sSampleWidthParam, 10.0f / shadowMap->GetSize());
1015        cgGLSetParameter1f(sSampleWidthParam, 2.0f / shadowMap->GetSize());
1016        //cgGLSetParameter1f(sSampleWidthParam, 2.0f / 2048);
1017         
1018        cgGLSetMatrixParameterfc(sShadowMatrixParam, (const float *)shadowMatrix.x);
1019
1020        cgGLSetTextureParameter(sNoiseTexShadowParam, noiseTex);
1021        cgGLEnableTextureParameter(sNoiseTexShadowParam);
1022
1023        Vector3 lightDir = -light->GetDirection();
1024        cgGLSetParameter3f(sLightDirShadowParam, lightDir.x, lightDir.y, lightDir.z);
1025
1026        // the average log luminance for tone mapping
1027        cgGLSetParameter1f(sImageKeyShadowParam, imageKey);
1028
1029        glColor3f(1.0f, 1.0f, 1.0f);
1030       
1031        glBegin(GL_QUADS);
1032
1033        float offs2 = 0.5f;
1034
1035        glTexCoord2f(0, 0); glVertex3f(-offs2, -offs2, -0.5f);
1036        glTexCoord2f(1, 0); glVertex3f( offs2, -offs2, -0.5f);
1037        glTexCoord2f(1, 1); glVertex3f( offs2,  offs2, -0.5f);
1038        glTexCoord2f(0, 1); glVertex3f(-offs2,  offs2, -0.5f);
1039
1040        glEnd();
1041
1042        cgGLDisableTextureParameter(sColorsTexShadowParam);
1043        cgGLDisableTextureParameter(sPositionsTexShadowParam);
1044        cgGLDisableTextureParameter(sNormalsTexShadowParam);
1045        cgGLDisableTextureParameter(sShadowMapParam);
1046
1047        cgGLDisableTextureParameter(sNoiseTexShadowParam);
1048
1049        FrameBufferObject::Release();
1050
1051        PrintGLerror("deferred shading + shadows");
1052}
1053
1054
1055void DeferredRenderer::SetSamplingMethod(SAMPLING_METHOD s)
1056{
1057        if (s != mSamplingMethod)
1058        {
1059                mSamplingMethod = s;
1060                mRegenerateSamples = true;
1061        }
1062}
1063
1064
1065void DeferredRenderer::SetShadingMethod(SHADING_METHOD s)
1066{
1067        if (s != mShadingMethod)
1068        {
1069                mShadingMethod = s;
1070                mRegenerateSamples = true;
1071        }
1072}
1073
1074
1075
1076
1077
1078} // namespace
Note: See TracBrowser for help on using the repository browser.