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

Revision 2939, 19.7 KB checked in by mattausch, 16 years ago (diff)

lispsm working for standard case (light dir perpendicular to scene), but not even uniform working for all other cases

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