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

Revision 2911, 6.5 KB checked in by mattausch, 16 years ago (diff)
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
19
20static Polyhedron *polyhedron = NULL;
21
22
23static void PrintGLerror(char *msg)
24{
25        GLenum errCode;
26        const GLubyte *errStr;
27       
28        if ((errCode = glGetError()) != GL_NO_ERROR)
29        {
30                errStr = gluErrorString(errCode);
31                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
32        }
33}
34
35
36
37static CGprogram sCgShadowProgram;
38static CGparameter sShadowParam;
39
40
41static void GrabDepthBuffer(float *data, GLuint depthTexture)
42{
43        glEnable(GL_TEXTURE_2D);
44        glBindTexture(GL_TEXTURE_2D, depthTexture);
45
46        glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data);
47
48        glBindTexture(GL_TEXTURE_2D, 0);
49        glDisable(GL_TEXTURE_2D);
50}
51
52
53static void ExportDepthBuffer(float *data, int size)
54{
55        ilInit();
56        assert(ilGetError() == IL_NO_ERROR);
57
58        ILstring filename = ILstring("shadow.tga");
59        ilRegisterType(IL_FLOAT);
60
61        const int depth = 1;
62        const int bpp = 1;
63
64        if (!ilTexImage(size, size, depth, bpp, IL_LUMINANCE, IL_FLOAT, data))
65        {
66                cerr << "IL error " << ilGetError() << endl;
67       
68                ilShutDown();
69                assert(ilGetError() == IL_NO_ERROR);
70
71                return;
72        }
73
74        if (!ilSaveImage(filename))
75        {
76                cerr << "TGA write error " << ilGetError() << endl;
77        }
78
79        ilShutDown();
80        assert(ilGetError() == IL_NO_ERROR);
81
82        cout << "exported depth buffer" << endl;
83}
84
85
86
87ShadowMap::ShadowMap(Light *light, int size, const AxisAlignedBox3 &sceneBox, Camera *cam):
88mSceneBox(sceneBox), mSize(size), mCamera(cam), mLight(light)
89{
90        mFbo = new FrameBufferObject(size, size, FrameBufferObject::DEPTH_32, true);
91        // the diffuse color buffer
92        mFbo->AddColorBuffer(ColorBufferObject::BUFFER_UBYTE, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, false);
93
94        mShadowCam = new Camera(mSceneBox.Size().x * 0.5f, mSceneBox.Size().y * 0.5f);
95        mShadowCam->SetOrtho(true);
96}
97
98
99ShadowMap::~ShadowMap()
100{
101        DEL_PTR(mFbo);
102        DEL_PTR(mShadowCam);
103}
104
105
106void ShadowMap::DrawPolys()
107{
108        if (!polyhedron) return;
109
110        cout << "here3" << endl;
111
112        for (size_t i = 0; i < polyhedron->NumPolygons(); ++ i)
113        {
114                float r = (float)i / polyhedron->NumPolygons();
115                float g = 1;
116                float b = 1;
117
118                glColor3f(r, g, b);
119
120                glBegin(GL_LINE_LOOP);
121
122                Polygon3 *poly = polyhedron->GetPolygons()[i];
123
124                for (size_t j = 0; j < poly->mVertices.size(); ++ j)
125                {
126                        Vector3 v = poly->mVertices[j];
127                        glVertex3d(v.x, v.y, v.z);
128                }
129
130                glEnd();
131        }
132}
133
134
135void ShadowMap::CalcFocussedFrustum(const Matrix4x4 &camProjView,
136                                                                        const Matrix4x4 &lightProjView,
137                                                                        Matrix4x4 &focussed)
138{
139        ///////////////////
140        //-- First step: calc clipped frustum
141
142        DEL_PTR(polyhedron);
143        polyhedron = mCamera->CalcClippedFrustum(mSceneBox);
144
145        if (polyhedron)
146        {
147                // second step: focus light frustum on clipped frustum
148                Frustum lightFrustum(lightProjView);
149
150                for (int i = 0; i < 6; ++ i)
151                {
152                        // the clipping planes look outward the frustum,
153                        // so distances > 0 mean that a point is outside
154                        const float invLength = 1.0f / Magnitude(lightFrustum.mClipPlanes[i].mNormal);
155
156                        lightFrustum.mClipPlanes[i].mD *= invLength;
157                        lightFrustum.mClipPlanes[i].mNormal *= invLength;
158                }
159
160                //lightFrustum.EnclosePolyhedron(*polyhedron);
161                lightFrustum.ExtractTransformation(focussed);
162        }
163}
164
165
166void ShadowMap::ComputeShadowMap(RenderTraverser *renderer, const Matrix4x4 &projView)
167{
168        const float xlen = Magnitude(mSceneBox.Diagonal() * 0.5f);
169        const float ylen = Magnitude(mSceneBox.Diagonal() * 0.5f);
170       
171        mShadowCam->SetDirection(mLight->GetDirection());
172       
173        // set position so that we can see the whole scene
174        Vector3 pos = mSceneBox.Center();
175
176        Matrix4x4 camView;
177        mCamera->GetModelViewMatrix(camView);
178
179        pos -= mLight->GetDirection() * Magnitude(mSceneBox.Diagonal() * 0.5f);
180        //mShadowCam->SetPosition(pos);
181
182        mFbo->Bind();
183       
184        glDrawBuffers(1, mrt);
185
186        glPushAttrib(GL_VIEWPORT_BIT);
187        glViewport(0, 0, mSize, mSize);
188
189        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
190
191        glDisable(GL_LIGHTING);
192        glDisable(GL_TEXTURE_2D);
193        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
194
195        glPolygonOffset(1.0f, 2000.0f);
196        glEnable(GL_POLYGON_OFFSET_FILL);
197
198        glShadeModel(GL_FLAT);
199        glEnable(GL_DEPTH_TEST);
200
201        glMatrixMode(GL_PROJECTION);
202        glPushMatrix();
203        glLoadIdentity();
204       
205        // setup projection
206        glOrtho(+xlen, -xlen, +ylen, -ylen, 0.0f, Magnitude(mSceneBox.Diagonal()));
207       
208
209        glMatrixMode(GL_MODELVIEW);
210        glPushMatrix();
211        glLoadIdentity();
212
213        // setup shadow camera
214        mShadowCam->SetupCameraView();
215
216
217        //////////////
218        //-- compute texture matrix
219
220        Matrix4x4 lightView, lightProj;
221
222        mShadowCam->GetModelViewMatrix(lightView);
223        mShadowCam->GetProjectionMatrix(lightProj);
224
225        Matrix4x4 oldLightProjView = lightView * lightProj;
226        Matrix4x4 newLightProj;
227
228        CalcFocussedFrustum(projView, lightProj, newLightProj);
229        //CalcFocussedFrustum(projView, oldLightProjView, newLightProj);
230
231        Matrix4x4 dummyMat;
232        glGetFloatv(GL_PROJECTION_MATRIX, (float *)dummyMat.x);
233
234
235        cout << "old:\n" << dummyMat << endl;
236
237
238        glMatrixMode(GL_PROJECTION);
239        glLoadMatrixf((float *)newLightProj.x);
240       
241        glMatrixMode(GL_MODELVIEW);
242        //glLoadIdentity();
243
244        Matrix4x4 dummyMat3;
245        glGetFloatv(GL_PROJECTION_MATRIX, (float *)dummyMat3.x);
246
247        cout << "new:\n" << newLightProj << endl;
248
249        lightView = camView;
250        mLightProjView = lightView * newLightProj;
251        //mLightProjView = newLightProj;
252
253        //cout << "old: \n" << oldLightProjView << " new: \n " << mLightProjView << endl;
254       
255
256        static Matrix4x4 biasMatrix(0.5f, 0.0f, 0.0f, 0.5f,
257                                                                0.0f, 0.5f, 0.0f, 0.5f,
258                                                                0.0f, 0.0f, 0.5f, 0.5f,
259                                                                0.0f, 0.0f, 0.0f, 1.0f);
260
261        mTextureMatrix = mLightProjView * biasMatrix;
262        //mTextureMatrix = oldLightProjView * biasMatrix;
263
264
265
266
267        /////////////
268        //-- render scene into shadow map
269
270        renderer->RenderScene();
271
272       
273        glDisable(GL_POLYGON_OFFSET_FILL);
274        glMatrixMode(GL_MODELVIEW);
275        glPopMatrix();
276
277        glMatrixMode(GL_PROJECTION);
278        glPopMatrix();
279
280        glPopAttrib();
281        /*
282        float *data = new float[mSize * mSize];
283
284        GrabDepthBuffer(data, mFbo->GetDepthTex());
285        ExportDepthBuffer(data, mSize);
286
287        delete [] data;
288       
289        PrintGLerror("shadow map");
290*/
291        FrameBufferObject::Release();
292}
293
294
295void ShadowMap::GetTextureMatrix(Matrix4x4 &m) const
296{
297        m = mTextureMatrix;
298}
299
300 
301unsigned int ShadowMap::GetShadowTexture() const
302{
303        return mFbo->GetDepthTex();
304}
305
306
307} // namespace
Note: See TracBrowser for help on using the repository browser.