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

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