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

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

shadow mapping almost working (but ulgy!!)

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(int size, const AxisAlignedBox3 &sceneBox, Camera *cam):
82mSceneBox(sceneBox), mSize(size), mCamera(cam)
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}
97
98
99
100void ShadowMap::ComputeShadowMap(Light *light, RenderTraverser *traverser)
101{
102        mLight = light;
103
104        const float xlen = Magnitude(mSceneBox.Diagonal() * 0.5f);
105        const float ylen = Magnitude(mSceneBox.Diagonal() * 0.5f);
106       
107        mShadowCam->SetDirection(light->GetDirection());
108       
109        // set position so that we can see the whole scene
110        Vector3 pos = mSceneBox.Center();
111
112        pos -= light->GetDirection() * Magnitude(mSceneBox.Diagonal() * 0.5f);
113        mShadowCam->SetPosition(pos);
114
115        mFbo->Bind();
116       
117        glDrawBuffers(1, mrt);
118
119        glPushAttrib(GL_VIEWPORT_BIT);
120        glViewport(0, 0, mSize, mSize);
121
122        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
123
124        glDisable(GL_LIGHTING);
125        glDisable(GL_TEXTURE_2D);
126        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
127
128        glPolygonOffset(1.0f, 2000.0f);
129        glEnable(GL_POLYGON_OFFSET_FILL);
130
131        glShadeModel(GL_FLAT);
132        glEnable(GL_DEPTH_TEST);
133
134        glMatrixMode(GL_PROJECTION);
135        glPushMatrix();
136        glLoadIdentity();
137       
138        // setup projection
139        glOrtho(+xlen, -xlen, +ylen, -ylen, 0.0f, Magnitude(mSceneBox.Diagonal()));
140       
141
142        glMatrixMode(GL_MODELVIEW);
143        glPushMatrix();
144
145        glLoadIdentity();
146
147        // setup shadow camera
148        mShadowCam->SetupCameraView();
149
150        //////////////
151        //-- compute texture matrix
152
153        Matrix4x4 lightView, lightProj;
154
155        mShadowCam->GetModelViewMatrix(lightView);
156        mShadowCam->GetProjectionMatrix(lightProj);
157
158        static Matrix4x4 biasMatrix(0.5f, 0.0f, 0.0f, 0.5f,
159                                                                0.0f, 0.5f, 0.0f, 0.5f,
160                                                                0.0f, 0.0f, 0.5f, 0.5f,
161                                                                0.0f, 0.0f, 0.0f, 1.0f); //bias from [-1, 1] to [0, 1]
162
163        Matrix4x4 lightProjView = lightView * lightProj;
164        mTextureMatrix = lightProjView * biasMatrix;
165
166
167        /////////////
168        //-- render scene into shadow map
169
170        traverser->RenderScene();
171       
172        glDisable(GL_POLYGON_OFFSET_FILL);
173        glMatrixMode(GL_MODELVIEW);
174        glPopMatrix();
175
176        glMatrixMode(GL_PROJECTION);
177        glPopMatrix();
178
179        glPopAttrib();
180       
181        /*float *data = new float[mSize * mSize];
182
183        GrabDepthBuffer(data, mFbo->GetDepthTex());
184        ExportDepthBuffer(data, mSize);
185
186        delete [] data;
187        */
188        PrintGLerror("shadow map");
189
190        FrameBufferObject::Release();
191}
192
193
194void ShadowMap::GetTextureMatrix(Matrix4x4 &m) const
195{
196        m = mTextureMatrix;
197}
198
199 
200unsigned int ShadowMap::GetShadowTexture() const
201{
202        return mFbo->GetDepthTex();
203}
204
205
206} // namespace
Note: See TracBrowser for help on using the repository browser.