9 #include "vmath/vmath.h"
11 #include "gmath/gmath.h"
17 static int tex_sz, prev_vp[4];
18 static unsigned int fbo, depth_tex, rb_color;
19 static gph::Mat4 shadow_mat;
21 bool init_shadow(int sz)
24 printf("initializing shadow buffer (%dx%d)\n", tex_sz, tex_sz);
26 glGenFramebuffers(1, &fbo);
27 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
29 const float border_color[] = {1, 1, 1, 1};
31 glGenTextures(1, &depth_tex);
32 glBindTexture(GL_TEXTURE_2D, depth_tex);
33 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
34 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
35 glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color);
36 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
37 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
38 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
39 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex_sz, tex_sz, 0,
40 GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
41 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0);
43 assert(glGetError() == GL_NO_ERROR);
45 glDrawBuffer(GL_FALSE);
46 glReadBuffer(GL_FALSE);
48 if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
49 fprintf(stderr, "incomplete framebuffer\n");
53 glBindFramebuffer(GL_FRAMEBUFFER, 0);
54 glDrawBuffer(GL_BACK);
55 glReadBuffer(GL_BACK);
56 assert(glGetError() == GL_NO_ERROR);
63 glDeleteTextures(1, &depth_tex);
64 glDeleteRenderbuffers(1, &rb_color);
65 glDeleteFramebuffers(1, &fbo);
68 void begin_shadow_pass(const gph::Vec3 &lpos, const gph::Vec3 <arg, float lfov, float znear, float zfar)
72 glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);
73 glDisable(GL_LIGHTING);
74 glColorMask(0, 0, 0, 0);
79 glGetFloatv(GL_MODELVIEW_MATRIX, viewmat[0]);
82 Matrix4x4 lt_viewmat, lt_projmat;
83 lt_projmat.set_perspective(DEG_TO_RAD(lfov) * 2.0, 1.0, znear, zfar);
84 lt_viewmat.set_lookat(Vector3(lpos.x, lpos.y, lpos.z), Vector3(ltarg.x, ltarg.y, ltarg.z), Vector3(0, 1, 0));
85 Matrix4x4 smat = lt_projmat * lt_viewmat * viewmat.inverse();
88 memcpy(shadow_mat[0], smat[0], 16 * sizeof(float));
90 glMatrixMode(GL_PROJECTION);
92 glLoadTransposeMatrixf(lt_projmat[0]);
94 glMatrixMode(GL_MODELVIEW);
96 glLoadTransposeMatrixf(lt_viewmat[0]);
99 glGetFloatv(GL_MODELVIEW_MATRIX, viewmat[0]);
101 gph::Mat4 lt_viewmat, lt_projmat;
102 lt_projmat.perspective(gph::deg_to_rad(lfov) * 2.0, 1.0, znear, zfar);
103 lt_viewmat.inv_lookat(lpos, ltarg, gph::Vec3(0, 1, 0));
104 shadow_mat = lt_projmat * lt_viewmat * viewmat.inverse();
105 //shadow_mat = viewmat.inverse() * lt_viewmat * lt_projmat;
108 glMatrixMode(GL_PROJECTION);
110 glLoadMatrixf(lt_projmat[0]);
112 glMatrixMode(GL_MODELVIEW);
114 glLoadMatrixf(lt_viewmat[0]);
117 glGetIntegerv(GL_VIEWPORT, prev_vp);
118 glViewport(0, 0, tex_sz, tex_sz);
120 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
122 glPolygonOffset(2, 2);
123 glEnable(GL_POLYGON_OFFSET_FILL);
125 glClear(GL_DEPTH_BUFFER_BIT);
130 void end_shadow_pass()
134 glBindFramebuffer(GL_FRAMEBUFFER, 0);
136 glViewport(prev_vp[0], prev_vp[1], prev_vp[2], prev_vp[3]);
138 glMatrixMode(GL_PROJECTION);
140 glMatrixMode(GL_MODELVIEW);
146 gph::Mat4 get_shadow_matrix()
151 unsigned int get_shadow_tex()