tavli
changeset 19:37dead56f01e
fixed shadows
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 29 Jun 2015 06:18:45 +0300 |
parents | 986c0b76513f |
children | 111c1a9bca29 |
files | sdr/shadow.v.glsl src/board.cc src/game.cc src/game.h src/object.cc src/opengl.c src/opengl.h src/opt.cc src/scenery.cc src/shadow.cc src/shadow.h |
diffstat | 11 files changed, 120 insertions(+), 33 deletions(-) [+] |
line diff
1.1 --- a/sdr/shadow.v.glsl Mon Jun 29 01:29:36 2015 +0300 1.2 +++ b/sdr/shadow.v.glsl Mon Jun 29 06:18:45 2015 +0300 1.3 @@ -17,6 +17,5 @@ 1.4 0.5, 0.5, 0.5, 1.0); 1.5 mat4 tex_matrix = offmat * gl_TextureMatrix[1]; 1.6 1.7 - shadow_tc = tex_matrix * gl_Vertex; 1.8 - shadow_tc = shadow_tc / shadow_tc.w; 1.9 + shadow_tc = tex_matrix * vec4(vpos, 1.0); 1.10 }
2.1 --- a/src/board.cc Mon Jun 29 01:29:36 2015 +0300 2.2 +++ b/src/board.cc Mon Jun 29 06:18:45 2015 +0300 2.3 @@ -172,11 +172,16 @@ 2.4 2.5 void Board::draw() const 2.6 { 2.7 + bool use_shadows = opt.shadows && sdr_shadow; 2.8 + unsigned int board_sdr = use_shadows ? sdr_shadow : sdr_phong; 2.9 + unsigned int piece_sdr = use_shadows ? sdr_shadow_notex : sdr_phong_notex; 2.10 + 2.11 for(size_t i=0; i<obj.size(); i++) { 2.12 if(wireframe) { 2.13 obj[i]->draw_wire(); 2.14 obj[i]->draw_normals(0.075); 2.15 } else { 2.16 + obj[i]->set_shader(board_sdr); 2.17 obj[i]->draw(); 2.18 } 2.19 } 2.20 @@ -185,6 +190,7 @@ 2.21 Vector3 pos = piece_pos(pieces[i].slot, pieces[i].level); 2.22 piece_obj->xform().set_translation(pos); 2.23 piece_obj->mtl.diffuse = opt.piece_color[pieces[i].owner]; 2.24 + piece_obj->set_shader(piece_sdr); 2.25 piece_obj->draw(); 2.26 } 2.27 } 2.28 @@ -193,9 +199,6 @@ 2.29 bool Board::generate() 2.30 { 2.31 static const float board_spec = 0.4; 2.32 - bool use_shadows = opt.shadows && sdr_shadow; 2.33 - unsigned int board_sdr = use_shadows ? sdr_shadow : sdr_phong; 2.34 - unsigned int piece_sdr = use_shadows ? sdr_shadow_notex : sdr_phong_notex; 2.35 2.36 Mesh tmp; 2.37 Matrix4x4 xform; 2.38 @@ -215,7 +218,6 @@ 2.39 obottom->set_mesh(bottom); 2.40 obottom->xform().set_translation(Vector3(sign * BOARD_OFFSET, 0, 0)); 2.41 obottom->set_texture(img_field.texture()); 2.42 - obottom->set_shader(board_sdr); 2.43 obottom->mtl.specular = Vector3(board_spec, board_spec, board_spec); 2.44 obj.push_back(obottom); 2.45 2.46 @@ -258,7 +260,6 @@ 2.47 osides->tex_xform().set_scaling(Vector3(2, 2, 2)); 2.48 osides->tex_xform().rotate(-Vector3(1, 0, 0.5), M_PI / 4.0); 2.49 osides->mtl.specular = Vector3(board_spec, board_spec, board_spec); 2.50 - osides->set_shader(board_sdr); 2.51 obj.push_back(osides); 2.52 2.53 } 2.54 @@ -332,7 +333,6 @@ 2.55 opiece->mtl.diffuse = Vector3(0.6, 0.6, 0.6); 2.56 opiece->mtl.specular = Vector3(0.8, 0.8, 0.8); 2.57 opiece->xform().set_translation(Vector3(0, 0.2, 0)); 2.58 - opiece->set_shader(piece_sdr); 2.59 //obj.push_back(opiece); 2.60 2.61 piece_obj = opiece;
3.1 --- a/src/game.cc Mon Jun 29 01:29:36 2015 +0300 3.2 +++ b/src/game.cc Mon Jun 29 06:18:45 2015 +0300 3.3 @@ -15,6 +15,7 @@ 3.4 unsigned long cur_time; 3.5 unsigned int sdr_phong, sdr_phong_notex; 3.6 unsigned int sdr_shadow, sdr_shadow_notex; 3.7 +unsigned int sdr_unlit; 3.8 bool wireframe; 3.9 3.10 static Board board; 3.11 @@ -23,7 +24,7 @@ 3.12 static bool bnstate[8]; 3.13 static int prev_x, prev_y; 3.14 3.15 -static bool dbg_busyloop; 3.16 +static bool dbg_busyloop, dbg_show_shadowmap; 3.17 3.18 bool game_init() 3.19 { 3.20 @@ -37,6 +38,9 @@ 3.21 glEnable(GL_LIGHTING); 3.22 glEnable(GL_LIGHT0); 3.23 3.24 + float amb[] = {0.3, 0.3, 0.3, 1.0}; 3.25 + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, amb); 3.26 + 3.27 if(glcaps.sep_spec) { 3.28 glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR); 3.29 } 3.30 @@ -55,7 +59,7 @@ 3.31 } 3.32 3.33 if(glcaps.fbo) { 3.34 - init_shadow(512); 3.35 + init_shadow(2048); 3.36 3.37 if(!(sdr_shadow = create_program_load("sdr/shadow.v.glsl", "sdr/shadow.p.glsl"))) { 3.38 return false; 3.39 @@ -66,6 +70,7 @@ 3.40 if(!(sdr_shadow_notex = create_program_load("sdr/shadow.v.glsl", "sdr/shadow-notex.p.glsl"))) { 3.41 return false; 3.42 } 3.43 + set_uniform_int(sdr_shadow_notex, "shadowmap", 1); 3.44 } 3.45 } 3.46 3.47 @@ -104,13 +109,11 @@ 3.48 glRotatef(cam_phi, 1, 0, 0); 3.49 glRotatef(cam_theta, 0, 1, 0); 3.50 3.51 - float ldir[] = {-10, 20, 10, 1}; 3.52 - glLightfv(GL_LIGHT0, GL_POSITION, ldir); 3.53 + float lpos[] = {-10, 20, 10, 1}; 3.54 + glLightfv(GL_LIGHT0, GL_POSITION, lpos); 3.55 3.56 if(opt.shadows && sdr_shadow) { 3.57 - printf("shadow pass\n"); 3.58 - 3.59 - begin_shadow_pass(Vector3(-10, 20, 10), Vector3(0, 0, 0), 25); 3.60 + begin_shadow_pass(Vector3(lpos[0], lpos[1], lpos[2]), Vector3(0, 0, 0), 4.5); 3.61 draw_scene(); 3.62 end_shadow_pass(); 3.63 3.64 @@ -119,7 +122,7 @@ 3.65 3.66 glMatrixMode(GL_TEXTURE); 3.67 Matrix4x4 shadow_matrix = get_shadow_matrix(); 3.68 - glLoadMatrixf(shadow_matrix[0]); 3.69 + glLoadTransposeMatrixf(shadow_matrix[0]); 3.70 3.71 glActiveTexture(GL_TEXTURE0); 3.72 glMatrixMode(GL_MODELVIEW); 3.73 @@ -129,10 +132,49 @@ 3.74 glActiveTexture(GL_TEXTURE1); 3.75 glBindTexture(GL_TEXTURE_2D, 0); 3.76 glActiveTexture(GL_TEXTURE0); 3.77 + glBindTexture(GL_TEXTURE_2D, 0); 3.78 } else { 3.79 draw_scene(); 3.80 } 3.81 3.82 + if(dbg_show_shadowmap) { 3.83 + glMatrixMode(GL_PROJECTION); 3.84 + glPushMatrix(); 3.85 + glLoadIdentity(); 3.86 + glMatrixMode(GL_MODELVIEW); 3.87 + glPushMatrix(); 3.88 + glLoadIdentity(); 3.89 + glMatrixMode(GL_TEXTURE); 3.90 + glLoadIdentity(); 3.91 + 3.92 + glPushAttrib(GL_ENABLE_BIT); 3.93 + glUseProgram(0); 3.94 + glBindTexture(GL_TEXTURE_2D, get_shadow_tex()); 3.95 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); 3.96 + glEnable(GL_TEXTURE_2D); 3.97 + glDisable(GL_DEPTH_TEST); 3.98 + glDisable(GL_LIGHTING); 3.99 + glDisable(GL_BLEND); 3.100 + 3.101 + glBegin(GL_QUADS); 3.102 + glColor4f(1, 1, 1, 1); 3.103 + glTexCoord2f(0, 0); glVertex2f(-1, -1); 3.104 + glTexCoord2f(1, 0); glVertex2f(1, -1); 3.105 + glTexCoord2f(1, 1); glVertex2f(1, 1); 3.106 + glTexCoord2f(0, 1); glVertex2f(-1, 1); 3.107 + glEnd(); 3.108 + 3.109 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); 3.110 + glBindTexture(GL_TEXTURE_2D, 0); 3.111 + 3.112 + glPopAttrib(); 3.113 + 3.114 + glMatrixMode(GL_PROJECTION); 3.115 + glPopMatrix(); 3.116 + glMatrixMode(GL_MODELVIEW); 3.117 + glPopMatrix(); 3.118 + } 3.119 + 3.120 if(dbg_busyloop) { 3.121 redisplay(); 3.122 } 3.123 @@ -201,6 +243,11 @@ 3.124 redisplay(); 3.125 break; 3.126 3.127 + case 'D': 3.128 + dbg_show_shadowmap = !dbg_show_shadowmap; 3.129 + redisplay(); 3.130 + break; 3.131 + 3.132 case 's': 3.133 opt.shadows = !opt.shadows; 3.134 redisplay();
4.1 --- a/src/game.h Mon Jun 29 01:29:36 2015 +0300 4.2 +++ b/src/game.h Mon Jun 29 06:18:45 2015 +0300 4.3 @@ -4,6 +4,7 @@ 4.4 extern int win_width, win_height; 4.5 extern unsigned int sdr_phong, sdr_phong_notex; 4.6 extern unsigned int sdr_shadow, sdr_shadow_notex; 4.7 +extern unsigned int sdr_unlit; 4.8 extern unsigned long cur_time; 4.9 4.10 extern bool wireframe;
5.1 --- a/src/object.cc Mon Jun 29 01:29:36 2015 +0300 5.2 +++ b/src/object.cc Mon Jun 29 06:18:45 2015 +0300 5.3 @@ -1,5 +1,6 @@ 5.4 #include "object.h" 5.5 #include "opengl.h" 5.6 +#include "shadow.h" 5.7 5.8 Material::Material() 5.9 : diffuse(1, 1, 1), specular(0, 0, 0) 5.10 @@ -81,7 +82,7 @@ 5.11 glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT); 5.12 rop.setup(); 5.13 5.14 - if(sdr) { 5.15 + if(sdr && !shadow_pass) { 5.16 glUseProgram(sdr); 5.17 } 5.18
6.1 --- a/src/opengl.c Mon Jun 29 01:29:36 2015 +0300 6.2 +++ b/src/opengl.c Mon Jun 29 06:18:45 2015 +0300 6.3 @@ -10,6 +10,7 @@ 6.4 glcaps.fsaa = GLEW_ARB_multisample; 6.5 glcaps.sep_spec = GLEW_EXT_separate_specular_color; 6.6 glcaps.fbo = GLEW_ARB_framebuffer_object; 6.7 + glcaps.shadow = GLEW_ARB_shadow | GLEW_SGIX_shadow; 6.8 6.9 return 0; 6.10 }
7.1 --- a/src/opengl.h Mon Jun 29 01:29:36 2015 +0300 7.2 +++ b/src/opengl.h Mon Jun 29 06:18:45 2015 +0300 7.3 @@ -8,6 +8,7 @@ 7.4 int fsaa; 7.5 int sep_spec; 7.6 int fbo; 7.7 + int shadow; 7.8 }; 7.9 extern struct GLCaps glcaps; 7.10
8.1 --- a/src/opt.cc Mon Jun 29 01:29:36 2015 +0300 8.2 +++ b/src/opt.cc Mon Jun 29 06:18:45 2015 +0300 8.3 @@ -10,7 +10,8 @@ 8.4 opt.xres = 1280; 8.5 opt.yres = 800; 8.6 opt.fullscreen = false; 8.7 - opt.shadows = false; opt.reflections = true; 8.8 + opt.shadows = true; 8.9 + opt.reflections = true; 8.10 8.11 opt.def_username = opt.saved_passwd = 0; 8.12
9.1 --- a/src/scenery.cc Mon Jun 29 01:29:36 2015 +0300 9.2 +++ b/src/scenery.cc Mon Jun 29 06:18:45 2015 +0300 9.3 @@ -22,7 +22,9 @@ 9.4 {5.99, 0}, // mid 1 9.5 {6, -0.1}, 9.6 {6.1, -0.1}, // mid 2 9.7 - {6.13, -0.3} 9.8 + {6.13, -0.3}, 9.9 + {3, -0.3}, // mid 3 9.10 + {0, -0.3} 9.11 }; 9.12 static const BezCurve table_curve = { 9.13 sizeof table_cp / sizeof *table_cp, 9.14 @@ -34,7 +36,6 @@ 9.15 9.16 bool init_scenery() 9.17 { 9.18 - unsigned int sdr = opt.shadows && sdr_shadow ? sdr_shadow : sdr_phong; 9.19 if(!gen_textures()) { 9.20 return false; 9.21 } 9.22 @@ -58,7 +59,6 @@ 9.23 otable->mtl.specular = Vector3(0.7, 0.7, 0.7); 9.24 otable->xform().set_translation(Vector3(0, -0.025, 0)); 9.25 otable->set_texture(img_marble.texture()); 9.26 - otable->set_shader(sdr); 9.27 obj.push_back(otable); 9.28 9.29 9.30 @@ -86,11 +86,14 @@ 9.31 9.32 void draw_scenery() 9.33 { 9.34 + unsigned int sdr = opt.shadows && sdr_shadow ? sdr_shadow : sdr_phong; 9.35 + 9.36 for(size_t i=0; i<obj.size(); i++) { 9.37 if(wireframe) { 9.38 obj[i]->draw_wire(); 9.39 obj[i]->draw_normals(0.075); 9.40 } else { 9.41 + obj[i]->set_shader(sdr); 9.42 obj[i]->draw(); 9.43 } 9.44 }
10.1 --- a/src/shadow.cc Mon Jun 29 01:29:36 2015 +0300 10.2 +++ b/src/shadow.cc Mon Jun 29 06:18:45 2015 +0300 10.3 @@ -3,25 +3,28 @@ 10.4 #include "shadow.h" 10.5 #include "vmath/vmath.h" 10.6 10.7 +bool shadow_pass; 10.8 + 10.9 static int tex_sz, prev_vp[4]; 10.10 static unsigned int fbo, depth_tex, rb_color; 10.11 static Matrix4x4 shadow_mat; 10.12 10.13 bool init_shadow(int sz) 10.14 { 10.15 - if(!glcaps.fbo) { 10.16 - return true; 10.17 + if(!glcaps.fbo || !glcaps.shadow) { 10.18 + return false; 10.19 } 10.20 10.21 tex_sz = sz; 10.22 + printf("initializing shadow buffer (%dx%d)\n", tex_sz, tex_sz); 10.23 10.24 glGenFramebuffers(1, &fbo); 10.25 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 10.26 10.27 glGenTextures(1, &depth_tex); 10.28 glBindTexture(GL_TEXTURE_2D, depth_tex); 10.29 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 10.30 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 10.31 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 10.32 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 10.33 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 10.34 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 10.35 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); 10.36 @@ -56,36 +59,48 @@ 10.37 10.38 void begin_shadow_pass(const Vector3 &lpos, const Vector3 <arg, float lfov) 10.39 { 10.40 - Matrix4x4 viewmat, projmat; 10.41 + shadow_pass = true; 10.42 10.43 glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT); 10.44 glDisable(GL_LIGHTING); 10.45 glColorMask(0, 0, 0, 0); 10.46 glDepthMask(1); 10.47 10.48 - projmat.set_perspective(DEG_TO_RAD(lfov) * 2.0, 1.0, 0.5, 500.0); 10.49 - viewmat.set_lookat(lpos, ltarg, Vector3(0, 1, 0)); 10.50 - shadow_mat = viewmat * projmat; 10.51 + Matrix4x4 viewmat; 10.52 + glGetFloatv(GL_MODELVIEW_MATRIX, viewmat[0]); 10.53 + viewmat.transpose(); 10.54 + 10.55 + Matrix4x4 lt_viewmat, lt_projmat; 10.56 + lt_projmat.set_perspective(DEG_TO_RAD(lfov) * 2.0, 1.0, 8.0, 50.0); 10.57 + lt_viewmat.set_lookat(lpos, ltarg, Vector3(0, 1, 0)); 10.58 + shadow_mat = lt_projmat * lt_viewmat * viewmat.inverse(); 10.59 10.60 glMatrixMode(GL_PROJECTION); 10.61 glPushMatrix(); 10.62 - glLoadTransposeMatrixf(projmat[0]); 10.63 + glLoadTransposeMatrixf(lt_projmat[0]); 10.64 + 10.65 glMatrixMode(GL_MODELVIEW); 10.66 glPushMatrix(); 10.67 - glLoadTransposeMatrixf(viewmat[0]); 10.68 + glLoadTransposeMatrixf(lt_viewmat[0]); 10.69 10.70 glGetIntegerv(GL_VIEWPORT, prev_vp); 10.71 glViewport(0, 0, tex_sz, tex_sz); 10.72 10.73 - glCullFace(GL_FRONT); 10.74 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 10.75 + 10.76 + glPolygonOffset(2, 2); 10.77 + glEnable(GL_POLYGON_OFFSET_FILL); 10.78 + 10.79 + glClear(GL_DEPTH_BUFFER_BIT); 10.80 + glUseProgram(0); 10.81 } 10.82 10.83 10.84 void end_shadow_pass() 10.85 { 10.86 + shadow_pass = false; 10.87 + 10.88 glBindFramebuffer(GL_FRAMEBUFFER, 0); 10.89 - glCullFace(GL_BACK); 10.90 10.91 glViewport(prev_vp[0], prev_vp[1], prev_vp[2], prev_vp[3]); 10.92 10.93 @@ -100,6 +115,22 @@ 10.94 Matrix4x4 get_shadow_matrix() 10.95 { 10.96 return shadow_mat; 10.97 + 10.98 + /* 10.99 + glMatrixMode(GL_MODELVIEW); 10.100 + glPushMatrix(); 10.101 + glLoadIdentity(); 10.102 + gluPerspective(lfov * 2.0, 1.0, 0.5, 50.0); 10.103 + gluLookAt(lpos.x, lpos.y, lpos.z, ltarg.x, ltarg.y, ltarg.z, 0, 1, 0); 10.104 + 10.105 + float mat[16]; 10.106 + glGetFloatv(GL_MODELVIEW_MATRIX, mat); 10.107 + 10.108 + Matrix4x4 res; 10.109 + memcpy(res[0], mat, sizeof mat); 10.110 + res.transpose(); 10.111 + return res; 10.112 + */ 10.113 } 10.114 10.115 unsigned int get_shadow_tex()