void Texture::set_data(const void* data_ptr) { set_mip_data(data_ptr, _size, 0); CHECK_FOR_GL_ERROR; if (_params.filter == TexFilter::Mipmapped) { generate_mipmaps(); } }
bool CImage::GenerateMipmaps(unsigned int nMipmaps) { // Compressed formats should have mipmaps packed in // if(is_format_compressed(m_pixelFormat)) return false; // We do not support non-square mipmapping at this time // if(!is_power_of_2(m_imageWidth, m_imageHeight)) return false; m_mipMapCount = gmin(get_mipmap_count_from_dim(gmax(gmax(m_imageWidth, m_imageHeight), m_depth)), nMipmaps); m_pPixels = (unsigned char*)realloc(m_pPixels, GetSizeWithMipmaps()); unsigned char *dest, *src = m_pPixels; int c = get_channel_count(m_pixelFormat); int cSize = get_bytes_per_channel(m_pixelFormat); if(IsCubemap()) { int dim = m_imageWidth; for(int i = 1; i < m_mipMapCount; ++i) { int sliceSize = dim * dim * c * cSize; dest = src + 6 * sliceSize; for(unsigned int s = 0; s < 6; ++s) { if(cSize == 1) generate_mipmaps(src + s * sliceSize, dest + s * sliceSize / 4, dim, dim, 1, c); else if(cSize == 2) generate_mipmaps((unsigned short*)(src + s * sliceSize), (unsigned short*)(dest + s * sliceSize / 4), dim, dim, 1, c); else generate_mipmaps((float*)(src + s * sliceSize), (float*)(dest + s * sliceSize / 4), dim, dim, 1, c); } src = dest; dim >>= 1; } } else {
void GL::Texture::setup(const void* data, GLenum type, int samples) { assert(_dimensions >= 1 && _dimensions <= 3); GLenum targets[] = {GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D}; GLenum wrap_enums[] = {GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, GL_TEXTURE_WRAP_R}; _target = targets[_dimensions-1]; if (samples > 0) { // Multisample textures don't support mipmapping. assert(_min_filter != GL_NEAREST_MIPMAP_NEAREST); assert(_min_filter != GL_LINEAR_MIPMAP_NEAREST); assert(_min_filter != GL_NEAREST_MIPMAP_LINEAR); assert(_min_filter != GL_LINEAR_MIPMAP_LINEAR); assert(_dimensions == 2); if (_dimensions == 2) { _target = GL_TEXTURE_2D_MULTISAMPLE; } } bind(); if (samples == 0) { if (FLEXT_EXT_texture_filter_anisotropic) { glTexParameterf(_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_config.max_anisotropy()); } glTexParameteri(_target, GL_TEXTURE_MAG_FILTER, _mag_filter); glTexParameteri(_target, GL_TEXTURE_MIN_FILTER, _min_filter); for (int i = 0; i < _dimensions; ++i) { glTexParameteri(_target, wrap_enums[i], _wrap_method); } } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); switch (_dimensions) { case 1: glTexImage1D(GL_TEXTURE_1D, // target 0, // level _internal_format, // internalFormat _width, // size 0, // border _format, // format type, // type data); // pixels break; case 2: if (samples < 1) { glTexImage2D(GL_TEXTURE_2D, // target 0, // level _internal_format, // internalFormat _width,_height, // size 0, // border _format, // format type, // type data); // pixels } else { glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, // target samples, // samples _internal_format, // internalFormat _width,_height, // size GL_FALSE); // fixedsamplelocations } break; case 3: glTexImage3D(GL_TEXTURE_3D, // target 0, // level _internal_format, // internalFormat _width,_height,_depth, // size 0, // border _format, // format type, // type data); // pixels break; default: assert(0); // To keep the compiler quiet.. } generate_mipmaps(); unbind(); }