source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SsaoShader.cpp @ 2894

Revision 2894, 26.8 KB checked in by mattausch, 16 years ago (diff)

shadow mapping almost working (but ulgy!!)

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