source: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ShadowMapping.cpp @ 3019

Revision 3019, 17.7 KB checked in by mattausch, 16 years ago (diff)

detected memory leaks mainly in shadowmapping!!
strange problems with deferred rendering, seems to be uninitialized sometimes (solved?)

RevLine 
[2891]1#include "ShadowMapping.h"
2#include "FrameBufferObject.h"
3#include "RenderState.h"
4#include "RenderTraverser.h"
5#include "Light.h"
[2911]6#include "Polygon3.h"
7#include "Polyhedron.h"
8
[2891]9#include <IL/il.h>
10#include <assert.h>
11
[2911]12
[2891]13using namespace std;
14
15
16namespace CHCDemoEngine
17{
18
[2931]19static CGprogram sCgShadowProgram;
20static CGparameter sShadowParam;
[2891]21
[2931]22
[2911]23static Polyhedron *polyhedron = NULL;
[2929]24static Polyhedron *lightPoly = NULL;
[2911]25
26
[2891]27static void PrintGLerror(char *msg)
28{
29        GLenum errCode;
30        const GLubyte *errStr;
31       
32        if ((errCode = glGetError()) != GL_NO_ERROR)
33        {
34                errStr = gluErrorString(errCode);
35                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
36        }
37}
38
39
[2936]40static Polyhedron *CreatePolyhedron(const Matrix4x4 &lightMatrix,
41                                                                        const AxisAlignedBox3 &sceneBox)
[2931]42{
43        Frustum frustum(lightMatrix);
[2891]44
[2931]45        vector<Plane3> clipPlanes;
[2891]46
[2931]47        for (int i = 0; i < 6; ++ i)
48        {
49                ////////////
50                //-- normalize the coefficients
[2891]51
[2931]52                // the clipping planes look outward the frustum,
53                // so distances > 0 mean that a point is outside
54                const float invLength = -1.0f / Magnitude(frustum.mClipPlanes[i].mNormal);
55
56                frustum.mClipPlanes[i].mD *= invLength;
57                frustum.mClipPlanes[i].mNormal *= invLength;
58        }
59
[2939]60        // first create near plane because of precision issues
61        clipPlanes.push_back(frustum.mClipPlanes[4]);
62
[2931]63        clipPlanes.push_back(frustum.mClipPlanes[0]);
64        clipPlanes.push_back(frustum.mClipPlanes[1]);
65        clipPlanes.push_back(frustum.mClipPlanes[2]);
66        clipPlanes.push_back(frustum.mClipPlanes[3]);
[2936]67        clipPlanes.push_back(frustum.mClipPlanes[5]);
68
[2931]69        return Polyhedron::CreatePolyhedron(clipPlanes, sceneBox);
70}
71
72
[2891]73static void GrabDepthBuffer(float *data, GLuint depthTexture)
74{
75        glEnable(GL_TEXTURE_2D);
76        glBindTexture(GL_TEXTURE_2D, depthTexture);
77
78        glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data);
79
80        glBindTexture(GL_TEXTURE_2D, 0);
81        glDisable(GL_TEXTURE_2D);
82}
83
84
85static void ExportDepthBuffer(float *data, int size)
86{
87        ilInit();
88        assert(ilGetError() == IL_NO_ERROR);
89
90        ILstring filename = ILstring("shadow.tga");
91        ilRegisterType(IL_FLOAT);
92
93        const int depth = 1;
94        const int bpp = 1;
95
96        if (!ilTexImage(size, size, depth, bpp, IL_LUMINANCE, IL_FLOAT, data))
97        {
98                cerr << "IL error " << ilGetError() << endl;
99       
100                ilShutDown();
101                assert(ilGetError() == IL_NO_ERROR);
102
103                return;
104        }
105
106        if (!ilSaveImage(filename))
107        {
108                cerr << "TGA write error " << ilGetError() << endl;
109        }
110
111        ilShutDown();
112        assert(ilGetError() == IL_NO_ERROR);
113
114        cout << "exported depth buffer" << endl;
115}
116
117
118
[2924]119static AxisAlignedBox3 GetExtremalPoints(const Matrix4x4 &m,
120                                                                                 const VertexArray &pts)
121{
122        AxisAlignedBox3 extremalPoints;
123        extremalPoints.Initialize();
124
125        VertexArray::const_iterator it, it_end = pts.end();
126               
127        for (it = pts.begin(); it != it_end; ++ it)
128        {
129                Vector3 pt = *it;
130                pt = m * pt;
131
132                extremalPoints.Include(pt);
133        }
134
135        return extremalPoints;
136}
137
138
[3011]139ShadowMap::ShadowMap(DirectionalLight *light
140                                         , int size,
141                                         const AxisAlignedBox3 &sceneBox,
142                                         Camera *cam):
[2897]143mSceneBox(sceneBox), mSize(size), mCamera(cam), mLight(light)
[2891]144{
145        mFbo = new FrameBufferObject(size, size, FrameBufferObject::DEPTH_32, true);
[2965]146
[2947]147        // need a color buffer to keep opengl happy
[3011]148        mFbo->AddColorBuffer(ColorBufferObject::RGB_UBYTE,
[2965]149                                 ColorBufferObject::WRAP_CLAMP_TO_EDGE,
150                                                 ColorBufferObject::FILTER_NEAREST);
[2891]151
[2965]152
[2947]153        mShadowCam = new Camera(mSize, mSize);
[2891]154        mShadowCam->SetOrtho(true);
155}
156
157
[2894]158ShadowMap::~ShadowMap()
[2891]159{
160        DEL_PTR(mFbo);
[2897]161        DEL_PTR(mShadowCam);
[3019]162
163        DEL_PTR(lightPoly);
164        DEL_PTR(polyhedron);
[2891]165}
166
167
[2963]168static void DrawPolyhedron(Polyhedron *poly, const Vector3 &color)
[2891]169{
[2929]170        if (!poly) return;
[2911]171
[2929]172        for (size_t i = 0; i < poly->NumPolygons(); ++ i)
[2911]173        {
[2929]174                glColor3f(color.x, color.y, color.z);
[2911]175
176                glBegin(GL_LINE_LOOP);
177
[2929]178                Polygon3 *p = poly->GetPolygons()[i];
[2911]179
[2929]180                for (size_t j = 0; j < p->mVertices.size(); ++ j)
[2911]181                {
[2929]182                        Vector3 v = p->mVertices[j];
[2911]183                        glVertex3d(v.x, v.y, v.z);
184                }
185
186                glEnd();
187        }
188}
189
190
[2963]191void ShadowMap::VisualizeFrustra()
[2911]192{
[2963]193        DrawPolyhedron(lightPoly, Vector3(1, 0, 1));
194        DrawPolyhedron(polyhedron, Vector3(0, 1, 0));
[2913]195}
[2911]196
[2913]197
[2944]198// z0 is the point that lies on the parallel plane to the near plane through e (A)
199//and on the near plane of the C frustum (the plane z = bZmax) and on the line x = e.x
200Vector3 ShadowMap::GetLightSpaceZ0(const Matrix4x4 &lightSpace,
201                                                                   const Vector3 &e,
202                                                                   const float maxZ,
203                                                                   const Vector3 &eyeDir) const
204{
205        // to calculate the parallel plane to the near plane through e we
206        // calculate the plane A with the three points
207        Plane3 planeA(e, eyeDir);
208
209        planeA.Transform(lightSpace);
210       
211        // get the parameters of A from the plane equation n dot d = 0
212        const float d = planeA.mD;
213        const Vector3 n = planeA.mNormal;
214       
215        // transform to light space
216        const Vector3 e_ls = lightSpace * e;
217
218        Vector3 z0;
219
220        z0.x = e_ls.x;
221        z0.y = (d - n.z * maxZ - n.x * e_ls.x) / n.y;
222        z0.z = maxZ;
223
224        return z0;
225        //return V3(e_ls.x(),(d-n.z()*b_lsZmax-n.x()*e_ls.x())/n.y(),b_lsZmax);
226}
227
228
229float ShadowMap::ComputeNOpt(const Matrix4x4 &lightSpace,
230                                                         const AxisAlignedBox3 &extremalPoints,
231                                                         const VertexArray &body) const
232{
233        const Vector3 nearPt = GetNearCameraPointE(body);
234        const Vector3 eyeDir = mCamera->GetDirection();
235
236        Matrix4x4 eyeView;
237        mCamera->GetModelViewMatrix(eyeView);
238
239        const Matrix4x4 invLightSpace = Invert(lightSpace);
240
241        const Vector3 z0_ls = GetLightSpaceZ0(lightSpace, nearPt, extremalPoints.Max().z, eyeDir);
242        const Vector3 z1_ls = Vector3(z0_ls.x, z0_ls.y, extremalPoints.Min().z);
243       
244        // transform back to world space
245        const Vector3 z0_ws = invLightSpace * z0_ls;
246        const Vector3 z1_ws = invLightSpace * z1_ls;
247
248        // transform to eye space
249        const Vector3 z0_es = eyeView * z0_ws;
250        const Vector3 z1_es = eyeView * z1_ws;
251
252        const float z0 = z0_es.z;
253        const float z1 = z1_es.z;
254
255        cout << "z0 ls: " << z0_ls << " z1 ls: " << z1_ls << endl;
256        cout << "z0: " << z0_es << " z1: " << z1_es << endl;
257
258        const float d = fabs(extremalPoints.Max()[2] - extremalPoints.Min()[2]);
259
260        const float n = d / (sqrt(z1 / z0) - 1.0f);
261
262        return n;
263}
264
265
[2920]266float ShadowMap::ComputeN(const AxisAlignedBox3 &extremalPoints) const
[2913]267{
[2944]268        const float nearPlane = mCamera->GetNear();
[2916]269       
[2920]270        const float d = fabs(extremalPoints.Max()[2] - extremalPoints.Min()[2]);
271       
[2916]272        const float dotProd = DotProd(mCamera->GetDirection(), mShadowCam->GetDirection());
273        const float sinGamma = sin(fabs(acos(dotProd)));
274
[2944]275        // test for values close to zero
276        if (sinGamma < 1e-6f) return 1e6f;
277       
[2954]278        const float scale = 2.0f;
279        return scale * (nearPlane + sqrt(nearPlane * (nearPlane + d * sinGamma))) /  sinGamma;
[2916]280}
281
282
[2924]283Matrix4x4 ShadowMap::CalcLispSMTransform(const Matrix4x4 &lightSpace,
[2920]284                                                                                 const AxisAlignedBox3 &extremalPoints,
[2924]285                                                                                 const VertexArray &body
[2920]286                                                                                 )
[2917]287{
[2928]288        AxisAlignedBox3 bounds_ls = GetExtremalPoints(lightSpace, body);
289
[2913]290        ///////////////
[2915]291        //-- We apply the lispsm algorithm in order to calculate an optimal light projection matrix
[2924]292        //-- first find the free parameter values n, and P (the projection center), and the projection depth
293
[2945]294        const float n = ComputeN(bounds_ls);
295        //const float n = ComputeNOpt(lightSpace, extremalPoints, body); cout << "n: " << n << endl;
[2924]296
[2944]297        if (n >= 1e6f) // light direction nearly parallel to view => switch to uniform
298                return IdentityMatrix();
299
[2924]300        const Vector3 nearPt = GetNearCameraPointE(body);
[2933]301       
[2915]302        //get the coordinates of the near camera point in light space
[2924]303        const Vector3 lsNear = lightSpace * nearPt;
[2915]304
[2939]305        // the start point has the x and y coordinate of e, the z coord of the near plane of the light volume
[2924]306        const Vector3 startPt = Vector3(lsNear.x, lsNear.y, bounds_ls.Max().z);
[2943]307       
[2915]308        // the new projection center
[2936]309        const Vector3 projCenter = startPt + Vector3::UNIT_Z() * n;
[2915]310
311        //construct a translation that moves to the projection center
312        const Matrix4x4 projectionCenter = TranslationMatrix(-projCenter);
313
[2916]314        // light space y size
[2933]315        const float d = fabs(bounds_ls.Max()[2] - bounds_ls.Min()[2]);
[2922]316
[2924]317        const float dy = fabs(bounds_ls.Max()[1] - bounds_ls.Min()[1]);
318        const float dx = fabs(bounds_ls.Max()[0] - bounds_ls.Min()[0]);
[2922]319
[2924]320       
[2915]321
[2928]322        //////////
[2924]323        //-- now apply these values to construct the perspective lispsm matrix
324
325        Matrix4x4 matLispSM;
326       
[2939]327        matLispSM = GetFrustum(-1.0, 1.0, -1.0, 1.0, n, n + d);
[2924]328
329        // translate to the projection center
[2920]330        matLispSM = projectionCenter * matLispSM;
[2915]331
332        // transform into OpenGL right handed system
[2920]333        Matrix4x4 refl = ScaleMatrix(1.0f, 1.0f, -1.0f);
334        matLispSM *= refl;
[2924]335       
[2920]336        return matLispSM;
[2915]337}
338
[2925]339#if 0
340Vector3 ShadowMap::GetNearCameraPointE(const VertexArray &pts) const
341{
342        float maxDist = -1e25f;
343        Vector3 nearest = Vector3::ZERO();
[2915]344
[2925]345        Matrix4x4 eyeView;
346        mCamera->GetModelViewMatrix(eyeView);
347
348        VertexArray newPts;
349        polyhedron->CollectVertices(newPts);
350       
351        //the LVS volume is always in front of the camera
352        VertexArray::const_iterator it, it_end = pts.end();     
353
354        for (it = pts.begin(); it != it_end; ++ it)
355        {
356                Vector3 pt = *it;
357                Vector3 ptE = eyeView * pt;
[2943]358               
[2925]359                if (ptE.z > 0) cerr <<"should not happen " << ptE.z << endl;
360                else
361                if (ptE.z > maxDist)
362                {
363                        cout << " d " << ptE.z;
364       
365                        maxDist = ptE.z;
366                        nearest = pt;
367                }
368        }
369
[2933]370        //      return Invert(eyeView) * nearest;
[2925]371        return nearest;
372}
373
374#else
375
[2920]376Vector3 ShadowMap::GetNearCameraPointE(const VertexArray &pts) const
[2919]377{
[2925]378        VertexArray newPts;
379        polyhedron->CollectVertices(newPts);
380
[2922]381        Vector3 nearest = Vector3::ZERO();
382        float minDist = 1e25f;
[2920]383
[2924]384        const Vector3 camPos = mCamera->GetPosition();
[2920]385
[2925]386        VertexArray::const_iterator it, it_end = newPts.end();
[2920]387
[2925]388        for (it = newPts.begin(); it != it_end; ++ it)
[2920]389        {
390                Vector3 pt = *it;
391
392                const float dist = SqrDistance(pt, camPos);
393
394                if (dist < minDist)
395                {
396                        minDist = dist;
397                        nearest = pt;
398                }
399        }
400
401        return nearest;
402}
403
[2925]404#endif
[2920]405
[2933]406Vector3 ShadowMap::GetProjViewDir(const Matrix4x4 &lightSpace,
407                                                                  const VertexArray &pts) const
[2920]408{
[2919]409        //get the point in the LVS volume that is nearest to the camera
[2920]410        const Vector3 e = GetNearCameraPointE(pts);
411
[2919]412        //construct edge to transform into light-space
[2920]413        const Vector3 b = e + mCamera->GetDirection();
[2919]414        //transform to light-space
[2920]415        const Vector3 e_lp = lightSpace * e;
416        const Vector3 b_lp = lightSpace * b;
417
418        Vector3 projDir(b_lp - e_lp);
419
[2919]420        //project the view direction into the shadow map plane
[2932]421        projDir.y = .0f;
[2920]422
423        return Normalize(projDir);
[2919]424}
425
426
[2915]427bool ShadowMap::CalcLightProjection(Matrix4x4 &lightProj)
428{
429        ///////////////////
430        //-- First step: calc frustum clipped by scene box
431
[2922]432        DEL_PTR(polyhedron);
[2915]433        polyhedron = CalcClippedFrustum(mSceneBox);
434
435        if (!polyhedron) return false; // something is wrong
436
437        // include the part of the light volume that "sees" the frustum
438        // we only require frustum vertices
439
440        VertexArray frustumPoints;
[2939]441        IncludeLightVolume(*polyhedron, frustumPoints, mLight->GetDirection(), mSceneBox);
[2915]442
443
444        ///////////////
445        //-- transform points from world view to light view and calculate extremal points
446
447        Matrix4x4 lightView;
448        mShadowCam->GetModelViewMatrix(lightView);
449
[2920]450        const AxisAlignedBox3 extremalPoints = GetExtremalPoints(lightView, frustumPoints);
[2913]451
[2920]452        // we use directional lights, so the projection can be set to identity
453        lightProj = IdentityMatrix();
[2913]454
[2922]455        // switch coordinate system to that used in the lispsm algorithm for calculations
456        Matrix4x4 transform2LispSM = ZeroMatrix();
457
458        transform2LispSM.x[0][0] =  1.0f;
[2934]459        transform2LispSM.x[1][2] =  -1.0f; // y => -z
[2924]460        transform2LispSM.x[2][1] =  1.0f; // z => y
[2922]461        transform2LispSM.x[3][3] =  1.0f;
462
[2936]463
[2922]464        //switch to the lightspace used in the article
[2936]465        lightProj *= transform2LispSM;
[2922]466
[2924]467        const Vector3 projViewDir = GetProjViewDir(lightView * lightProj, frustumPoints);
[2916]468
[2952]469        //do DirectionalLight Space Perspective shadow mapping
[2922]470        //rotate the lightspace so that the projected light view always points upwards
471        //calculate a frame matrix that uses the projViewDir[lightspace] as up vector
[2917]472        //look(from position, into the direction of the projected direction, with unchanged up-vector)
[2938]473        //const Matrix4x4 frame = MyLookAt2(Vector3::ZERO(), projViewDir, Vector3::UNIT_Y());
[2944]474        const Matrix4x4 frame = LookAt(Vector3::ZERO(), projViewDir, Vector3::UNIT_Y());
[2917]475
[2936]476        lightProj *= frame;
[2924]477
[2917]478        const Matrix4x4 matLispSM =
[2920]479                CalcLispSMTransform(lightView * lightProj, extremalPoints, frustumPoints);
[2917]480
[2936]481        lightProj *= matLispSM;
[2917]482
[2922]483        // change back to GL coordinate system
484        Matrix4x4 transformToGL = ZeroMatrix();
485       
[2940]486        transformToGL.x[0][0] =   1.0f;
487        transformToGL.x[1][2] =   1.0f; // z => y
[2934]488        transformToGL.x[2][1] =  -1.0f; // y => -z
[2940]489        transformToGL.x[3][3] =   1.0f;
[2922]490
[2936]491        lightProj *= transformToGL;
[2922]492
[2920]493        AxisAlignedBox3 lightPts = GetExtremalPoints(lightView * lightProj, frustumPoints);
494
[2917]495        // focus projection matrix on the extremal points => scale to unit cube
[2922]496        Matrix4x4 scaleTranslate = GetFittingProjectionMatrix(lightPts);
[2917]497
[2939]498        lightProj = lightProj * scaleTranslate;
499
500        Matrix4x4 mymat = lightView * lightProj;
501
502        AxisAlignedBox3 lightPtsNew = GetExtremalPoints(mymat, frustumPoints);
503
[2920]504        // we have to flip the signs in order to tranform to opengl right handed system
505        Matrix4x4 refl = ScaleMatrix(1, 1, -1);
506        lightProj *= refl;
[2916]507       
[2913]508        return true;
[2911]509}
510
511
[2913]512Polyhedron *ShadowMap::CalcClippedFrustum(const AxisAlignedBox3 &box) const
513{
[2931]514        Polyhedron *p = mCamera->ComputeFrustum();
515       
516        Polyhedron *clippedPolyhedron = box.CalcIntersection(*p);
[2913]517
[2931]518        DEL_PTR(p);
[2913]519       
[2931]520        return clippedPolyhedron;
521}
[2913]522
523
[2931]524//calculates the up vector for the light coordinate frame
525static Vector3 CalcUpVec(const Vector3 viewDir, const Vector3 lightDir)
526{
527        //we do what gluLookAt does...
528        //left is the normalized vector perpendicular to lightDir and viewDir
529        //this means left is the normalvector of the yz-plane from the paper
530        Vector3 left = CrossProd(lightDir, viewDir);
[2913]531       
[2931]532        //we now can calculate the rotated(in the yz-plane) viewDir vector
533        //and use it as up vector in further transformations
534        Vector3 up = CrossProd(left, lightDir);
[2913]535
[2931]536        return Normalize(up);
[2913]537}
538
539
[2932]540void ShadowMap::GetTextureMatrix(Matrix4x4 &m) const
541{
542        m = mTextureMatrix;
543}
544
545 
546unsigned int ShadowMap::GetDepthTexture() const
547{
548        return mFbo->GetDepthTex();
549}
550
551unsigned int ShadowMap::GetShadowColorTexture() const
552{
553        return mFbo->GetColorBuffer(0)->GetTexture();
554       
555}
556
557
558void ShadowMap::IncludeLightVolume(const Polyhedron &polyhedron,
559                                                                   VertexArray &frustumPoints,
560                                                                   const Vector3 lightDir,
561                                                                   const AxisAlignedBox3 &sceneBox
562                                                                   )
563{
564        // we don't need closed form anymore => just store vertices
565        VertexArray vertices;
566        polyhedron.CollectVertices(vertices);
567
568        // we 'look' at each point and calculate intersections of rays with scene bounding box
569        VertexArray::const_iterator it, it_end = vertices.end();
570
571        for (it = vertices.begin(); it != it_end; ++ it)
572        {
573                Vector3 v  = *it;
574
575                frustumPoints.push_back(v);
576               
[2939]577                // hack: start at point which is guaranteed to be outside of box
[2932]578                v -= Magnitude(mSceneBox.Diagonal()) * lightDir;
579
580                SimpleRay ray(v, lightDir);
581
582                float tNear, tFar;
583
584                if (sceneBox.Intersects(ray, tNear, tFar))
585                {
586                        Vector3 newpt = ray.Extrap(tNear);
587                        frustumPoints.push_back(newpt);                 
588                }
589        }
590}
591
592
[2911]593void ShadowMap::ComputeShadowMap(RenderTraverser *renderer, const Matrix4x4 &projView)
594{
[2891]595        mFbo->Bind();
[2892]596       
[2891]597        glDrawBuffers(1, mrt);
598
599        glPushAttrib(GL_VIEWPORT_BIT);
600        glViewport(0, 0, mSize, mSize);
601
602        glDisable(GL_LIGHTING);
603        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
604
605        glShadeModel(GL_FLAT);
606
607
[2942]608        /////////////
609        //-- render scene into shadow map
[2894]610
[2942]611        _Render(renderer);
[2911]612
[2939]613
[2913]614        //////////////
615        //-- compute texture matrix
[2925]616
[2894]617        static Matrix4x4 biasMatrix(0.5f, 0.0f, 0.0f, 0.5f,
618                                                                0.0f, 0.5f, 0.0f, 0.5f,
619                                                                0.0f, 0.0f, 0.5f, 0.5f,
[2911]620                                                                0.0f, 0.0f, 0.0f, 1.0f);
[2894]621
[2911]622        mTextureMatrix = mLightProjView * biasMatrix;
[2894]623
[2891]624        glPopAttrib();
[2928]625       
[2943]626        glShadeModel(GL_SMOOTH);
[2928]627        glEnable(GL_LIGHTING);
628        glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
629
[2913]630#if 0
[2911]631        float *data = new float[mSize * mSize];
[2891]632
633        GrabDepthBuffer(data, mFbo->GetDepthTex());
634        ExportDepthBuffer(data, mSize);
635
[2892]636        delete [] data;
[2911]637       
[2892]638        PrintGLerror("shadow map");
[2913]639#endif
[2942]640       
[2891]641        FrameBufferObject::Release();
642}
643
644
[2931]645void ShadowMap::RenderShadowView(RenderTraverser *renderer, const Matrix4x4 &projView)
646{
[2942]647        glEnable(GL_LIGHTING);
[2943]648       
[2942]649        _Render(renderer);
650       
[2943]651        /*glDisable(GL_LIGHTING);
652        glDisable(GL_DEPTH_TEST);
653
654        Polyhedron *hpoly = CreatePolyhedron(projView, mSceneBox);
655        DrawPoly(hpoly, Vector3(1, 1, 1));
656        DEL_PTR(hpoly);
657
658        glEnable(GL_LIGHTING);
659        glEnable(GL_DEPTH_TEST);*/
660
[2942]661        glDisable(GL_POLYGON_OFFSET_FILL);
662}
663
664
665void ShadowMap::_Render(RenderTraverser *renderer)
666{
[2939]667        const Vector3 dir = mLight->GetDirection();
[2931]668
669        mShadowCam->SetDirection(dir);
670
671        // set position so that we can see the whole scene
672        Vector3 pos = mSceneBox.Center();
673        pos -= dir * Magnitude(mSceneBox.Diagonal() * 0.5f);
674
[2932]675        mShadowCam->SetPosition(mCamera->GetPosition());
676
677        Vector3 upVec = CalcUpVec(mCamera->GetDirection(), dir);
[2944]678        Matrix4x4 lightView = LookAt(mShadowCam->GetPosition(), dir, upVec);
[2932]679
680        mShadowCam->mViewOrientation = lightView;
681
[2931]682        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
683
[2944]684        glPolygonOffset(5.0f, 100.0f);
[2931]685        glEnable(GL_POLYGON_OFFSET_FILL);
[2932]686       
687        Matrix4x4 lightProj;
[2931]688        CalcLightProjection(lightProj);
689
690        glMatrixMode(GL_PROJECTION);
691        glPushMatrix();
692        glLoadMatrixf((float *)lightProj.x);
693
694        mLightProjView = lightView * lightProj;
[2932]695
[2931]696        DEL_PTR(lightPoly);
697        lightPoly = CreatePolyhedron(mLightProjView, mSceneBox);
698
699        glMatrixMode(GL_MODELVIEW);
700        glPushMatrix();
[2951]701       
[2932]702        mShadowCam->SetupCameraView();
[2931]703
[2942]704       
[2931]705        /////////////
706        //-- render scene into shadow map
707
708        renderer->RenderScene();
709
[2943]710
[2931]711        glMatrixMode(GL_PROJECTION);
712        glPopMatrix();
713
[2951]714        glMatrixMode(GL_MODELVIEW);
715        glPopMatrix();
716
[2931]717       
[2942]718        glDisable(GL_POLYGON_OFFSET_FILL);
[2931]719}
[2891]720} // namespace
Note: See TracBrowser for help on using the repository browser.