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

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