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

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