void TextureGL::Update(const void *data, const vector2f &dataSize, ImageFormat format, ImageType type) { glEnable(m_target); glBindTexture(m_target, m_texture); switch (m_target) { case GL_TEXTURE_2D: glTexSubImage2D(m_target, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(type), data); break; default: assert(0); } glBindTexture(m_target, 0); glDisable(m_target); }
TextureGL::TextureGL(const TextureDescriptor &descriptor, const bool useCompressed) : Texture(descriptor) { m_target = GLTextureType(descriptor.type); glGenTextures(1, &m_texture); glBindTexture(m_target, m_texture); RendererOGL::CheckErrors(); // useCompressed is the global scope flag whereas descriptor.allowCompression is the local texture mode flag // either both or neither might be true however only compress the texture when both are true. const bool compressTexture = useCompressed && descriptor.allowCompression; switch (m_target) { case GL_TEXTURE_2D: if (!IsCompressed(descriptor.format)) { if (!descriptor.generateMipmaps) glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, 0); RendererOGL::CheckErrors(); glTexImage2D( m_target, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), descriptor.dataSize.x, descriptor.dataSize.y, 0, GLImageFormat(descriptor.format), GLImageType(descriptor.format), 0); RendererOGL::CheckErrors(); if (descriptor.generateMipmaps) glGenerateMipmap(m_target); RendererOGL::CheckErrors(); } else { const GLint oglFormatMinSize = GetMinSize(descriptor.format); size_t Width = descriptor.dataSize.x; size_t Height = descriptor.dataSize.y; size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * oglFormatMinSize; GLint maxMip = 0; for( unsigned int i=0; i < descriptor.numberOfMipMaps; ++i ) { maxMip = i; glCompressedTexImage2D(GL_TEXTURE_2D, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); if( Width<=MIN_COMPRESSED_TEXTURE_DIMENSION || Height<=MIN_COMPRESSED_TEXTURE_DIMENSION ) { break; } bufSize /= 4; Width /= 2; Height /= 2; } glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, maxMip); RendererOGL::CheckErrors(); } break; case GL_TEXTURE_CUBE_MAP: if(!IsCompressed(descriptor.format)) { if(descriptor.generateMipmaps) glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, 0); RendererOGL::CheckErrors(); glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), descriptor.dataSize.x, descriptor.dataSize.y, 0, GLImageFormat(descriptor.format), GLImageType(descriptor.format), 0); glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), descriptor.dataSize.x, descriptor.dataSize.y, 0, GLImageFormat(descriptor.format), GLImageType(descriptor.format), 0); glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), descriptor.dataSize.x, descriptor.dataSize.y, 0, GLImageFormat(descriptor.format), GLImageType(descriptor.format), 0); glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), descriptor.dataSize.x, descriptor.dataSize.y, 0, GLImageFormat(descriptor.format), GLImageType(descriptor.format), 0); glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), descriptor.dataSize.x, descriptor.dataSize.y, 0, GLImageFormat(descriptor.format), GLImageType(descriptor.format), 0); glTexImage2D( GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, compressTexture ? GLCompressedInternalFormat(descriptor.format) : GLInternalFormat(descriptor.format), descriptor.dataSize.x, descriptor.dataSize.y, 0, GLImageFormat(descriptor.format), GLImageType(descriptor.format), 0); RendererOGL::CheckErrors(); if (descriptor.generateMipmaps) glGenerateMipmap(m_target); RendererOGL::CheckErrors(); } else { const GLint oglFormatMinSize = GetMinSize(descriptor.format); size_t Width = descriptor.dataSize.x; size_t Height = descriptor.dataSize.y; size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * oglFormatMinSize; GLint maxMip = 0; for( unsigned int i=0; i < descriptor.numberOfMipMaps; ++i ) { maxMip = i; glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, i, GLInternalFormat(descriptor.format), Width, Height, 0, bufSize, 0); if( Width<=MIN_COMPRESSED_TEXTURE_DIMENSION || Height<=MIN_COMPRESSED_TEXTURE_DIMENSION ) { break; } bufSize /= 4; Width /= 2; Height /= 2; } glTexParameteri(m_target, GL_TEXTURE_MAX_LEVEL, maxMip); RendererOGL::CheckErrors(); } break; default: assert(0); } RendererOGL::CheckErrors(); GLenum magFilter, minFilter, wrapS, wrapT; switch (descriptor.sampleMode) { default: // safe default will fall through to LINEAR_CLAMP when run in release builds without assert assert(0); case LINEAR_CLAMP: magFilter = GL_LINEAR; minFilter = descriptor.generateMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; wrapS = wrapT = GL_CLAMP_TO_EDGE; break; case NEAREST_CLAMP: magFilter = GL_NEAREST; minFilter = descriptor.generateMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; wrapS = wrapT = GL_CLAMP_TO_EDGE; break; case LINEAR_REPEAT: magFilter = GL_LINEAR; minFilter = descriptor.generateMipmaps ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR; wrapS = wrapT = GL_REPEAT; break; case NEAREST_REPEAT: magFilter = GL_NEAREST; minFilter = descriptor.generateMipmaps ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST; wrapS = wrapT = GL_REPEAT; break; } glTexParameteri(m_target, GL_TEXTURE_WRAP_S, wrapS); glTexParameteri(m_target, GL_TEXTURE_WRAP_T, wrapS); glTexParameteri(m_target, GL_TEXTURE_MAG_FILTER, magFilter); glTexParameteri(m_target, GL_TEXTURE_MIN_FILTER, minFilter); RendererOGL::CheckErrors(); }
void TextureGL::Update(const TextureCubeData &data, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) { assert(m_target == GL_TEXTURE_CUBE_MAP); glBindTexture(m_target, m_texture); switch (m_target) { case GL_TEXTURE_CUBE_MAP: if (!IsCompressed(format)) { glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.posX); glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.negX); glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.posY); glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.negY); glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.posZ); glTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, 0, 0, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data.negZ); } else { const GLint oglInternalFormat = GLImageFormat(format); size_t Offset = 0; size_t Width = dataSize.x; size_t Height = dataSize.y; size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * GetMinSize(format); const unsigned char *pData_px = static_cast<const unsigned char*>(data.posX); const unsigned char *pData_nx = static_cast<const unsigned char*>(data.negX); const unsigned char *pData_py = static_cast<const unsigned char*>(data.posY); const unsigned char *pData_ny = static_cast<const unsigned char*>(data.negY); const unsigned char *pData_pz = static_cast<const unsigned char*>(data.posZ); const unsigned char *pData_nz = static_cast<const unsigned char*>(data.negZ); for( unsigned int i = 0; i < numMips; ++i ) { glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_px[Offset]); glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_nx[Offset]); glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_py[Offset]); glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_ny[Offset]); glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_pz[Offset]); glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, i, 0, 0, Width, Height, oglInternalFormat, bufSize, &pData_nz[Offset]); if( Width<=MIN_COMPRESSED_TEXTURE_DIMENSION || Height<=MIN_COMPRESSED_TEXTURE_DIMENSION ) { break; } Offset += bufSize; bufSize /= 4; Width /= 2; Height /= 2; } } break; default: assert(0); } if (GetDescriptor().generateMipmaps) glGenerateMipmap(m_target); glBindTexture(m_target, 0); }
void TextureGL::Update(const void *data, const vector2f &pos, const vector2f &dataSize, TextureFormat format, const unsigned int numMips) { assert(m_target == GL_TEXTURE_2D); glBindTexture(m_target, m_texture); switch (m_target) { case GL_TEXTURE_2D: if (!IsCompressed(format)) { glTexSubImage2D(m_target, 0, pos.x, pos.y, dataSize.x, dataSize.y, GLImageFormat(format), GLImageType(format), data); } else { const GLint oglInternalFormat = GLImageFormat(format); size_t Offset = 0; size_t Width = dataSize.x; size_t Height = dataSize.y; size_t bufSize = ((Width + 3) / 4) * ((Height + 3) / 4) * GetMinSize(format); const unsigned char *pData = static_cast<const unsigned char*>(data); for( unsigned int i = 0; i < numMips; ++i ) { glCompressedTexSubImage2D(m_target, i, pos.x, pos.y, Width, Height, oglInternalFormat, bufSize, &pData[Offset]); if( Width<=MIN_COMPRESSED_TEXTURE_DIMENSION || Height<=MIN_COMPRESSED_TEXTURE_DIMENSION ) { break; } Offset += bufSize; bufSize /= 4; Width /= 2; Height /= 2; } } break; default: assert(0); } if (GetDescriptor().generateMipmaps) glGenerateMipmap(m_target); glBindTexture(m_target, 0); }