5 #include "vmath/vmath.h"
10 static int tex_sz, prev_vp[4];
11 static unsigned int fbo, depth_tex, rb_color;
12 static gph::Mat4 shadow_mat;
14 bool init_shadow(int sz)
17 printf("initializing shadow buffer (%dx%d)\n", tex_sz, tex_sz);
19 glGenFramebuffers(1, &fbo);
20 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
22 const float border_color[] = {1, 1, 1, 1};
24 glGenTextures(1, &depth_tex);
25 glBindTexture(GL_TEXTURE_2D, depth_tex);
26 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
27 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
28 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
29 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
30 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
31 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
32 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex_sz, tex_sz, 0,
33 GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
34 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0);
36 assert(glGetError() == GL_NO_ERROR);
38 glDrawBuffer(GL_FALSE);
39 glReadBuffer(GL_FALSE);
41 if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
42 fprintf(stderr, "incomplete framebuffer\n");
46 glBindFramebuffer(GL_FRAMEBUFFER, 0);
47 glDrawBuffer(GL_BACK);
48 glReadBuffer(GL_BACK);
49 assert(glGetError() == GL_NO_ERROR);
56 glDeleteTextures(1, &depth_tex);
57 glDeleteRenderbuffers(1, &rb_color);
58 glDeleteFramebuffers(1, &fbo);
61 void begin_shadow_pass(const gph::Vec3 &lpos, const gph::Vec3 <arg, float lfov, float znear, float zfar)
65 glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
66 glDisable(GL_LIGHTING);
67 glColorMask(0, 0, 0, 0);
71 glGetFloatv(GL_MODELVIEW_MATRIX, viewmat[0]);
74 Matrix4x4 lt_viewmat, lt_projmat;
75 lt_projmat.set_perspective(DEG_TO_RAD(lfov) * 2.0, 1.0, znear, zfar);
76 lt_viewmat.set_lookat(Vector3(lpos.x, lpos.y, lpos.z), Vector3(ltarg.x, ltarg.y, ltarg.z), Vector3(0, 1, 0));
77 Matrix4x4 smat = lt_projmat * lt_viewmat * viewmat.inverse();
80 memcpy(shadow_mat[0], smat[0], 16 * sizeof(float));
82 glMatrixMode(GL_PROJECTION);
84 glLoadTransposeMatrixf(lt_projmat[0]);
86 glMatrixMode(GL_MODELVIEW);
88 glLoadTransposeMatrixf(lt_viewmat[0]);
92 glGetFloatv(GL_MODELVIEW_MATRIX, viewmat[0]);
94 gph::Mat4 lt_viewmat, lt_projmat;
95 lt_projmat.perspective(deg_to_rad(lfov) * 2.0, 1.0, znear, zfar);
96 lt_viewmat.inv_lookat(lpos, ltarg, gph::Vec3(0, 1, 0));
97 shadow_mat = lt_projmat * lt_viewmat * viewmat.inverse();
98 //shadow_mat = viewmat.inverse() * lt_viewmat * lt_projmat;
101 glMatrixMode(GL_PROJECTION);
103 glLoadMatrixf(lt_projmat[0]);
105 glMatrixMode(GL_MODELVIEW);
107 glLoadMatrixf(lt_viewmat[0]);
110 glGetIntegerv(GL_VIEWPORT, prev_vp);
111 glViewport(0, 0, tex_sz, tex_sz);
113 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
115 glPolygonOffset(2, 2);
116 glEnable(GL_POLYGON_OFFSET_FILL);
118 glClear(GL_DEPTH_BUFFER_BIT);
123 void end_shadow_pass()
127 glBindFramebuffer(GL_FRAMEBUFFER, 0);
129 glViewport(prev_vp[0], prev_vp[1], prev_vp[2], prev_vp[3]);
131 glMatrixMode(GL_PROJECTION);
133 glMatrixMode(GL_MODELVIEW);
139 gph::Mat4 get_shadow_matrix()
144 unsigned int get_shadow_tex()