nuclear@0: #include nuclear@0: #include nuclear@0: #include "texture.h" nuclear@0: #include "opengl.h" nuclear@0: nuclear@0: Texture::Texture() nuclear@0: { nuclear@0: width = height = tex_width = tex_height = 0; nuclear@0: tex = 0; nuclear@0: } nuclear@0: nuclear@0: Texture::~Texture() nuclear@0: { nuclear@0: if(tex) { nuclear@0: glDeleteTextures(1, &tex); nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: static unsigned int next_pow2(unsigned int x) nuclear@0: { nuclear@0: --x; nuclear@0: x |= x >> 1; nuclear@0: x |= x >> 2; nuclear@0: x |= x >> 4; nuclear@0: x |= x >> 8; nuclear@0: x |= x >> 16; nuclear@0: return x + 1; nuclear@0: } nuclear@0: nuclear@0: bool Texture::load(const char *fname) nuclear@0: { nuclear@0: img_pixmap img; nuclear@0: img_init(&img); nuclear@0: if(img_load(&img, fname) == -1) { nuclear@0: fprintf(stderr, "failed to load texture: %s\n", fname); nuclear@0: img_destroy(&img); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@0: unsigned int intfmt = img_glintfmt(&img); nuclear@0: unsigned int pixfmt = img_glfmt(&img); nuclear@0: unsigned int pixtype = img_gltype(&img); nuclear@0: nuclear@0: // if we have the sRGB extension, change the internal formats to sRGB nuclear@0: if(GLEW_EXT_texture_sRGB) { nuclear@0: switch(intfmt) { nuclear@0: case 3: nuclear@0: case GL_RGB: nuclear@0: intfmt = GL_SRGB_EXT; nuclear@0: break; nuclear@0: case 4: nuclear@0: case GL_RGBA: nuclear@0: intfmt = GL_SRGB_ALPHA; nuclear@0: break; nuclear@0: case 1: nuclear@0: case GL_LUMINANCE: nuclear@0: intfmt = GL_SLUMINANCE; nuclear@0: break; nuclear@0: default: nuclear@0: break; nuclear@0: } nuclear@0: } nuclear@0: nuclear@0: width = img.width; nuclear@0: height = img.height; nuclear@0: tex_width = next_pow2(width); nuclear@0: tex_height = next_pow2(height); nuclear@0: nuclear@0: if(!tex) { nuclear@0: glGenTextures(1, &tex); nuclear@0: } nuclear@0: glBindTexture(GL_TEXTURE_2D, tex); nuclear@0: nuclear@0: if(GLEW_SGIS_generate_mipmap) { nuclear@0: glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); nuclear@0: } else { nuclear@0: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); nuclear@0: } nuclear@0: nuclear@0: glTexImage2D(GL_TEXTURE_2D, 0, intfmt, tex_width, tex_height, 0, pixfmt, pixtype, 0); nuclear@0: glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, pixfmt, pixtype, img.pixels); nuclear@0: nuclear@0: tmat.scaling((float)width / (float)tex_width, (float)height / (float)tex_height, 1); nuclear@0: return true; nuclear@0: } nuclear@0: nuclear@0: const Mat4 &Texture::texture_matrix() const nuclear@0: { nuclear@0: return tmat; nuclear@0: } nuclear@0: nuclear@0: void Texture::bind(bool loadmat) const nuclear@0: { nuclear@0: if(!tex) return; nuclear@0: nuclear@0: if(loadmat) { nuclear@0: glMatrixMode(GL_TEXTURE); nuclear@0: glLoadMatrixf(tmat[0]); nuclear@0: glMatrixMode(GL_MODELVIEW); nuclear@0: } nuclear@0: nuclear@0: glBindTexture(GL_TEXTURE_2D, tex); nuclear@0: }