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

Revision 2897, 30.4 KB checked in by mattausch, 16 years ago (diff)

improved shadow mapping

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