tavli

changeset 22:c2a2069a49ec

slot highlighting, TODO blur
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 07 Jul 2015 21:56:37 +0300
parents c3fbf9616dbd
children 3e6430028d54
files src/board.cc src/board.h src/game.cc src/game.h src/image.cc src/image.h src/scenery.cc
diffstat 7 files changed, 141 insertions(+), 47 deletions(-) [+]
line diff
     1.1 --- a/src/board.cc	Thu Jul 02 00:01:39 2015 +0300
     1.2 +++ b/src/board.cc	Tue Jul 07 21:56:37 2015 +0300
     1.3 @@ -85,6 +85,7 @@
     1.4  Board::Board()
     1.5  {
     1.6  	piece_obj = 0;
     1.7 +	slot_sel = -1;
     1.8  	clear();
     1.9  
    1.10  	for(int i=0; i<NUM_SLOTS; i++) {
    1.11 @@ -208,6 +209,16 @@
    1.12  	return -1;
    1.13  }
    1.14  
    1.15 +void Board::select_slot(int idx)
    1.16 +{
    1.17 +	slot_sel = idx < 0 || idx >= NUM_SLOTS ? -1 : idx;
    1.18 +}
    1.19 +
    1.20 +int Board::get_selected_slot() const
    1.21 +{
    1.22 +	return slot_sel;
    1.23 +}
    1.24 +
    1.25  void Board::draw() const
    1.26  {
    1.27  	bool use_shadows = opt.shadows && sdr_shadow;
    1.28 @@ -232,38 +243,50 @@
    1.29  		piece_obj->draw();
    1.30  	}
    1.31  
    1.32 -	// draw the slot bounds
    1.33 -	/*
    1.34 -	static const float pal[][3] = {
    1.35 +	/*static const float pal[][3] = {
    1.36  		{1, 0, 0},
    1.37  		{0, 1, 0},
    1.38  		{0, 0, 1},
    1.39  		{1, 1, 0},
    1.40  		{0, 1, 1},
    1.41  		{1, 0, 1}
    1.42 -	};
    1.43 -	int idx = dbg_int % NUM_SLOTS;
    1.44 +	};*/
    1.45 +	int idx = slot_sel % NUM_SLOTS;
    1.46  	if(idx >= 0) {
    1.47  		glUseProgram(0);
    1.48  
    1.49  		glPushAttrib(GL_ENABLE_BIT);
    1.50  		glDisable(GL_LIGHTING);
    1.51  		glDisable(GL_CULL_FACE);
    1.52 -		glDisable(GL_DEPTH_TEST);
    1.53 +		glEnable(GL_DEPTH_TEST);
    1.54 +		glEnable(GL_TEXTURE_2D);
    1.55 +		glBindTexture(GL_TEXTURE_2D, img_highlight.texture());
    1.56 +		glEnable(GL_BLEND);
    1.57 +		glBlendFunc(GL_SRC_ALPHA, GL_ONE);
    1.58 +
    1.59 +		glDepthMask(0);
    1.60  
    1.61  		glBegin(GL_TRIANGLES);
    1.62 -		glColor3fv(pal[idx % (sizeof pal / sizeof *pal)]);
    1.63 +		//glColor3fv(pal[idx % (sizeof pal / sizeof *pal)]);
    1.64 +		glColor4f(1, 1, 1, 0.4);
    1.65 +		glTexCoord2f(0, 0);
    1.66  		glVertex3f(slotbb[idx].tri0.v[0].x, slotbb[idx].tri0.v[0].y, slotbb[idx].tri0.v[0].z);
    1.67 +		glTexCoord2f(1, 0);
    1.68  		glVertex3f(slotbb[idx].tri0.v[1].x, slotbb[idx].tri0.v[1].y, slotbb[idx].tri0.v[1].z);
    1.69 +		glTexCoord2f(1, 1);
    1.70  		glVertex3f(slotbb[idx].tri0.v[2].x, slotbb[idx].tri0.v[2].y, slotbb[idx].tri0.v[2].z);
    1.71 +		glTexCoord2f(0, 0);
    1.72  		glVertex3f(slotbb[idx].tri1.v[0].x, slotbb[idx].tri1.v[0].y, slotbb[idx].tri1.v[0].z);
    1.73 +		glTexCoord2f(1, 1);
    1.74  		glVertex3f(slotbb[idx].tri1.v[1].x, slotbb[idx].tri1.v[1].y, slotbb[idx].tri1.v[1].z);
    1.75 +		glTexCoord2f(0, 1);
    1.76  		glVertex3f(slotbb[idx].tri1.v[2].x, slotbb[idx].tri1.v[2].y, slotbb[idx].tri1.v[2].z);
    1.77  		glEnd();
    1.78  
    1.79 +		glDepthMask(1);
    1.80 +
    1.81  		glPopAttrib();
    1.82  	}
    1.83 -	*/
    1.84  	// TODO slot highlighting
    1.85  }
    1.86  
    1.87 @@ -477,6 +500,21 @@
    1.88  	return sqrt(x * x + y * y) < rad;
    1.89  }
    1.90  
    1.91 +static bool field_pattern(float x, float y)
    1.92 +{
    1.93 +	y = y < 0.5 ? y * 2.0 : 2.0 - y * 2.0;
    1.94 +	bool inside = false;
    1.95 +
    1.96 +	inside |= (spike(x, y + 0.33333) && !spike(x, y + 0.4)) ||
    1.97 +		(spike(x, y + 0.5) && !spike(x, y + 0.68));
    1.98 +	inside |= (circle(x, y, 0.12) && !circle(x, y, 0.1)) || circle(x, y, 0.06);
    1.99 +	inside |= (diamond(x, y) && !diamond(x, y - 0.015)) ||
   1.100 +		(diamond(x, y - 0.023) && !diamond(x, y - 0.028));
   1.101 +	inside |= center_circle(x, y, 0.03);
   1.102 +
   1.103 +	return inside;
   1.104 +}
   1.105 +
   1.106  bool Board::generate_textures()
   1.107  {
   1.108  	// ---- board field texture ----
   1.109 @@ -492,39 +530,49 @@
   1.110  		for(int j=0; j<img_field.width; j++) {
   1.111  			float u = (float)j / (float)img_field.width;
   1.112  
   1.113 -			int r = 0, g = 0, b = 0;
   1.114 +			// pattern mask
   1.115 +			bool inside = field_pattern(u, v);
   1.116  
   1.117  			float wood_val = wood(u, v);
   1.118 -
   1.119 -			// pattern mask
   1.120 -			float x = u;
   1.121 -			float y = v < 0.5 ? v * 2.0 : 2.0 - v * 2.0;
   1.122 -			bool inside = false;
   1.123 -
   1.124 -			inside |= (spike(x, y + 0.33333) && !spike(x, y + 0.4)) ||
   1.125 -				(spike(x, y + 0.5) && !spike(x, y + 0.68));
   1.126 -			inside |= (circle(x, y, 0.12) && !circle(x, y, 0.1)) || circle(x, y, 0.06);
   1.127 -			inside |= (diamond(x, y) && !diamond(x, y - 0.015)) ||
   1.128 -				(diamond(x, y - 0.023) && !diamond(x, y - 0.028));
   1.129 -			inside |= center_circle(x, y, 0.03);
   1.130 -
   1.131  			Vector3 wood_color = lerp(wcol1, wcol2, wood_val) * 0.9;
   1.132  			if(inside) {
   1.133  				wood_color = lerp(wcol1, wcol2, 1.0 - wood_val) * 2.0;
   1.134  			}
   1.135  
   1.136 -			r = (int)(wood_color.x * 255.0);
   1.137 -			g = (int)(wood_color.y * 255.0);
   1.138 -			b = (int)(wood_color.z * 255.0);
   1.139 +			int r = (int)(wood_color.x * 255.0);
   1.140 +			int g = (int)(wood_color.y * 255.0);
   1.141 +			int b = (int)(wood_color.z * 255.0);
   1.142  
   1.143  			pptr[0] = r > 255 ? 255 : r;
   1.144  			pptr[1] = g > 255 ? 255 : g;
   1.145  			pptr[2] = b > 255 ? 255 : b;
   1.146 -			pptr += 3;
   1.147 +			pptr[3] = 255;
   1.148 +			pptr += 4;
   1.149  		}
   1.150  	}
   1.151  	img_field.texture();
   1.152  
   1.153 +
   1.154 +	// ---- slot highlighting texture ----
   1.155 +	img_highlight.create(128, 256);
   1.156 +	pptr = img_highlight.pixels;
   1.157 +	for(int i=0; i<img_highlight.height; i++) {
   1.158 +		float v = (float)i / (float)img_highlight.height;
   1.159 +		for(int j=0; j<img_highlight.width; j++) {
   1.160 +			float u = (float)j / (float)img_highlight.width;
   1.161 +
   1.162 +			bool inside = field_pattern(u / 5.0, v * 0.445);
   1.163 +
   1.164 +			pptr[0] = 255;
   1.165 +			pptr[1] = 255;
   1.166 +			pptr[2] = 255;
   1.167 +			pptr[3] = inside ? 255 : 0;
   1.168 +			pptr += 4;
   1.169 +		}
   1.170 +	}
   1.171 +	img_highlight.texture();
   1.172 +
   1.173 +
   1.174  	// ---- generic wood texture ----
   1.175  	img_wood.create(256, 256);
   1.176  	pptr = img_wood.pixels;
   1.177 @@ -543,7 +591,8 @@
   1.178  			pptr[0] = r > 255 ? 255 : r;
   1.179  			pptr[1] = g > 255 ? 255 : g;
   1.180  			pptr[2] = b > 255 ? 255 : b;
   1.181 -			pptr += 3;
   1.182 +			pptr[3] = 255;
   1.183 +			pptr += 4;
   1.184  		}
   1.185  	}
   1.186  	img_wood.texture();
   1.187 @@ -576,8 +625,9 @@
   1.188  			pptr[0] = r > 255 ? 255 : (r < 0 ? 0 : r);
   1.189  			pptr[1] = g > 255 ? 255 : (g < 0 ? 0 : g);
   1.190  			pptr[2] = b > 255 ? 255 : (b < 0 ? 0 : b);
   1.191 +			pptr[3] = 255;
   1.192  
   1.193 -			pptr += 3;
   1.194 +			pptr += 4;
   1.195  		}
   1.196  	}
   1.197  	img_hinge.texture();
     2.1 --- a/src/board.h	Thu Jul 02 00:01:39 2015 +0300
     2.2 +++ b/src/board.h	Tue Jul 07 21:56:37 2015 +0300
     2.3 @@ -41,11 +41,12 @@
     2.4  	Piece pieces[MAX_PIECES];
     2.5  	int hist[NUM_SLOTS + 1];
     2.6  	Quad slotbb[NUM_SLOTS];
     2.7 +	int slot_sel;	// current slot selection
     2.8  
     2.9  	std::vector<Object*> obj;
    2.10  	Object *piece_obj;
    2.11  
    2.12 -	Image img_wood, img_field, img_hinge;
    2.13 +	Image img_wood, img_field, img_hinge, img_highlight;
    2.14  
    2.15  	bool generate();
    2.16  	bool generate_textures();
    2.17 @@ -66,6 +67,8 @@
    2.18  	Vector3 piece_pos(int slot, int level = 0) const;
    2.19  
    2.20  	int slot_hit(const Ray &ray) const;
    2.21 +	void select_slot(int idx);
    2.22 +	int get_selected_slot() const;
    2.23  
    2.24  	void draw() const;
    2.25  };
     3.1 --- a/src/game.cc	Thu Jul 02 00:01:39 2015 +0300
     3.2 +++ b/src/game.cc	Tue Jul 07 21:56:37 2015 +0300
     3.3 @@ -19,6 +19,8 @@
     3.4  bool wireframe;
     3.5  int dbg_int;
     3.6  
     3.7 +Ray pick_ray;
     3.8 +
     3.9  static Board board;
    3.10  
    3.11  static float cam_theta, cam_phi = 45, cam_dist = 3;
    3.12 @@ -289,13 +291,29 @@
    3.13  
    3.14  		if(cam_phi < -90) cam_phi = -90;
    3.15  		if(cam_phi > 90) cam_phi = 90;
    3.16 -
    3.17 -		redisplay();
    3.18  	}
    3.19  	if(bnstate[2]) {
    3.20  		cam_dist += dy * 0.1;
    3.21  		if(cam_dist < 0.0) cam_dist = 0.0;
    3.22 +	}
    3.23  
    3.24 -		redisplay();
    3.25 -	}
    3.26 +	// in all cases construct the global pick ray
    3.27 +	double viewmat[16], projmat[16];
    3.28 +	int vp[4], ysz;
    3.29 +	double px, py, pz;
    3.30 +
    3.31 +	glGetIntegerv(GL_VIEWPORT, vp);
    3.32 +	glGetDoublev(GL_MODELVIEW_MATRIX, viewmat);
    3.33 +	glGetDoublev(GL_PROJECTION_MATRIX, projmat);
    3.34 +
    3.35 +	ysz = vp[3] - vp[1];
    3.36 +
    3.37 +	gluUnProject(x, ysz - y, 0, viewmat, projmat, vp, &px, &py, &pz);
    3.38 +	pick_ray.origin = Vector3(px, py, pz);
    3.39 +	gluUnProject(x, ysz - y, 1, viewmat, projmat, vp, &px, &py, &pz);
    3.40 +	pick_ray.dir = Vector3(px, py, pz) - pick_ray.origin;
    3.41 +
    3.42 +	board.select_slot(board.slot_hit(pick_ray));
    3.43 +
    3.44 +	redisplay();
    3.45  }
     4.1 --- a/src/game.h	Thu Jul 02 00:01:39 2015 +0300
     4.2 +++ b/src/game.h	Tue Jul 07 21:56:37 2015 +0300
     4.3 @@ -1,12 +1,16 @@
     4.4  #ifndef GAME_H_
     4.5  #define GAME_H_
     4.6  
     4.7 +#include "vmath/vmath.h"
     4.8 +
     4.9  extern int win_width, win_height;
    4.10  extern unsigned int sdr_phong, sdr_phong_notex;
    4.11  extern unsigned int sdr_shadow, sdr_shadow_notex;
    4.12  extern unsigned int sdr_unlit;
    4.13  extern unsigned long cur_time;
    4.14  
    4.15 +extern Ray pick_ray;
    4.16 +
    4.17  extern bool wireframe;
    4.18  extern int dbg_int;
    4.19  
     5.1 --- a/src/image.cc	Thu Jul 02 00:01:39 2015 +0300
     5.2 +++ b/src/image.cc	Tue Jul 07 21:56:37 2015 +0300
     5.3 @@ -38,7 +38,7 @@
     5.4  	destroy();
     5.5  
     5.6  	try {
     5.7 -		unsigned char *tmp = new unsigned char[width * height * 3];
     5.8 +		unsigned char *tmp = new unsigned char[width * height * 4];
     5.9  		this->pixels = tmp;
    5.10  		this->width = width;
    5.11  		this->height = height;
    5.12 @@ -48,7 +48,7 @@
    5.13  	}
    5.14  
    5.15  	if(pixels) {
    5.16 -		memcpy(this->pixels, pixels, width * height * 3);
    5.17 +		memcpy(this->pixels, pixels, width * height * 4);
    5.18  	}
    5.19  	return true;
    5.20  }
    5.21 @@ -69,7 +69,7 @@
    5.22  bool Image::load(const char *fname)
    5.23  {
    5.24  	int xsz, ysz;
    5.25 -	unsigned char *pix = (unsigned char*)img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGB24);
    5.26 +	unsigned char *pix = (unsigned char*)img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGBA32);
    5.27  	if(!pix) {
    5.28  		return false;
    5.29  	}
    5.30 @@ -96,13 +96,13 @@
    5.31  		if(GLEW_SGIS_generate_mipmap) {
    5.32  			glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, 1);
    5.33  
    5.34 -			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_width, tex_height, 0, GL_RGB, GL_UNSIGNED_BYTE,
    5.35 +			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
    5.36  					width == tex_width && height == tex_height ? pixels : 0);
    5.37  			if(width != tex_width || height != tex_height) {
    5.38 -				glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
    5.39 +				glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    5.40  			}
    5.41  		} else {
    5.42 -			gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, tex_width, tex_height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
    5.43 +			gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, tex_width, tex_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    5.44  		}
    5.45  
    5.46  		if(GLEW_EXT_texture_filter_anisotropic) {
    5.47 @@ -138,28 +138,45 @@
    5.48  
    5.49  void clear_image(Image *img)
    5.50  {
    5.51 -	clear_image(img, 0, 0, 0);
    5.52 +	clear_image(img, 0, 0, 0, 255);
    5.53  }
    5.54  
    5.55 -void clear_image(Image *img, float r, float g, float b)
    5.56 +void clear_image(Image *img, float r, float g, float b, float a)
    5.57  {
    5.58  	if(!img->pixels) {
    5.59  		return;
    5.60  	}
    5.61  
    5.62 -	unsigned char col[3];
    5.63 +	unsigned char col[4];
    5.64  	unsigned char *ptr = img->pixels;
    5.65  	int npix = img->width * img->height;
    5.66  
    5.67  	col[0] = (int)(r * 255.0);
    5.68  	col[1] = (int)(g * 255.0);
    5.69  	col[2] = (int)(b * 255.0);
    5.70 +	col[3] = (int)(a * 255.0);
    5.71  
    5.72  	for(int i=0; i<npix; i++) {
    5.73 -		for(int j=0; j<3; j++) {
    5.74 +		for(int j=0; j<4; j++) {
    5.75  			ptr[j] = col[j];
    5.76  		}
    5.77 -		ptr += 3;
    5.78 +		ptr += 4;
    5.79 +	}
    5.80 +}
    5.81 +
    5.82 +void clear_image_alpha(Image *img, float a)
    5.83 +{
    5.84 +	if(!img->pixels) {
    5.85 +		return;
    5.86 +	}
    5.87 +
    5.88 +	unsigned char alpha = (int)(a * 255.0);
    5.89 +	unsigned char *ptr = img->pixels;
    5.90 +	int npix = img->width * img->height;
    5.91 +
    5.92 +	for(int i=0; i<npix; i++) {
    5.93 +		ptr[3] = alpha;
    5.94 +		ptr += 4;
    5.95  	}
    5.96  }
    5.97  
    5.98 @@ -168,7 +185,7 @@
    5.99  	int xsz = dest->width;
   5.100  	int ysz = dest->height;
   5.101  	int npixels = xsz * ysz;
   5.102 -	int nbytes = npixels * 3;
   5.103 +	int nbytes = npixels * 4;
   5.104  	int tint = (int)(t * 255);
   5.105  
   5.106  	if(aimg->width != xsz || bimg->width != xsz || aimg->height != ysz || bimg->height != ysz) {
     6.1 --- a/src/image.h	Thu Jul 02 00:01:39 2015 +0300
     6.2 +++ b/src/image.h	Tue Jul 07 21:56:37 2015 +0300
     6.3 @@ -30,7 +30,8 @@
     6.4  };
     6.5  
     6.6  void clear_image(Image *img);
     6.7 -void clear_image(Image *img, float r, float g, float b);
     6.8 +void clear_image(Image *img, float r, float g, float b, float a = 255);
     6.9 +void clear_image_alpha(Image *img, float a);
    6.10  
    6.11  enum ImgCombine {
    6.12  	IMG_OP_ADD,
     7.1 --- a/src/scenery.cc	Thu Jul 02 00:01:39 2015 +0300
     7.2 +++ b/src/scenery.cc	Tue Jul 07 21:56:37 2015 +0300
     7.3 @@ -129,7 +129,8 @@
     7.4  			pptr[0] = r > 255 ? 255 : (r < 0 ? 0 : r);
     7.5  			pptr[1] = g > 255 ? 255 : (g < 0 ? 0 : g);
     7.6  			pptr[2] = b > 255 ? 255 : (b < 0 ? 0 : b);
     7.7 -			pptr += 3;
     7.8 +			pptr[3] = 255;
     7.9 +			pptr += 4;
    7.10  		}
    7.11  	}
    7.12  	img_marble.texture();