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

Revision 2900, 29.9 KB checked in by mattausch, 16 years ago (diff)

changed to real 3d samples which are then projected to texture space

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