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

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