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

Revision 2936, 19.5 KB checked in by mattausch, 16 years ago (diff)

totally broken

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