tavli
changeset 18:986c0b76513f
shadows, not completed
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 29 Jun 2015 01:29:36 +0300 |
parents | 16a420432aa3 |
children | 37dead56f01e |
files | sdr/shadow-notex.p.glsl sdr/shadow.p.glsl sdr/shadow.v.glsl src/board.cc src/game.cc src/game.h src/opengl.c src/opengl.h src/opt.cc src/opt.h src/scenery.cc src/shadow.cc src/shadow.h |
diffstat | 13 files changed, 306 insertions(+), 26 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/sdr/shadow-notex.p.glsl Mon Jun 29 01:29:36 2015 +0300 1.3 @@ -0,0 +1,29 @@ 1.4 +/* vi: set ft=glsl */ 1.5 +uniform sampler2DShadow shadowmap; 1.6 + 1.7 +varying vec3 vdir, ldir, normal; 1.8 +varying vec4 shadow_tc; 1.9 + 1.10 +#define KD gl_FrontMaterial.diffuse.rgb 1.11 +#define KS gl_FrontMaterial.specular.rgb 1.12 +#define SPOW gl_FrontMaterial.shininess 1.13 + 1.14 +void main() 1.15 +{ 1.16 + float shadow = shadow2DProj(shadowmap, shadow_tc).x; 1.17 + 1.18 + vec3 n = normalize(normal); 1.19 + vec3 v = normalize(vdir); 1.20 + vec3 l = normalize(ldir); 1.21 + vec3 h = normalize(l + v); 1.22 + 1.23 + float ndotl = max(dot(n, l), 0.0); 1.24 + float ndoth = max(dot(n, h), 0.0); 1.25 + 1.26 + vec3 diffuse = KD * gl_LightSource[0].diffuse.rgb * ndotl; 1.27 + vec3 specular = KS * gl_LightSource[0].specular.rgb * pow(ndoth, SPOW); 1.28 + 1.29 + vec3 ambient = gl_LightModel.ambient.rgb * KD; 1.30 + gl_FragColor.rgb = ambient + (diffuse + specular) * shadow; 1.31 + gl_FragColor.a = gl_FrontMaterial.diffuse.a; 1.32 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/sdr/shadow.p.glsl Mon Jun 29 01:29:36 2015 +0300 2.3 @@ -0,0 +1,32 @@ 2.4 +/* vi: set ft=glsl */ 2.5 +uniform sampler2D tex; 2.6 +uniform sampler2DShadow shadowmap; 2.7 + 2.8 +varying vec3 vdir, ldir, normal; 2.9 +varying vec4 shadow_tc; 2.10 + 2.11 +#define KD gl_FrontMaterial.diffuse.rgb 2.12 +#define KS gl_FrontMaterial.specular.rgb 2.13 +#define SPOW gl_FrontMaterial.shininess 2.14 + 2.15 +void main() 2.16 +{ 2.17 + float shadow = shadow2DProj(shadowmap, shadow_tc).x; 2.18 + vec4 texel = texture2D(tex, gl_TexCoord[0].st); 2.19 + 2.20 + vec3 n = normalize(normal); 2.21 + vec3 v = normalize(vdir); 2.22 + vec3 l = normalize(ldir); 2.23 + vec3 h = normalize(l + v); 2.24 + 2.25 + float ndotl = max(dot(n, l), 0.0); 2.26 + float ndoth = max(dot(n, h), 0.0); 2.27 + 2.28 + vec3 albedo = KD * texel.rgb; 2.29 + vec3 diffuse = albedo * gl_LightSource[0].diffuse.rgb * ndotl; 2.30 + vec3 specular = KS * gl_LightSource[0].specular.rgb * pow(ndoth, SPOW); 2.31 + 2.32 + vec3 ambient = gl_LightModel.ambient.rgb * albedo; 2.33 + gl_FragColor.rgb = ambient + (diffuse + specular) * shadow; 2.34 + gl_FragColor.a = gl_FrontMaterial.diffuse.a * texel.a; 2.35 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/sdr/shadow.v.glsl Mon Jun 29 01:29:36 2015 +0300 3.3 @@ -0,0 +1,22 @@ 3.4 +varying vec3 vdir, ldir, normal; 3.5 +varying vec4 shadow_tc; 3.6 + 3.7 +void main() 3.8 +{ 3.9 + gl_Position = ftransform(); 3.10 + 3.11 + vec3 vpos = (gl_ModelViewMatrix * gl_Vertex).xyz; 3.12 + normal = gl_NormalMatrix * gl_Normal; 3.13 + vdir = -vpos; 3.14 + ldir = gl_LightSource[0].position.xyz - vpos; 3.15 + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; 3.16 + 3.17 + mat4 offmat = mat4(0.5, 0.0, 0.0, 0.0, 3.18 + 0.0, 0.5, 0.0, 0.0, 3.19 + 0.0, 0.0, 0.5, 0.0, 3.20 + 0.5, 0.5, 0.5, 1.0); 3.21 + mat4 tex_matrix = offmat * gl_TextureMatrix[1]; 3.22 + 3.23 + shadow_tc = tex_matrix * gl_Vertex; 3.24 + shadow_tc = shadow_tc / shadow_tc.w; 3.25 +}
4.1 --- a/src/board.cc Sun Jun 28 23:04:37 2015 +0300 4.2 +++ b/src/board.cc Mon Jun 29 01:29:36 2015 +0300 4.3 @@ -21,6 +21,28 @@ 4.4 #define PIECES_PER_LAYER 5 4.5 4.6 4.7 +static const vec2_t piece_cp[] = { 4.8 + {0, 0.25}, 4.9 + {1, 0.25}, // mid0 4.10 + {2, 0.5}, 4.11 + {2.5, 0.5}, // mid1 4.12 + {3, 0.5}, 4.13 + {4, 0.5}, // mid2 4.14 + {4, 0}, 4.15 + {4, -0.5}, // mid3 4.16 + {3, -0.5}, 4.17 + {2.5, -0.5}, // mid4 4.18 + {0, -0.5} 4.19 +}; 4.20 +static const BezCurve piece_curve = { 4.21 + sizeof piece_cp / sizeof *piece_cp, 4.22 + (vec2_t*)piece_cp, 4.23 + 0.25 * PIECE_RAD 4.24 +}; 4.25 + 4.26 +#define PIECE_HEIGHT (0.25 * PIECE_RAD) 4.27 + 4.28 + 4.29 Piece::Piece() 4.30 { 4.31 owner = 0; 4.32 @@ -138,7 +160,7 @@ 4.33 int layer = level / PIECES_PER_LAYER; 4.34 int layer_level = level % PIECES_PER_LAYER; 4.35 4.36 - pos.y = (layer + 1) * 0.25 * PIECE_RAD; 4.37 + pos.y = (layer + 0.5) * PIECE_HEIGHT; 4.38 4.39 pos.z = (-VSIZE * 0.5 + PIECE_RAD + PIECE_RAD * 2.0 * layer_level); 4.40 if(top_side) { 4.41 @@ -168,28 +190,13 @@ 4.42 } 4.43 4.44 4.45 -static const vec2_t piece_cp[] = { 4.46 - {0, 0.25}, 4.47 - {1, 0.25}, // mid0 4.48 - {2, 0.5}, 4.49 - {2.5, 0.5}, // mid1 4.50 - {3, 0.5}, 4.51 - {4, 0.5}, // mid2 4.52 - {4, 0}, 4.53 - {4, -0.5}, // mid3 4.54 - {3, -0.5}, 4.55 - {2.5, -0.5}, // mid4 4.56 - {0, -0.5} 4.57 -}; 4.58 -static const BezCurve piece_curve = { 4.59 - sizeof piece_cp / sizeof *piece_cp, 4.60 - (vec2_t*)piece_cp, 4.61 - 0.25 * PIECE_RAD 4.62 -}; 4.63 - 4.64 - 4.65 bool Board::generate() 4.66 { 4.67 + static const float board_spec = 0.4; 4.68 + bool use_shadows = opt.shadows && sdr_shadow; 4.69 + unsigned int board_sdr = use_shadows ? sdr_shadow : sdr_phong; 4.70 + unsigned int piece_sdr = use_shadows ? sdr_shadow_notex : sdr_phong_notex; 4.71 + 4.72 Mesh tmp; 4.73 Matrix4x4 xform; 4.74 4.75 @@ -208,6 +215,8 @@ 4.76 obottom->set_mesh(bottom); 4.77 obottom->xform().set_translation(Vector3(sign * BOARD_OFFSET, 0, 0)); 4.78 obottom->set_texture(img_field.texture()); 4.79 + obottom->set_shader(board_sdr); 4.80 + obottom->mtl.specular = Vector3(board_spec, board_spec, board_spec); 4.81 obj.push_back(obottom); 4.82 4.83 4.84 @@ -248,6 +257,8 @@ 4.85 osides->set_texture(img_wood.texture()); 4.86 osides->tex_xform().set_scaling(Vector3(2, 2, 2)); 4.87 osides->tex_xform().rotate(-Vector3(1, 0, 0.5), M_PI / 4.0); 4.88 + osides->mtl.specular = Vector3(board_spec, board_spec, board_spec); 4.89 + osides->set_shader(board_sdr); 4.90 obj.push_back(osides); 4.91 4.92 } 4.93 @@ -321,7 +332,7 @@ 4.94 opiece->mtl.diffuse = Vector3(0.6, 0.6, 0.6); 4.95 opiece->mtl.specular = Vector3(0.8, 0.8, 0.8); 4.96 opiece->xform().set_translation(Vector3(0, 0.2, 0)); 4.97 - opiece->set_shader(sdr_phong_notex); 4.98 + opiece->set_shader(piece_sdr); 4.99 //obj.push_back(opiece); 4.100 4.101 piece_obj = opiece;
5.1 --- a/src/game.cc Sun Jun 28 23:04:37 2015 +0300 5.2 +++ b/src/game.cc Mon Jun 29 01:29:36 2015 +0300 5.3 @@ -1,15 +1,20 @@ 5.4 #include <stdio.h> 5.5 +#include <assert.h> 5.6 #include "opengl.h" 5.7 #include "game.h" 5.8 #include "board.h" 5.9 #include "scenery.h" 5.10 #include "sdr.h" 5.11 +#include "shadow.h" 5.12 +#include "opt.h" 5.13 5.14 +static void draw_scene(); 5.15 static void draw_backdrop(); 5.16 5.17 int win_width, win_height; 5.18 unsigned long cur_time; 5.19 unsigned int sdr_phong, sdr_phong_notex; 5.20 +unsigned int sdr_shadow, sdr_shadow_notex; 5.21 bool wireframe; 5.22 5.23 static Board board; 5.24 @@ -48,6 +53,20 @@ 5.25 if(!(sdr_phong_notex = create_program_load("sdr/phong.v.glsl", "sdr/phong-notex.p.glsl"))) { 5.26 return false; 5.27 } 5.28 + 5.29 + if(glcaps.fbo) { 5.30 + init_shadow(512); 5.31 + 5.32 + if(!(sdr_shadow = create_program_load("sdr/shadow.v.glsl", "sdr/shadow.p.glsl"))) { 5.33 + return false; 5.34 + } 5.35 + set_uniform_int(sdr_shadow, "tex", 0); 5.36 + set_uniform_int(sdr_shadow, "shadowmap", 1); 5.37 + 5.38 + if(!(sdr_shadow_notex = create_program_load("sdr/shadow.v.glsl", "sdr/shadow-notex.p.glsl"))) { 5.39 + return false; 5.40 + } 5.41 + } 5.42 } 5.43 5.44 if(!board.init()) { 5.45 @@ -59,6 +78,7 @@ 5.46 return false; 5.47 } 5.48 5.49 + assert(glGetError() == GL_NO_ERROR); 5.50 return true; 5.51 } 5.52 5.53 @@ -66,6 +86,7 @@ 5.54 { 5.55 board.destroy(); 5.56 destroy_scenery(); 5.57 + destroy_shadow(); 5.58 } 5.59 5.60 void game_update(unsigned long time_msec) 5.61 @@ -86,15 +107,44 @@ 5.62 float ldir[] = {-10, 20, 10, 1}; 5.63 glLightfv(GL_LIGHT0, GL_POSITION, ldir); 5.64 5.65 - draw_backdrop(); 5.66 - draw_scenery(); 5.67 - board.draw(); 5.68 + if(opt.shadows && sdr_shadow) { 5.69 + printf("shadow pass\n"); 5.70 + 5.71 + begin_shadow_pass(Vector3(-10, 20, 10), Vector3(0, 0, 0), 25); 5.72 + draw_scene(); 5.73 + end_shadow_pass(); 5.74 + 5.75 + glActiveTexture(GL_TEXTURE1); 5.76 + glBindTexture(GL_TEXTURE_2D, get_shadow_tex()); 5.77 + 5.78 + glMatrixMode(GL_TEXTURE); 5.79 + Matrix4x4 shadow_matrix = get_shadow_matrix(); 5.80 + glLoadMatrixf(shadow_matrix[0]); 5.81 + 5.82 + glActiveTexture(GL_TEXTURE0); 5.83 + glMatrixMode(GL_MODELVIEW); 5.84 + 5.85 + draw_scene(); 5.86 + 5.87 + glActiveTexture(GL_TEXTURE1); 5.88 + glBindTexture(GL_TEXTURE_2D, 0); 5.89 + glActiveTexture(GL_TEXTURE0); 5.90 + } else { 5.91 + draw_scene(); 5.92 + } 5.93 5.94 if(dbg_busyloop) { 5.95 redisplay(); 5.96 } 5.97 } 5.98 5.99 +static void draw_scene() 5.100 +{ 5.101 + draw_backdrop(); 5.102 + draw_scenery(); 5.103 + board.draw(); 5.104 +} 5.105 + 5.106 static void draw_backdrop() 5.107 { 5.108 glPushAttrib(GL_ENABLE_BIT); 5.109 @@ -150,6 +200,11 @@ 5.110 dbg_busyloop = !dbg_busyloop; 5.111 redisplay(); 5.112 break; 5.113 + 5.114 + case 's': 5.115 + opt.shadows = !opt.shadows; 5.116 + redisplay(); 5.117 + break; 5.118 } 5.119 } 5.120 }
6.1 --- a/src/game.h Sun Jun 28 23:04:37 2015 +0300 6.2 +++ b/src/game.h Mon Jun 29 01:29:36 2015 +0300 6.3 @@ -3,6 +3,7 @@ 6.4 6.5 extern int win_width, win_height; 6.6 extern unsigned int sdr_phong, sdr_phong_notex; 6.7 +extern unsigned int sdr_shadow, sdr_shadow_notex; 6.8 extern unsigned long cur_time; 6.9 6.10 extern bool wireframe;
7.1 --- a/src/opengl.c Sun Jun 28 23:04:37 2015 +0300 7.2 +++ b/src/opengl.c Mon Jun 29 01:29:36 2015 +0300 7.3 @@ -9,6 +9,7 @@ 7.4 glcaps.shaders = GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader; 7.5 glcaps.fsaa = GLEW_ARB_multisample; 7.6 glcaps.sep_spec = GLEW_EXT_separate_specular_color; 7.7 + glcaps.fbo = GLEW_ARB_framebuffer_object; 7.8 7.9 return 0; 7.10 }
8.1 --- a/src/opengl.h Sun Jun 28 23:04:37 2015 +0300 8.2 +++ b/src/opengl.h Mon Jun 29 01:29:36 2015 +0300 8.3 @@ -7,6 +7,7 @@ 8.4 int shaders; 8.5 int fsaa; 8.6 int sep_spec; 8.7 + int fbo; 8.8 }; 8.9 extern struct GLCaps glcaps; 8.10
9.1 --- a/src/opt.cc Sun Jun 28 23:04:37 2015 +0300 9.2 +++ b/src/opt.cc Mon Jun 29 01:29:36 2015 +0300 9.3 @@ -10,6 +10,8 @@ 9.4 opt.xres = 1280; 9.5 opt.yres = 800; 9.6 opt.fullscreen = false; 9.7 + opt.shadows = false; opt.reflections = true; 9.8 + 9.9 opt.def_username = opt.saved_passwd = 0; 9.10 9.11 opt.piece_color[0] = v3_cons(0.3, 0.35, 0.6);
10.1 --- a/src/opt.h Sun Jun 28 23:04:37 2015 +0300 10.2 +++ b/src/opt.h Mon Jun 29 01:29:36 2015 +0300 10.3 @@ -6,6 +6,7 @@ 10.4 struct Options { 10.5 int xres, yres; 10.6 bool fullscreen; 10.7 + bool shadows, reflections; 10.8 10.9 char *def_username, *saved_passwd; 10.10
11.1 --- a/src/scenery.cc Sun Jun 28 23:04:37 2015 +0300 11.2 +++ b/src/scenery.cc Mon Jun 29 01:29:36 2015 +0300 11.3 @@ -8,6 +8,7 @@ 11.4 #include "revol.h" 11.5 #include "image.h" 11.6 #include "sdr.h" 11.7 +#include "opt.h" 11.8 11.9 static bool gen_textures(); 11.10 11.11 @@ -33,6 +34,7 @@ 11.12 11.13 bool init_scenery() 11.14 { 11.15 + unsigned int sdr = opt.shadows && sdr_shadow ? sdr_shadow : sdr_phong; 11.16 if(!gen_textures()) { 11.17 return false; 11.18 } 11.19 @@ -56,7 +58,7 @@ 11.20 otable->mtl.specular = Vector3(0.7, 0.7, 0.7); 11.21 otable->xform().set_translation(Vector3(0, -0.025, 0)); 11.22 otable->set_texture(img_marble.texture()); 11.23 - otable->set_shader(sdr_phong); 11.24 + otable->set_shader(sdr); 11.25 obj.push_back(otable); 11.26 11.27
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/shadow.cc Mon Jun 29 01:29:36 2015 +0300 12.3 @@ -0,0 +1,108 @@ 12.4 +#include <assert.h> 12.5 +#include "opengl.h" 12.6 +#include "shadow.h" 12.7 +#include "vmath/vmath.h" 12.8 + 12.9 +static int tex_sz, prev_vp[4]; 12.10 +static unsigned int fbo, depth_tex, rb_color; 12.11 +static Matrix4x4 shadow_mat; 12.12 + 12.13 +bool init_shadow(int sz) 12.14 +{ 12.15 + if(!glcaps.fbo) { 12.16 + return true; 12.17 + } 12.18 + 12.19 + tex_sz = sz; 12.20 + 12.21 + glGenFramebuffers(1, &fbo); 12.22 + glBindFramebuffer(GL_FRAMEBUFFER, fbo); 12.23 + 12.24 + glGenTextures(1, &depth_tex); 12.25 + glBindTexture(GL_TEXTURE_2D, depth_tex); 12.26 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 12.27 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 12.28 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 12.29 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 12.30 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); 12.31 + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, tex_sz, tex_sz, 0, 12.32 + GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0); 12.33 + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_tex, 0); 12.34 + 12.35 + assert(glGetError() == GL_NO_ERROR); 12.36 + 12.37 + glDrawBuffer(GL_FALSE); 12.38 + glReadBuffer(GL_FALSE); 12.39 + 12.40 + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { 12.41 + fprintf(stderr, "incomplete framebuffer\n"); 12.42 + return false; 12.43 + } 12.44 + 12.45 + glBindFramebuffer(GL_FRAMEBUFFER, 0); 12.46 + glDrawBuffer(GL_BACK); 12.47 + glReadBuffer(GL_BACK); 12.48 + assert(glGetError() == GL_NO_ERROR); 12.49 + 12.50 + return true; 12.51 +} 12.52 + 12.53 +void destroy_shadow() 12.54 +{ 12.55 + glDeleteTextures(1, &depth_tex); 12.56 + glDeleteRenderbuffers(1, &rb_color); 12.57 + glDeleteFramebuffers(1, &fbo); 12.58 +} 12.59 + 12.60 +void begin_shadow_pass(const Vector3 &lpos, const Vector3 <arg, float lfov) 12.61 +{ 12.62 + Matrix4x4 viewmat, projmat; 12.63 + 12.64 + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT); 12.65 + glDisable(GL_LIGHTING); 12.66 + glColorMask(0, 0, 0, 0); 12.67 + glDepthMask(1); 12.68 + 12.69 + projmat.set_perspective(DEG_TO_RAD(lfov) * 2.0, 1.0, 0.5, 500.0); 12.70 + viewmat.set_lookat(lpos, ltarg, Vector3(0, 1, 0)); 12.71 + shadow_mat = viewmat * projmat; 12.72 + 12.73 + glMatrixMode(GL_PROJECTION); 12.74 + glPushMatrix(); 12.75 + glLoadTransposeMatrixf(projmat[0]); 12.76 + glMatrixMode(GL_MODELVIEW); 12.77 + glPushMatrix(); 12.78 + glLoadTransposeMatrixf(viewmat[0]); 12.79 + 12.80 + glGetIntegerv(GL_VIEWPORT, prev_vp); 12.81 + glViewport(0, 0, tex_sz, tex_sz); 12.82 + 12.83 + glCullFace(GL_FRONT); 12.84 + glBindFramebuffer(GL_FRAMEBUFFER, fbo); 12.85 +} 12.86 + 12.87 + 12.88 +void end_shadow_pass() 12.89 +{ 12.90 + glBindFramebuffer(GL_FRAMEBUFFER, 0); 12.91 + glCullFace(GL_BACK); 12.92 + 12.93 + glViewport(prev_vp[0], prev_vp[1], prev_vp[2], prev_vp[3]); 12.94 + 12.95 + glMatrixMode(GL_PROJECTION); 12.96 + glPopMatrix(); 12.97 + glMatrixMode(GL_MODELVIEW); 12.98 + glPopMatrix(); 12.99 + 12.100 + glPopAttrib(); 12.101 +} 12.102 + 12.103 +Matrix4x4 get_shadow_matrix() 12.104 +{ 12.105 + return shadow_mat; 12.106 +} 12.107 + 12.108 +unsigned int get_shadow_tex() 12.109 +{ 12.110 + return depth_tex; 12.111 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/src/shadow.h Mon Jun 29 01:29:36 2015 +0300 13.3 @@ -0,0 +1,15 @@ 13.4 +#ifndef SHADOW_H_ 13.5 +#define SHADOW_H_ 13.6 + 13.7 +#include "vmath/vmath.h" 13.8 + 13.9 +bool init_shadow(int sz); 13.10 +void destroy_shadow(); 13.11 + 13.12 +void begin_shadow_pass(const Vector3 &lpos, const Vector3 <arg, float lfov); 13.13 +void end_shadow_pass(); 13.14 + 13.15 +Matrix4x4 get_shadow_matrix(); 13.16 +unsigned int get_shadow_tex(); 13.17 + 13.18 +#endif // SHADOW_H_