bool Texture2D::createStorage(Size2i size, unsigned int channels, bool compressed, int levels) { if (created) { return false; } // levels = -1 means max mipmap level according to texture dimensions const int maxLevels = ilogb(size.max()) + 1; if (levels == 0) levels = 1; if (levels < 0 || levels > maxLevels) levels = maxLevels; this->channels = std::min(std::max(1u, channels), 4u); this->size = size; this->levels = levels; if (glTexStorage2D) { // try to allocate immutable storage (ogl 4.3) glTexStorage2D(target, levels, glInternalFormat(compressed), size.width(), size.height()); } else { // ensure texture completeness despite mutable storage for (int i=0; i<levels; ++i) { glTexImage2D(target, i, glInternalFormat(compressed), size.width(), size.height(), 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr); size = Size2i(std::max(1, size.width()>>1), std::max(1, size.height()>>1)); } glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1); } return created = true; }
// TODO: support mip maps GLTextureCubeMap::GLTextureCubeMap( int sideLength, GLImageInternalFormat internalFormat ) : GLTexture( GLTexture::Target::TEXTURE_CUBE_MAP, internalFormat, 1 ), m_sideLength( sideLength ) { assert( sideLength > 0 ); assert( sideLength <= GLTexture::maxSizeCubeMap() ); glTextureStorage2D( id(), 1, glInternalFormat(), sideLength, sideLength ); }
GLTexture3D::GLTexture3D( const Vector3i& size, GLImageInternalFormat internalFormat, GLsizei nMipMapLevels ) : GLTexture( GLTexture::Target::TEXTURE_3D, internalFormat, nMipMapLevels ), m_size( size ) { assert( size.x > 0 ); assert( size.y > 0 ); assert( size.z > 0 ); assert( size.x <= GLTexture::maxSize3D() ); assert( size.y <= GLTexture::maxSize3D() ); assert( size.z <= GLTexture::maxSize3D() ); glTexStorage3D( glTarget(), numMipMapLevels(), glInternalFormat(), size.x, size.y, size.z ); }
Texture &Texture::create(int w, int h, Type type, int filter, int wrap, Type dataType, void *data) { return create(w, h, 1, glInternalFormat(type), glFormat(type), glType(dataType), filter, wrap, data); }
Texture &Texture::create(int w, int h, Type type, int filter, int wrap) { return create(w, h, 1, glInternalFormat(type), glFormat(type), glType(type), filter, wrap, nullptr); }