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

Revision 2899, 4.3 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 <IL/il.h>
7#include <assert.h>
8
9using namespace std;
10
11
12namespace CHCDemoEngine
13{
14
15
16static void PrintGLerror(char *msg)
17{
18        GLenum errCode;
19        const GLubyte *errStr;
20       
21        if ((errCode = glGetError()) != GL_NO_ERROR)
22        {
23                errStr = gluErrorString(errCode);
24                fprintf(stderr,"OpenGL ERROR: %s: %s\n", errStr, msg);
25        }
26}
27
28
29
30static CGprogram sCgShadowProgram;
31static CGparameter sShadowParam;
32
33
34static void GrabDepthBuffer(float *data, GLuint depthTexture)
35{
36        glEnable(GL_TEXTURE_2D);
37        glBindTexture(GL_TEXTURE_2D, depthTexture);
38
39        glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data);
40
41        glBindTexture(GL_TEXTURE_2D, 0);
42        glDisable(GL_TEXTURE_2D);
43}
44
45
46static void ExportDepthBuffer(float *data, int size)
47{
48        ilInit();
49        assert(ilGetError() == IL_NO_ERROR);
50
51        ILstring filename = ILstring("shadow.tga");
52        ilRegisterType(IL_FLOAT);
53
54        const int depth = 1;
55        const int bpp = 1;
56
57        if (!ilTexImage(size, size, depth, bpp, IL_LUMINANCE, IL_FLOAT, data))
58        {
59                cerr << "IL error " << ilGetError() << endl;
60       
61                ilShutDown();
62                assert(ilGetError() == IL_NO_ERROR);
63
64                return;
65        }
66
67        if (!ilSaveImage(filename))
68        {
69                cerr << "TGA write error " << ilGetError() << endl;
70        }
71
72        ilShutDown();
73        assert(ilGetError() == IL_NO_ERROR);
74
75        cout << "exported depth buffer" << endl;
76}
77
78
79
80ShadowMap::ShadowMap(Light *light, int size, const AxisAlignedBox3 &sceneBox, Camera *cam):
81mSceneBox(sceneBox), mSize(size), mCamera(cam), mLight(light)
82{
83        mFbo = new FrameBufferObject(size, size, FrameBufferObject::DEPTH_32, true);
84        // the diffuse color buffer
85        mFbo->AddColorBuffer(ColorBufferObject::BUFFER_UBYTE, ColorBufferObject::WRAP_CLAMP_TO_EDGE, ColorBufferObject::FILTER_LINEAR, false);
86
87        mShadowCam = new Camera(mSceneBox.Size().x * 0.5f, mSceneBox.Size().y * 0.5f);
88        mShadowCam->SetOrtho(true);
89}
90
91
92ShadowMap::~ShadowMap()
93{
94        DEL_PTR(mFbo);
95        DEL_PTR(mShadowCam);
96}
97
98
99void ShadowMap::ComputeShadowMap(RenderTraverser *renderer)
100{
101        const float xlen = Magnitude(mSceneBox.Diagonal() * 0.5f);
102        const float ylen = Magnitude(mSceneBox.Diagonal() * 0.5f);
103       
104        mShadowCam->SetDirection(mLight->GetDirection());
105       
106        // set position so that we can see the whole scene
107        Vector3 pos = mSceneBox.Center();
108
109        pos -= mLight->GetDirection() * Magnitude(mSceneBox.Diagonal() * 0.5f);
110        mShadowCam->SetPosition(pos);
111
112        mFbo->Bind();
113       
114        glDrawBuffers(1, mrt);
115
116        glPushAttrib(GL_VIEWPORT_BIT);
117        glViewport(0, 0, mSize, mSize);
118
119        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
120
121        glDisable(GL_LIGHTING);
122        glDisable(GL_TEXTURE_2D);
123        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
124
125        glPolygonOffset(1.0f, 2000.0f);
126        glEnable(GL_POLYGON_OFFSET_FILL);
127
128        glShadeModel(GL_FLAT);
129        glEnable(GL_DEPTH_TEST);
130
131        glMatrixMode(GL_PROJECTION);
132        glPushMatrix();
133        glLoadIdentity();
134       
135        // setup projection
136        glOrtho(+xlen, -xlen, +ylen, -ylen, 0.0f, Magnitude(mSceneBox.Diagonal()));
137       
138
139        glMatrixMode(GL_MODELVIEW);
140        glPushMatrix();
141        glLoadIdentity();
142
143        // setup shadow camera
144        mShadowCam->SetupCameraView();
145
146
147        //////////////
148        //-- compute texture matrix
149
150        Matrix4x4 lightView, lightProj;
151
152        mShadowCam->GetModelViewMatrix(lightView);
153        mShadowCam->GetProjectionMatrix(lightProj);
154
155        static Matrix4x4 biasMatrix(0.5f, 0.0f, 0.0f, 0.5f,
156                                                                0.0f, 0.5f, 0.0f, 0.5f,
157                                                                0.0f, 0.0f, 0.5f, 0.5f,
158                                                                0.0f, 0.0f, 0.0f, 1.0f); //bias from [-1, 1] to [0, 1]
159
160        Matrix4x4 lightProjView = lightView * lightProj;
161        mTextureMatrix = lightProjView * biasMatrix;
162
163
164        /////////////
165        //-- render scene into shadow map
166
167        renderer->RenderScene();
168
169       
170        glDisable(GL_POLYGON_OFFSET_FILL);
171        glMatrixMode(GL_MODELVIEW);
172        glPopMatrix();
173
174        glMatrixMode(GL_PROJECTION);
175        glPopMatrix();
176
177        glPopAttrib();
178       
179        /*float *data = new float[mSize * mSize];
180
181        GrabDepthBuffer(data, mFbo->GetDepthTex());
182        ExportDepthBuffer(data, mSize);
183
184        delete [] data;
185        */
186        PrintGLerror("shadow map");
187
188        FrameBufferObject::Release();
189}
190
191
192void ShadowMap::GetTextureMatrix(Matrix4x4 &m) const
193{
194        m = mTextureMatrix;
195}
196
197 
198unsigned int ShadowMap::GetShadowTexture() const
199{
200        return mFbo->GetDepthTex();
201}
202
203
204} // namespace
Note: See TracBrowser for help on using the repository browser.