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

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