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

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