diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2016-06-22 16:15:37 +0200 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2016-07-04 14:24:32 +0200 |
commit | 1311ed24ad7b1f787727f086c341cd1a898fe06b (patch) | |
tree | 5235d6f78e911dfdfa44dd73c5a82dde092fddd0 | |
parent | 9f18d19a2016c193a71a10beb5e4dca79ad6189b (diff) | |
download | qtlocation-mapboxgl-1311ed24ad7b1f787727f086c341cd1a898fe06b.tar.gz |
[core] refactor Raster and allow explicit mipmapping levels
-rw-r--r-- | src/mbgl/renderer/raster_bucket.cpp | 4 | ||||
-rw-r--r-- | src/mbgl/util/raster.cpp | 62 | ||||
-rw-r--r-- | src/mbgl/util/raster.hpp | 40 |
3 files changed, 55 insertions, 51 deletions
diff --git a/src/mbgl/renderer/raster_bucket.cpp b/src/mbgl/renderer/raster_bucket.cpp index 2020860396..1cf6f2c413 100644 --- a/src/mbgl/renderer/raster_bucket.cpp +++ b/src/mbgl/renderer/raster_bucket.cpp @@ -31,9 +31,9 @@ void RasterBucket::drawRaster(RasterShader& shader, gl::Config& config, gl::ObjectStore& store) { config.activeTexture = GL_TEXTURE0; - raster.bind(true, store); + raster.bind(store, Raster::Scaling::Linear); config.activeTexture = GL_TEXTURE1; - raster.bind(true, store); + raster.bind(store, Raster::Scaling::Linear); array.bind(shader, vertices, BUFFER_OFFSET_0, store); MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)vertices.index())); } diff --git a/src/mbgl/util/raster.cpp b/src/mbgl/util/raster.cpp index b4e838ec00..7417c8bcd5 100644 --- a/src/mbgl/util/raster.cpp +++ b/src/mbgl/util/raster.cpp @@ -10,53 +10,67 @@ namespace mbgl { bool Raster::isLoaded() const { - std::lock_guard<std::mutex> lock(mtx); return loaded; } -void Raster::load(PremultipliedImage image) { +void Raster::load(PremultipliedImage image, uint32_t mipmapLevel) { assert(image.data.get()); - img = std::move(image); - width = GLsizei(img.width); - height = GLsizei(img.height); + if (images.size() <= mipmapLevel) { + images.resize(mipmapLevel + 1); + } + images.at(mipmapLevel) = std::move(image); - std::lock_guard<std::mutex> lock(mtx); loaded = true; } +void Raster::bind(gl::ObjectStore& store, Scaling newFilter, MipMap newMipMap) { + bool updateFilter = false; -void Raster::bind(bool linear, gl::ObjectStore& store) { - if (!width || !height) { - Log::Error(Event::OpenGL, "trying to bind texture without dimension"); - return; - } - - if (img.data && !texture) { - upload(store); - } else if (texture) { + if (!texture) { + if (images.empty()) { + Log::Error(Event::OpenGL, "trying to bind texture without images"); + return; + } else { + upload(store); + updateFilter = true; + } + } else { MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture)); + updateFilter = (filter != newFilter || mipmap != newMipMap); } - GLint new_filter = linear ? GL_LINEAR : GL_NEAREST; - if (new_filter != this->filter) { - MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, new_filter)); - MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, new_filter)); - filter = new_filter; + if (updateFilter) { + filter = newFilter; + mipmap = newMipMap; + 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) { - if (img.data && !texture) { + if (!images.empty() && !texture) { texture = store.createTexture(); MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture)); #ifndef GL_ES_VERSION_2_0 - MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 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)); - MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.data.get())); - img.data.reset(); + GLint level = 0; + for (auto& img : images) { + assert(img.data.get()); + MBGL_CHECK_ERROR(glTexImage2D( + GL_TEXTURE_2D, level++, GL_RGBA, static_cast<GLsizei>(img.width), + static_cast<GLsizei>(img.height), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.data.get())); + } + images.clear(); + images.shrink_to_fit(); } } diff --git a/src/mbgl/util/raster.hpp b/src/mbgl/util/raster.hpp index 17319394c4..6223440bd6 100644 --- a/src/mbgl/util/raster.hpp +++ b/src/mbgl/util/raster.hpp @@ -2,22 +2,21 @@ #include <mbgl/gl/object_store.hpp> #include <mbgl/util/image.hpp> -#include <mbgl/util/ptr.hpp> -#include <mbgl/util/chrono.hpp> #include <mbgl/util/optional.hpp> - -#include <mutex> +#include <mbgl/util/atomic.hpp> namespace mbgl { -class Raster : public std::enable_shared_from_this<Raster> { - +class Raster { public: + enum class MipMap : bool { No = false, Yes = true }; + enum class Scaling : bool { Nearest = false, Linear = true }; + // load image data - void load(PremultipliedImage); + void load(PremultipliedImage, uint32_t mipmapLevel = 0); // bind current texture - void bind(bool linear, gl::ObjectStore&); + void bind(gl::ObjectStore&, Scaling = Scaling::Nearest, MipMap = MipMap::No); // uploads the texture if it hasn't been uploaded yet. void upload(gl::ObjectStore&); @@ -25,28 +24,19 @@ public: // loaded status bool isLoaded() const; -public: - // loaded image dimensions - GLsizei width = 0; - GLsizei height = 0; - - // GL buffer object handle. - mbgl::optional<gl::UniqueTexture> texture; - - // texture opacity - double opacity = 0; - private: - mutable std::mutex mtx; - // raw pixels have been loaded - bool loaded = false; + util::Atomic<bool> loaded { false }; - // min/mag filter - GLint filter = 0; + // filters + Scaling filter = Scaling::Nearest; + MipMap mipmap = MipMap::No; // the raw pixels - PremultipliedImage img; + std::vector<PremultipliedImage> images; + + // GL buffer object handle. + mbgl::optional<gl::UniqueTexture> texture; }; } // namespace mbgl |