X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=antikythera;a=blobdiff_plain;f=src%2Fshadow.cc;fp=src%2Fshadow.cc;h=357ed8245e605a9b2afea34665cc71765c6c0200;hp=0000000000000000000000000000000000000000;hb=ccc1a688b59e25bb934a0d3e2bbf477960068d4f;hpb=080d7a779d43f549fc16c44e709cbf5989180fdf diff --git a/src/shadow.cc b/src/shadow.cc new file mode 100644 index 0000000..357ed82 --- /dev/null +++ b/src/shadow.cc @@ -0,0 +1,147 @@ +#define GPH_NAMESPACE +#include +#include "opengl.h" +#include "shadow.h" +#include "vmath/vmath.h" + + +bool shadow_pass; + +static int tex_sz, prev_vp[4]; +static unsigned int fbo, depth_tex, rb_color; +static gph::Mat4 shadow_mat; + +bool init_shadow(int sz) +{ + tex_sz = sz; + printf("initializing shadow buffer (%dx%d)\n", tex_sz, tex_sz); + + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + const float border_color[] = {1, 1, 1, 1}; + + glGenTextures(1, &depth_tex); + glBindTexture(GL_TEXTURE_2D, depth_tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border_color); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex_sz, tex_sz, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0); + + assert(glGetError() == GL_NO_ERROR); + + glDrawBuffer(GL_FALSE); + glReadBuffer(GL_FALSE); + + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + fprintf(stderr, "incomplete framebuffer\n"); + return false; + } + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDrawBuffer(GL_BACK); + glReadBuffer(GL_BACK); + assert(glGetError() == GL_NO_ERROR); + + return true; +} + +void destroy_shadow() +{ + glDeleteTextures(1, &depth_tex); + glDeleteRenderbuffers(1, &rb_color); + glDeleteFramebuffers(1, &fbo); +} + +void begin_shadow_pass(const gph::Vec3 &lpos, const gph::Vec3 <arg, float lfov, float znear, float zfar) +{ + shadow_pass = true; + + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT); + glDisable(GL_LIGHTING); + glColorMask(0, 0, 0, 0); + glDepthMask(1); + + Matrix4x4 viewmat; + glGetFloatv(GL_MODELVIEW_MATRIX, viewmat[0]); + viewmat.transpose(); + + Matrix4x4 lt_viewmat, lt_projmat; + lt_projmat.set_perspective(DEG_TO_RAD(lfov) * 2.0, 1.0, znear, zfar); + lt_viewmat.set_lookat(Vector3(lpos.x, lpos.y, lpos.z), Vector3(ltarg.x, ltarg.y, ltarg.z), Vector3(0, 1, 0)); + Matrix4x4 smat = lt_projmat * lt_viewmat * viewmat.inverse(); + smat.transpose(); + + memcpy(shadow_mat[0], smat[0], 16 * sizeof(float)); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadTransposeMatrixf(lt_projmat[0]); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadTransposeMatrixf(lt_viewmat[0]); + + + /*gph::Mat4 viewmat; + glGetFloatv(GL_MODELVIEW_MATRIX, viewmat[0]); + + gph::Mat4 lt_viewmat, lt_projmat; + lt_projmat.perspective(deg_to_rad(lfov) * 2.0, 1.0, znear, zfar); + lt_viewmat.inv_lookat(lpos, ltarg, gph::Vec3(0, 1, 0)); + shadow_mat = lt_projmat * lt_viewmat * viewmat.inverse(); + //shadow_mat = viewmat.inverse() * lt_viewmat * lt_projmat; + shadow_mat.print(); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixf(lt_projmat[0]); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadMatrixf(lt_viewmat[0]); + */ + + glGetIntegerv(GL_VIEWPORT, prev_vp); + glViewport(0, 0, tex_sz, tex_sz); + + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + + glPolygonOffset(2, 2); + glEnable(GL_POLYGON_OFFSET_FILL); + + glClear(GL_DEPTH_BUFFER_BIT); + glUseProgram(0); +} + + +void end_shadow_pass() +{ + shadow_pass = false; + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + glViewport(prev_vp[0], prev_vp[1], prev_vp[2], prev_vp[3]); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glPopAttrib(); +} + +gph::Mat4 get_shadow_matrix() +{ + return shadow_mat; +} + +unsigned int get_shadow_tex() +{ + return depth_tex; +}