#include #include #include #include #include #include #include namespace mbgl { bool Raster::isLoaded() const { return loaded; } GLuint Raster::getID() const { return texture ? *texture : 0; } std::array Raster::getSize() const { return size; } void Raster::load(PremultipliedImage image, uint32_t mipmapLevel) { if (images.size() <= mipmapLevel) { images.resize(mipmapLevel + 1); } images.at(mipmapLevel) = std::move(image); loaded = true; } void Raster::bind(gl::ObjectStore& store, gl::Config& config, uint32_t unit, Scaling newFilter, MipMap newMipMap) { bool filterNeedsUpdate = false; if (!texture) { if (images.empty()) { Log::Error(Event::OpenGL, "trying to bind texture without images"); return; } else { upload(store, config, unit); filterNeedsUpdate = true; } } else { if (config.texture[unit] != *texture) { config.activeTexture = unit; config.texture[unit] = *texture; } filterNeedsUpdate = (filter != newFilter || mipmap != newMipMap); } if (filterNeedsUpdate) { filter = newFilter; mipmap = newMipMap; updateFilter(); } } void Raster::updateFilter() { MBGL_CHECK_ERROR(glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter == Scaling::Linear ? (mipmap == MipMap::Yes ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR) : (mipmap == MipMap::Yes ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST))); MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter == Scaling::Linear ? GL_LINEAR : GL_NEAREST)); } void Raster::upload(gl::ObjectStore& store, gl::Config& config, uint32_t unit) { if (!images.empty() && !texture) { texture = store.createTexture(); config.activeTexture = unit; config.texture[unit] = *texture; updateFilter(); #ifndef GL_ES_VERSION_2_0 MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, images.size())); #endif MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); GLint level = 0; for (auto& img : images) { MBGL_CHECK_ERROR(glTexImage2D( GL_TEXTURE_2D, level++, GL_RGBA, static_cast(img.width), static_cast(img.height), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.data.get())); } size = { { images.front().width, images.front().height } }; images.clear(); images.shrink_to_fit(); } } } // namespace mbgl