# HG changeset patch # User John Tsiombikas # Date 1435547925 -10800 # Node ID 37dead56f01ef73c552fbbcf9272082424456fa6 # Parent 986c0b76513f0c7418eeb7dd9734aba33516f163 fixed shadows diff -r 986c0b76513f -r 37dead56f01e sdr/shadow.v.glsl --- a/sdr/shadow.v.glsl Mon Jun 29 01:29:36 2015 +0300 +++ b/sdr/shadow.v.glsl Mon Jun 29 06:18:45 2015 +0300 @@ -17,6 +17,5 @@ 0.5, 0.5, 0.5, 1.0); mat4 tex_matrix = offmat * gl_TextureMatrix[1]; - shadow_tc = tex_matrix * gl_Vertex; - shadow_tc = shadow_tc / shadow_tc.w; + shadow_tc = tex_matrix * vec4(vpos, 1.0); } diff -r 986c0b76513f -r 37dead56f01e src/board.cc --- a/src/board.cc Mon Jun 29 01:29:36 2015 +0300 +++ b/src/board.cc Mon Jun 29 06:18:45 2015 +0300 @@ -172,11 +172,16 @@ void Board::draw() const { + bool use_shadows = opt.shadows && sdr_shadow; + unsigned int board_sdr = use_shadows ? sdr_shadow : sdr_phong; + unsigned int piece_sdr = use_shadows ? sdr_shadow_notex : sdr_phong_notex; + for(size_t i=0; idraw_wire(); obj[i]->draw_normals(0.075); } else { + obj[i]->set_shader(board_sdr); obj[i]->draw(); } } @@ -185,6 +190,7 @@ Vector3 pos = piece_pos(pieces[i].slot, pieces[i].level); piece_obj->xform().set_translation(pos); piece_obj->mtl.diffuse = opt.piece_color[pieces[i].owner]; + piece_obj->set_shader(piece_sdr); piece_obj->draw(); } } @@ -193,9 +199,6 @@ bool Board::generate() { static const float board_spec = 0.4; - bool use_shadows = opt.shadows && sdr_shadow; - unsigned int board_sdr = use_shadows ? sdr_shadow : sdr_phong; - unsigned int piece_sdr = use_shadows ? sdr_shadow_notex : sdr_phong_notex; Mesh tmp; Matrix4x4 xform; @@ -215,7 +218,6 @@ obottom->set_mesh(bottom); obottom->xform().set_translation(Vector3(sign * BOARD_OFFSET, 0, 0)); obottom->set_texture(img_field.texture()); - obottom->set_shader(board_sdr); obottom->mtl.specular = Vector3(board_spec, board_spec, board_spec); obj.push_back(obottom); @@ -258,7 +260,6 @@ osides->tex_xform().set_scaling(Vector3(2, 2, 2)); osides->tex_xform().rotate(-Vector3(1, 0, 0.5), M_PI / 4.0); osides->mtl.specular = Vector3(board_spec, board_spec, board_spec); - osides->set_shader(board_sdr); obj.push_back(osides); } @@ -332,7 +333,6 @@ opiece->mtl.diffuse = Vector3(0.6, 0.6, 0.6); opiece->mtl.specular = Vector3(0.8, 0.8, 0.8); opiece->xform().set_translation(Vector3(0, 0.2, 0)); - opiece->set_shader(piece_sdr); //obj.push_back(opiece); piece_obj = opiece; diff -r 986c0b76513f -r 37dead56f01e src/game.cc --- a/src/game.cc Mon Jun 29 01:29:36 2015 +0300 +++ b/src/game.cc Mon Jun 29 06:18:45 2015 +0300 @@ -15,6 +15,7 @@ unsigned long cur_time; unsigned int sdr_phong, sdr_phong_notex; unsigned int sdr_shadow, sdr_shadow_notex; +unsigned int sdr_unlit; bool wireframe; static Board board; @@ -23,7 +24,7 @@ static bool bnstate[8]; static int prev_x, prev_y; -static bool dbg_busyloop; +static bool dbg_busyloop, dbg_show_shadowmap; bool game_init() { @@ -37,6 +38,9 @@ glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); + float amb[] = {0.3, 0.3, 0.3, 1.0}; + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb); + if(glcaps.sep_spec) { glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); } @@ -55,7 +59,7 @@ } if(glcaps.fbo) { - init_shadow(512); + init_shadow(2048); if(!(sdr_shadow = create_program_load("sdr/shadow.v.glsl", "sdr/shadow.p.glsl"))) { return false; @@ -66,6 +70,7 @@ if(!(sdr_shadow_notex = create_program_load("sdr/shadow.v.glsl", "sdr/shadow-notex.p.glsl"))) { return false; } + set_uniform_int(sdr_shadow_notex, "shadowmap", 1); } } @@ -104,13 +109,11 @@ glRotatef(cam_phi, 1, 0, 0); glRotatef(cam_theta, 0, 1, 0); - float ldir[] = {-10, 20, 10, 1}; - glLightfv(GL_LIGHT0, GL_POSITION, ldir); + float lpos[] = {-10, 20, 10, 1}; + glLightfv(GL_LIGHT0, GL_POSITION, lpos); if(opt.shadows && sdr_shadow) { - printf("shadow pass\n"); - - begin_shadow_pass(Vector3(-10, 20, 10), Vector3(0, 0, 0), 25); + begin_shadow_pass(Vector3(lpos[0], lpos[1], lpos[2]), Vector3(0, 0, 0), 4.5); draw_scene(); end_shadow_pass(); @@ -119,7 +122,7 @@ glMatrixMode(GL_TEXTURE); Matrix4x4 shadow_matrix = get_shadow_matrix(); - glLoadMatrixf(shadow_matrix[0]); + glLoadTransposeMatrixf(shadow_matrix[0]); glActiveTexture(GL_TEXTURE0); glMatrixMode(GL_MODELVIEW); @@ -129,10 +132,49 @@ glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); } else { draw_scene(); } + if(dbg_show_shadowmap) { + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + + glPushAttrib(GL_ENABLE_BIT); + glUseProgram(0); + glBindTexture(GL_TEXTURE_2D, get_shadow_tex()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); + glEnable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glDisable(GL_BLEND); + + glBegin(GL_QUADS); + glColor4f(1, 1, 1, 1); + glTexCoord2f(0, 0); glVertex2f(-1, -1); + glTexCoord2f(1, 0); glVertex2f(1, -1); + glTexCoord2f(1, 1); glVertex2f(1, 1); + glTexCoord2f(0, 1); glVertex2f(-1, 1); + glEnd(); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + glBindTexture(GL_TEXTURE_2D, 0); + + glPopAttrib(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } + if(dbg_busyloop) { redisplay(); } @@ -201,6 +243,11 @@ redisplay(); break; + case 'D': + dbg_show_shadowmap = !dbg_show_shadowmap; + redisplay(); + break; + case 's': opt.shadows = !opt.shadows; redisplay(); diff -r 986c0b76513f -r 37dead56f01e src/game.h --- a/src/game.h Mon Jun 29 01:29:36 2015 +0300 +++ b/src/game.h Mon Jun 29 06:18:45 2015 +0300 @@ -4,6 +4,7 @@ extern int win_width, win_height; extern unsigned int sdr_phong, sdr_phong_notex; extern unsigned int sdr_shadow, sdr_shadow_notex; +extern unsigned int sdr_unlit; extern unsigned long cur_time; extern bool wireframe; diff -r 986c0b76513f -r 37dead56f01e src/object.cc --- a/src/object.cc Mon Jun 29 01:29:36 2015 +0300 +++ b/src/object.cc Mon Jun 29 06:18:45 2015 +0300 @@ -1,5 +1,6 @@ #include "object.h" #include "opengl.h" +#include "shadow.h" Material::Material() : diffuse(1, 1, 1), specular(0, 0, 0) @@ -81,7 +82,7 @@ glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT); rop.setup(); - if(sdr) { + if(sdr && !shadow_pass) { glUseProgram(sdr); } diff -r 986c0b76513f -r 37dead56f01e src/opengl.c --- a/src/opengl.c Mon Jun 29 01:29:36 2015 +0300 +++ b/src/opengl.c Mon Jun 29 06:18:45 2015 +0300 @@ -10,6 +10,7 @@ glcaps.fsaa = GLEW_ARB_multisample; glcaps.sep_spec = GLEW_EXT_separate_specular_color; glcaps.fbo = GLEW_ARB_framebuffer_object; + glcaps.shadow = GLEW_ARB_shadow | GLEW_SGIX_shadow; return 0; } diff -r 986c0b76513f -r 37dead56f01e src/opengl.h --- a/src/opengl.h Mon Jun 29 01:29:36 2015 +0300 +++ b/src/opengl.h Mon Jun 29 06:18:45 2015 +0300 @@ -8,6 +8,7 @@ int fsaa; int sep_spec; int fbo; + int shadow; }; extern struct GLCaps glcaps; diff -r 986c0b76513f -r 37dead56f01e src/opt.cc --- a/src/opt.cc Mon Jun 29 01:29:36 2015 +0300 +++ b/src/opt.cc Mon Jun 29 06:18:45 2015 +0300 @@ -10,7 +10,8 @@ opt.xres = 1280; opt.yres = 800; opt.fullscreen = false; - opt.shadows = false; opt.reflections = true; + opt.shadows = true; + opt.reflections = true; opt.def_username = opt.saved_passwd = 0; diff -r 986c0b76513f -r 37dead56f01e src/scenery.cc --- a/src/scenery.cc Mon Jun 29 01:29:36 2015 +0300 +++ b/src/scenery.cc Mon Jun 29 06:18:45 2015 +0300 @@ -22,7 +22,9 @@ {5.99, 0}, // mid 1 {6, -0.1}, {6.1, -0.1}, // mid 2 - {6.13, -0.3} + {6.13, -0.3}, + {3, -0.3}, // mid 3 + {0, -0.3} }; static const BezCurve table_curve = { sizeof table_cp / sizeof *table_cp, @@ -34,7 +36,6 @@ bool init_scenery() { - unsigned int sdr = opt.shadows && sdr_shadow ? sdr_shadow : sdr_phong; if(!gen_textures()) { return false; } @@ -58,7 +59,6 @@ otable->mtl.specular = Vector3(0.7, 0.7, 0.7); otable->xform().set_translation(Vector3(0, -0.025, 0)); otable->set_texture(img_marble.texture()); - otable->set_shader(sdr); obj.push_back(otable); @@ -86,11 +86,14 @@ void draw_scenery() { + unsigned int sdr = opt.shadows && sdr_shadow ? sdr_shadow : sdr_phong; + for(size_t i=0; idraw_wire(); obj[i]->draw_normals(0.075); } else { + obj[i]->set_shader(sdr); obj[i]->draw(); } } diff -r 986c0b76513f -r 37dead56f01e src/shadow.cc --- a/src/shadow.cc Mon Jun 29 01:29:36 2015 +0300 +++ b/src/shadow.cc Mon Jun 29 06:18:45 2015 +0300 @@ -3,25 +3,28 @@ #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 Matrix4x4 shadow_mat; bool init_shadow(int sz) { - if(!glcaps.fbo) { - return true; + if(!glcaps.fbo || !glcaps.shadow) { + return false; } tex_sz = sz; + printf("initializing shadow buffer (%dx%d)\n", tex_sz, tex_sz); glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glGenTextures(1, &depth_tex); glBindTexture(GL_TEXTURE_2D, depth_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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); @@ -56,36 +59,48 @@ void begin_shadow_pass(const Vector3 &lpos, const Vector3 <arg, float lfov) { - Matrix4x4 viewmat, projmat; + shadow_pass = true; glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT); glDisable(GL_LIGHTING); glColorMask(0, 0, 0, 0); glDepthMask(1); - projmat.set_perspective(DEG_TO_RAD(lfov) * 2.0, 1.0, 0.5, 500.0); - viewmat.set_lookat(lpos, ltarg, Vector3(0, 1, 0)); - shadow_mat = viewmat * projmat; + 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, 8.0, 50.0); + lt_viewmat.set_lookat(lpos, ltarg, Vector3(0, 1, 0)); + shadow_mat = lt_projmat * lt_viewmat * viewmat.inverse(); glMatrixMode(GL_PROJECTION); glPushMatrix(); - glLoadTransposeMatrixf(projmat[0]); + glLoadTransposeMatrixf(lt_projmat[0]); + glMatrixMode(GL_MODELVIEW); glPushMatrix(); - glLoadTransposeMatrixf(viewmat[0]); + glLoadTransposeMatrixf(lt_viewmat[0]); glGetIntegerv(GL_VIEWPORT, prev_vp); glViewport(0, 0, tex_sz, tex_sz); - glCullFace(GL_FRONT); 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); - glCullFace(GL_BACK); glViewport(prev_vp[0], prev_vp[1], prev_vp[2], prev_vp[3]); @@ -100,6 +115,22 @@ Matrix4x4 get_shadow_matrix() { return shadow_mat; + + /* + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + gluPerspective(lfov * 2.0, 1.0, 0.5, 50.0); + gluLookAt(lpos.x, lpos.y, lpos.z, ltarg.x, ltarg.y, ltarg.z, 0, 1, 0); + + float mat[16]; + glGetFloatv(GL_MODELVIEW_MATRIX, mat); + + Matrix4x4 res; + memcpy(res[0], mat, sizeof mat); + res.transpose(); + return res; + */ } unsigned int get_shadow_tex() diff -r 986c0b76513f -r 37dead56f01e src/shadow.h --- a/src/shadow.h Mon Jun 29 01:29:36 2015 +0300 +++ b/src/shadow.h Mon Jun 29 06:18:45 2015 +0300 @@ -3,6 +3,8 @@ #include "vmath/vmath.h" +extern bool shadow_pass; + bool init_shadow(int sz); void destroy_shadow();