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

Revision 2897, 4.4 KB checked in by mattausch, 16 years ago (diff)

improved shadow mapping

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