#include "texture.h" #include "image.h" Texture::Texture(GLenum format, GLenum internal_format, int width, int height, GLenum dataType, GLenum texTarget) : m_texUnit(0), m_target(texTarget), m_format(format), m_internal_format(internal_format), m_width(width), m_height(height), m_dataType(dataType), m_hasMipMaps(false) { glGenTextures(1, &m_texId); glBindTexture(m_target, m_texId); switch(m_target) { case GL_TEXTURE_2D : glTexImage2D(m_target, 0, internal_format, width, height, 0, format, dataType, NULL); setWrap(GL_REPEAT); setFiltering(GL_LINEAR); break; case GL_TEXTURE_RECTANGLE : glTexImage2D(m_target, 0, internal_format, width, height, 0, format, dataType, NULL); setWrap(GL_CLAMP_TO_EDGE); setFiltering(GL_LINEAR); break; case GL_TEXTURE_CUBE_MAP : for(int i=0; i<6; ++i) glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, width, height, 0, format, dataType, NULL); setWrap(GL_CLAMP_TO_EDGE); setFiltering(GL_LINEAR); break; default: break; } } Texture::Texture(Image* myImage, bool makeMipMaps) : m_texUnit(0), m_target(GL_TEXTURE_2D), m_width(myImage->width), m_height(myImage->height), m_dataType(GL_UNSIGNED_BYTE), m_hasMipMaps(makeMipMaps) { glGenTextures(1, &m_texId); glBindTexture(m_target, m_texId); initPixels(myImage, GL_TEXTURE_2D); setWrap(GL_REPEAT); setFiltering(GL_LINEAR); if(makeMipMaps) createMipMaps(); } Texture::Texture(Image* myCubemapImages[6], bool makeMipMaps) : m_texUnit(0), m_target(GL_TEXTURE_CUBE_MAP), m_width(myCubemapImages[0]->width), m_height(myCubemapImages[0]->height), m_dataType(GL_UNSIGNED_BYTE), m_hasMipMaps(makeMipMaps) { glGenTextures(1, &m_texId); glBindTexture(m_target, m_texId); for(int i=0; i<6; ++i) initPixels(myCubemapImages[i], GL_TEXTURE_CUBE_MAP_POSITIVE_X + i); setWrap(GL_CLAMP_TO_EDGE); setFiltering(GL_LINEAR); if(makeMipMaps) createMipMaps(); } Texture::Texture(Texture* tex, bool halfDim) : m_texUnit(0), m_target(tex->m_target), m_format(tex->m_format), m_internal_format(tex->m_internal_format), m_width(tex->m_width), m_height(tex->m_height), m_dataType(tex->m_dataType), m_hasMipMaps(false) { glGenTextures(1, &m_texId); glBindTexture(m_target, m_texId); if(halfDim) { m_width /= 2; m_height /= 2; } glTexImage2D(m_target, 0, m_internal_format, m_width, m_height, 0, m_format, m_dataType, NULL); } Texture::~Texture() { glDeleteTextures(1, &m_texId); } void Texture::initPixels(Image* myImage, GLenum target) { switch(myImage->depth) { case 32: m_format = GL_RGBA; m_internal_format = GL_RGBA; break; case 24: m_format = GL_RGB; m_internal_format = GL_RGB; break; case 8: m_format = GL_RED; m_internal_format = GL_R8; break; } glTexImage2D(target, 0, m_internal_format, m_width, m_height, 0, m_format, m_dataType, myImage->pixels.data()); } void Texture::setWrap(GLint wrap) { setParameter(GL_TEXTURE_WRAP_S, wrap); setParameter(GL_TEXTURE_WRAP_T, wrap); setParameter(GL_TEXTURE_WRAP_R, wrap); } void Texture::setFiltering(GLint filter) { setParameter(GL_TEXTURE_MIN_FILTER, filter); setParameter(GL_TEXTURE_MAG_FILTER, filter); } void Texture::setParameter(GLenum parameter, GLenum value) { glBindTexture(m_target, m_texId); glTexParameteri(m_target, parameter, value); } void Texture::createMipMaps() { m_hasMipMaps = true; glGenerateMipmap(m_target); setParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } void Texture::bind(int unit) { if(unit >= 0) m_texUnit = unit; glActiveTexture(GL_TEXTURE0+m_texUnit); glBindTexture(m_target, m_texId); } void Texture::unbind() { glActiveTexture(GL_TEXTURE0+m_texUnit); glBindTexture(m_target, 0); } Image* Texture::getData(int faceId) { bind(); int nbVal; int nbImages; switch(m_format) { case GL_RGBA: nbVal = 4; break; case GL_RGB: nbVal = 3; break; case GL_RED: nbVal = 1; break; case GL_DEPTH_COMPONENT: nbVal = 1; break; default: return NULL; } switch(m_target) { case GL_TEXTURE_2D_ARRAY: nbImages = 3; break; // TODO : add a member specifying how many layers has the texture default: nbImages = 1; break; } int size = nbVal*m_width*m_height*nbImages; Image *img = new Image(); img->depth = nbVal*8; img->height = m_height; img->width = m_width; img->allocate(size); if(m_target == GL_TEXTURE_CUBE_MAP) glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X+faceId, 0, m_format, GL_UNSIGNED_BYTE, img->pixels.data()); else glGetTexImage(m_target, 0, m_format, GL_UNSIGNED_BYTE, img->pixels.data()); return img; }