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 &ltarg, 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()
    11.1 --- a/src/shadow.h	Mon Jun 29 01:29:36 2015 +0300
    11.2 +++ b/src/shadow.h	Mon Jun 29 06:18:45 2015 +0300
    11.3 @@ -3,6 +3,8 @@
    11.4  
    11.5  #include "vmath/vmath.h"
    11.6  
    11.7 +extern bool shadow_pass;
    11.8 +
    11.9  bool init_shadow(int sz);
   11.10  void destroy_shadow();
   11.11