goat3dgfx

diff src/texture.cc @ 6:3d96734fd477

cubemap loading and cubemap example program
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 17 Nov 2013 08:20:13 +0200
parents 7bd5ebec3b6f
children 25b911c7c35c
line diff
     1.1 --- a/src/texture.cc	Sun Nov 17 03:22:40 2013 +0200
     1.2 +++ b/src/texture.cc	Sun Nov 17 08:20:13 2013 +0200
     1.3 @@ -245,10 +245,10 @@
     1.4  	texfmt = ifmt;
     1.5  
     1.6  	glBindTexture(GL_TEXTURE_CUBE_MAP, id);
     1.7 -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
     1.8 -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     1.9 -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    1.10 -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    1.11 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    1.12 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    1.13 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    1.14 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    1.15  
    1.16  	for(int i=0; i<6; i++) {
    1.17  		glTexImage2D(cube_faces[i], 0, ifmt, xsz, ysz, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
    1.18 @@ -257,12 +257,56 @@
    1.19  
    1.20  void TextureCube::set_image(const Image &img, int idx)
    1.21  {
    1.22 -	// TODO
    1.23 +	texfmt = glifmt_from_imgfmt(img.get_format());
    1.24 +	unsigned int fmt = glfmt_from_ifmt(texfmt);
    1.25 +	unsigned int type = gltype_from_ifmt(texfmt);
    1.26 +
    1.27 +	sz[0] = img.get_width();
    1.28 +	sz[1] = img.get_height();
    1.29 +
    1.30 +	glBindTexture(GL_TEXTURE_CUBE_MAP, id);
    1.31 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    1.32 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    1.33 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    1.34 +	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    1.35 +
    1.36 +	glTexImage2D(cube_faces[idx], 0, texfmt, sz[0], sz[1], 0, fmt, type, img.get_pixels());
    1.37  }
    1.38  
    1.39  bool TextureCube::load(const char *fname)
    1.40  {
    1.41 -	return false;	// TODO
    1.42 +	static const float one_third = 1.0 / 3.0;
    1.43 +	static const float two_thirds = 2.0 / 3.0;
    1.44 +	static const float hcross[2][6] = {
    1.45 +		{0.5, 0.0, 0.25, 0.25, 0.25, 0.75}, {one_third, one_third, 0.0, two_thirds, one_third, one_third} };
    1.46 +	static const float vcross[2][6] = {
    1.47 +		{two_thirds, 0.0, one_third, one_third, one_third, one_third}, {0.25, 0.25, 0.0, 0.5, 0.25, 0.75} };
    1.48 +	static const float hsix[2][6] = {
    1.49 +		{0.0, 0.0, one_third, one_third, two_thirds, two_thirds}, {0.0, 0.5, 0.0, 0.5, 0.0, 0.5} };
    1.50 +
    1.51 +	Image img;
    1.52 +	if(!img.load(fname)) {
    1.53 +		return false;
    1.54 +	}
    1.55 +
    1.56 +	int xsz = img.get_width();
    1.57 +	int ysz = img.get_height();
    1.58 +
    1.59 +	if(xsz / 4 == ysz / 3) {
    1.60 +		// horizontal cross, assume the vertical bit is center-left
    1.61 +		return load_multi(img, hcross[0], hcross[1], xsz / 4);
    1.62 +	}
    1.63 +	if(xsz / 3 == ysz / 4) {
    1.64 +		// vertical cross, assume the horizontal bit is center-top (180-rotated image 5)
    1.65 +		return load_multi(img, vcross[0], vcross[1], ysz / 4, (1 << 5));
    1.66 +	}
    1.67 +	if(xsz / 3 == ysz / 2) {
    1.68 +		// horizontal sixpack
    1.69 +		return load_multi(img, hsix[0], hsix[1], ysz / 2);
    1.70 +	}
    1.71 +
    1.72 +	error_log("failed to load %s: unknown cubemap configuration\n", fname);
    1.73 +	return false;
    1.74  }
    1.75  
    1.76  bool TextureCube::save(const char *fname) const
    1.77 @@ -270,6 +314,27 @@
    1.78  	return false;	// TODO
    1.79  }
    1.80  
    1.81 +bool TextureCube::load_multi(const Image &img, const float *xoffsets, const float *yoffsets, float sz,
    1.82 +		unsigned int rotmask)
    1.83 +{
    1.84 +	for(int i=0; i<6; i++) {
    1.85 +		Image face;
    1.86 +
    1.87 +		int xoffs = xoffsets[i] * img.get_width();
    1.88 +		int yoffs = yoffsets[i] * img.get_height();
    1.89 +
    1.90 +		if(!face.set_pixels(sz, sz, img.get_pixels(), xoffs, yoffs, img.get_width(), img.get_format())) {
    1.91 +			return false;
    1.92 +		}
    1.93 +
    1.94 +		if(rotmask & (1 << i)) {
    1.95 +			face.rotate_180();
    1.96 +		}
    1.97 +		set_image(face, i);
    1.98 +	}
    1.99 +	return true;
   1.100 +}
   1.101 +
   1.102  static int glifmt_from_ifmt(unsigned int ifmt)
   1.103  {
   1.104  #ifdef GL_ES_VERSION_2_0