size(s),
scene(c),
light(l),
+ unit(3),
radius(1)
{
depth_buf.set_min_filter(LINEAR);
depth_buf.parameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
depth_buf.parameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
fbo.attach(DEPTH_ATTACHMENT, depth_buf, 0);
- glDrawBuffer(GL_NONE);
+ draw_buffer(NO_BUFFER);
Framebuffer::unbind();
Texture::unbind();
}
radius=r;
}
+void ShadowMap::set_texture_unit(unsigned u)
+{
+ unit=u;
+}
+
void ShadowMap::prepare()
{
- const Vector4 &lpos=light.get_position();
+ Vector4 lpos=light.get_position();
if(lpos.w)
- throw Exception("Non-directional lights not supported at the moment");
+ {
+ /* XXX Not really proper way to support positional lights, but good
+ enough when the light source is far away */
+ lpos.x-=target.x;
+ lpos.y-=target.y;
+ lpos.z-=target.z;
+ float d=sqrt(lpos.x*lpos.x+lpos.y*lpos.y+lpos.z*lpos.z);
+ lpos.x/=d;
+ lpos.y/=d;
+ lpos.z/=d;
+ }
float matrix[16];
if(abs(lpos.z)>=abs(lpos.x) && abs(lpos.z)>=abs(lpos.y))
const Framebuffer *old_fbo=Framebuffer::current();
fbo.bind();
- glViewport(0, 0, size, size);
- glClear(GL_DEPTH_BUFFER_BIT);
+ clear(DEPTH_BUFFER_BIT);
scene.render("shadow");
matrix_mode(PROJECTION);
Framebuffer::unbind();
}
- depth_buf.bind_to(3);
+ depth_buf.bind_to(unit);
float diam=radius*2;
float s_eq[4]={ matrix[0]/diam, matrix[4]/diam, matrix[8]/diam, matrix[12]/diam+0.5 };
float t_eq[4]={ matrix[1]/diam, matrix[5]/diam, matrix[9]/diam, matrix[13]/diam+0.5 };
void ShadowMap::cleanup()
{
- TexUnit::activate(3);
+ TexUnit::activate(unit);
Texture::unbind();
disable(GL_TEXTURE_GEN_S);
disable(GL_TEXTURE_GEN_T);