summaryrefslogtreecommitdiff
path: root/src/mbgl/util/raster.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/util/raster.cpp')
-rw-r--r--src/mbgl/util/raster.cpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/src/mbgl/util/raster.cpp b/src/mbgl/util/raster.cpp
new file mode 100644
index 0000000000..56461aec5f
--- /dev/null
+++ b/src/mbgl/util/raster.cpp
@@ -0,0 +1,106 @@
+#include <mbgl/platform/platform.hpp>
+#include <mbgl/platform/gl.hpp>
+
+#include <mbgl/util/raster.hpp>
+#include <mbgl/util/time.hpp>
+#include <mbgl/util/uv_detail.hpp>
+#include <mbgl/util/std.hpp>
+
+#include <cassert>
+#include <cstring>
+
+using namespace mbgl;
+
+Raster::Raster(TexturePool& texturePool_)
+ : texturePool(texturePool_)
+{}
+
+Raster::~Raster() {
+ if (textured) {
+ texturePool.removeTextureID(texture);
+ }
+}
+
+bool Raster::isLoaded() const {
+ std::lock_guard<std::mutex> lock(mtx);
+ return loaded;
+}
+
+bool Raster::load(const std::string &data) {
+ img = util::make_unique<util::Image>(data);
+ width = img->getWidth();
+ height = img->getHeight();
+
+ std::lock_guard<std::mutex> lock(mtx);
+ if (img->getData()) {
+ loaded = true;
+ }
+ return loaded;
+}
+
+
+void Raster::bind(bool linear) {
+ if (!width || !height) {
+ fprintf(stderr, "trying to bind texture without dimension\n");
+ return;
+ }
+
+ if (img && !textured) {
+ texture = texturePool.getTextureID();
+ glBindTexture(GL_TEXTURE_2D, texture);
+#ifndef GL_ES_VERSION_2_0
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+#endif
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img->getData());
+ img.reset();
+ textured = true;
+ } else if (textured) {
+ glBindTexture(GL_TEXTURE_2D, texture);
+ }
+
+ GLuint new_filter = linear ? GL_LINEAR : GL_NEAREST;
+ if (new_filter != this->filter) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, new_filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, new_filter);
+ filter = new_filter;
+ }
+}
+
+// overload ::bind for prerendered raster textures
+void Raster::bind(const GLuint custom_texture) {
+ if (img && !textured) {
+ glBindTexture(GL_TEXTURE_2D, custom_texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img->getData());
+ img.reset();
+ textured = true;
+ } else if (textured) {
+ glBindTexture(GL_TEXTURE_2D, custom_texture);
+ }
+
+ GLuint new_filter = GL_LINEAR;
+ if (new_filter != this->filter) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, new_filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, new_filter);
+ filter = new_filter;
+ }
+
+}
+
+void Raster::beginFadeInTransition() {
+ timestamp start = util::now();
+ fade_transition = std::make_shared<util::ease_transition<double>>(opacity, 1.0, opacity, start, 250_milliseconds);
+}
+
+bool Raster::needsTransition() const {
+ return fade_transition != nullptr;
+}
+
+void Raster::updateTransitions(timestamp now) {
+ if (fade_transition->update(now) == util::transition::complete) {
+ fade_transition = nullptr;
+ }
+}