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

Revision 2879, 21.2 KB checked in by mattausch, 16 years ago (diff)

improved performance

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