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

Revision 2966, 31.5 KB checked in by mattausch, 16 years ago (diff)

started reinhard tonemapping implementation but slow

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