| 330 | } |
| 331 | |
| 332 | void Texture::Initialize(const ITextureLoader& texLoader) |
| 333 | { |
| 334 | const IGfxCapabilities& gfxCaps = theServiceLocator().GetGfxCapabilities(); |
| 335 | const std::int32_t maxTextureSize = gfxCaps.GetValue(IGfxCapabilities::GLIntValues::MAX_TEXTURE_SIZE); |
| 336 | FATAL_ASSERT_MSG(texLoader.width() <= maxTextureSize, "Texture width {} is bigger than device maximum {}", texLoader.width(), maxTextureSize); |
| 337 | FATAL_ASSERT_MSG(texLoader.height() <= maxTextureSize, "Texture height {} is bigger than device maximum {}", texLoader.height(), maxTextureSize); |
| 338 | |
| 339 | const TextureFormat& texFormat = texLoader.texFormat(); |
| 340 | GLenum internalFormat = texFormat.internalFormat(); |
| 341 | GLenum format = texFormat.format(); |
| 342 | std::uint32_t dataSize = texLoader.dataSize(); |
| 343 | |
| 344 | #if (defined(WITH_OPENGLES) && GL_ES_VERSION_3_0) || defined(DEATH_TARGET_EMSCRIPTEN) |
| 345 | const bool withTexStorage = true; |
| 346 | #else |
| 347 | const bool withTexStorage = gfxCaps.HasExtension(IGfxCapabilities::GLExtensions::ARB_TEXTURE_STORAGE); |
| 348 | #endif |
| 349 | |
| 350 | // Specify texture storage because it's either the very first time or there have been a change in size or format |
| 351 | if (dataSize_ == 0 || (width_ != texLoader.width() || height_ != texLoader.height() || ncFormatToInternal(format_) != internalFormat)) { |
| 352 | if (withTexStorage) { |
| 353 | if (dataSize_ > 0) { |
| 354 | // The OpenGL texture needs to be recreated as its storage is immutable |
| 355 | glTexture_ = std::make_unique<GLTexture>(GL_TEXTURE_2D); |
| 356 | dataSize_ = 0; |
| 357 | } |
| 358 | |
| 359 | if (dataSize_ == 0) { |
| 360 | glTexture_->TexStorage2D(texLoader.mipMapCount(), internalFormat, texLoader.width(), texLoader.height()); |
| 361 | } |
| 362 | } else if (!texFormat.isCompressed()) { |
| 363 | std::int32_t levelWidth = texLoader.width(); |
| 364 | std::int32_t levelHeight = texLoader.height(); |
| 365 | |
| 366 | for (std::int32_t i = 0; i < texLoader.mipMapCount(); i++) { |
| 367 | glTexture_->TexImage2D(i, internalFormat, levelWidth, levelHeight, format, texFormat.type(), nullptr); |
| 368 | levelWidth /= 2; |
| 369 | levelHeight /= 2; |
| 370 | } |
| 371 | } |
| 372 | } |
| 373 | |
| 374 | width_ = texLoader.width(); |
| 375 | height_ = texLoader.height(); |
| 376 | mipMapLevels_ = texLoader.mipMapCount(); |
| 377 | isCompressed_ = texFormat.isCompressed(); |
| 378 | format_ = internalFormatToNc(internalFormat); |
| 379 | dataSize_ = dataSize; |
| 380 | |
| 381 | glTexture_->TexParameteri(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 382 | glTexture_->TexParameteri(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 383 | wrapMode_ = SamplerWrapping::ClampToEdge; |
| 384 | |
| 385 | if (mipMapLevels_ > 1) { |
| 386 | glTexture_->TexParameteri(GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 387 | glTexture_->TexParameteri(GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); |
| 388 | magFiltering_ = SamplerFilter::Linear; |
| 389 | minFiltering_ = SamplerFilter::LinearMipmapLinear; |
nothing calls this directly
no test coverage detected