summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2016-10-26 17:19:19 -0700
committerKonstantin Käfer <mail@kkaefer.com>2016-11-01 18:41:52 +0100
commit358701f475b2c04c4681d70435bc76370b371285 (patch)
tree7ab5d170957eb8d209716f695aec428a44d4ddf2
parent9e3839781fdf1b1c6a2d61a5de9b2c7ddd68e9ed (diff)
downloadqtlocation-mapboxgl-358701f475b2c04c4681d70435bc76370b371285.tar.gz
[core] add ability to upload alpha-only textures + images
-rw-r--r--include/mbgl/util/image.hpp9
-rw-r--r--src/mbgl/gl/context.cpp16
-rw-r--r--src/mbgl/gl/context.hpp16
-rw-r--r--src/mbgl/gl/types.hpp4
4 files changed, 31 insertions, 14 deletions
diff --git a/include/mbgl/util/image.hpp b/include/mbgl/util/image.hpp
index 3dbab27f41..1d84d4824a 100644
--- a/include/mbgl/util/image.hpp
+++ b/include/mbgl/util/image.hpp
@@ -9,9 +9,10 @@
namespace mbgl {
-enum ImageAlphaMode {
+enum class ImageAlphaMode {
Unassociated,
- Premultiplied
+ Premultiplied,
+ Exclusive, // Alpha-channel only
};
template <ImageAlphaMode Mode>
@@ -47,15 +48,17 @@ public:
return size && data.get() != nullptr;
}
- size_t stride() const { return static_cast<size_t>(size.width) * 4; }
+ size_t stride() const { return channels * size.width; }
size_t bytes() const { return stride() * size.height; }
Size size;
+ static constexpr size_t channels = Mode == ImageAlphaMode::Exclusive ? 1 : 4;
std::unique_ptr<uint8_t[]> data;
};
using UnassociatedImage = Image<ImageAlphaMode::Unassociated>;
using PremultipliedImage = Image<ImageAlphaMode::Premultiplied>;
+using AlphaImage = Image<ImageAlphaMode::Exclusive>;
// TODO: don't use std::string for binary data.
PremultipliedImage decodeImage(const std::string&);
diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp
index 7200b75050..41f02b6364 100644
--- a/src/mbgl/gl/context.cpp
+++ b/src/mbgl/gl/context.cpp
@@ -26,6 +26,10 @@ static_assert(std::is_same<VertexArrayID, GLuint>::value, "OpenGL type mismatch"
static_assert(std::is_same<FramebufferID, GLuint>::value, "OpenGL type mismatch");
static_assert(std::is_same<RenderbufferID, GLuint>::value, "OpenGL type mismatch");
+static_assert(std::is_same<std::underlying_type_t<TextureFormat>, GLenum>::value, "OpenGL type mismatch");
+static_assert(underlying_type(TextureFormat::RGBA) == GL_RGBA, "OpenGL type mismatch");
+static_assert(underlying_type(TextureFormat::Alpha) == GL_ALPHA, "OpenGL type mismatch");
+
Context::~Context() {
reset();
}
@@ -183,9 +187,9 @@ Framebuffer Context::createFramebuffer(const Texture& color) {
}
UniqueTexture
-Context::createTexture(const Size size, const void* data, TextureUnit unit) {
+Context::createTexture(const Size size, const void* data, TextureFormat format, TextureUnit unit) {
auto obj = createTexture();
- updateTexture(obj, size, data, unit);
+ updateTexture(obj, size, data, format, unit);
// We are using clamp to edge here since OpenGL ES doesn't allow GL_REPEAT on NPOT textures.
// We use those when the pixelRatio isn't a power of two, e.g. on iPhone 6 Plus.
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
@@ -195,11 +199,13 @@ Context::createTexture(const Size size, const void* data, TextureUnit unit) {
return obj;
}
-void Context::updateTexture(TextureID id, const Size size, const void* data, TextureUnit unit) {
+void Context::updateTexture(
+ TextureID id, const Size size, const void* data, TextureFormat format, TextureUnit unit) {
activeTexture = unit;
texture[unit] = id;
- MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width, size.height, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, data));
+ MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, static_cast<GLenum>(format), size.width,
+ size.height, 0, static_cast<GLenum>(format), GL_UNSIGNED_BYTE,
+ data));
}
void Context::bindTexture(Texture& obj,
diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp
index ae2b71994f..4e9320f7d1 100644
--- a/src/mbgl/gl/context.hpp
+++ b/src/mbgl/gl/context.hpp
@@ -65,18 +65,22 @@ public:
// Create a texture from an image with data.
template <typename Image>
Texture createTexture(const Image& image, TextureUnit unit = 0) {
- return { image.size, createTexture(image.size, image.data.get(), unit) };
+ auto format = image.channels == 4 ? TextureFormat::RGBA : TextureFormat::Alpha;
+ return { image.size, createTexture(image.size, image.data.get(), format, unit) };
}
template <typename Image>
void updateTexture(Texture& obj, const Image& image, TextureUnit unit = 0) {
- updateTexture(obj.texture.get(), image.size, image.data.get(), unit);
+ auto format = image.channels == 4 ? TextureFormat::RGBA : TextureFormat::Alpha;
+ updateTexture(obj.texture.get(), image.size, image.data.get(), format, unit);
obj.size = image.size;
}
// Creates an empty texture with the specified dimensions.
- Texture createTexture(const Size size, TextureUnit unit = 0) {
- return { size, createTexture(size, nullptr, unit) };
+ Texture createTexture(const Size size,
+ TextureFormat format = TextureFormat::RGBA,
+ TextureUnit unit = 0) {
+ return { size, createTexture(size, nullptr, format, unit) };
}
void bindTexture(Texture&,
@@ -153,8 +157,8 @@ private:
UniqueBuffer createVertexBuffer(const void* data, std::size_t size);
UniqueBuffer createIndexBuffer(const void* data, std::size_t size);
- UniqueTexture createTexture(Size size, const void* data, TextureUnit);
- void updateTexture(TextureID, Size size, const void* data, TextureUnit);
+ UniqueTexture createTexture(Size size, const void* data, TextureFormat, TextureUnit);
+ void updateTexture(TextureID, Size size, const void* data, TextureFormat, TextureUnit);
UniqueFramebuffer createFramebuffer();
UniqueRenderbuffer createRenderbuffer(RenderbufferType, Size size);
diff --git a/src/mbgl/gl/types.hpp b/src/mbgl/gl/types.hpp
index 9a1eb365d1..10cf0a9730 100644
--- a/src/mbgl/gl/types.hpp
+++ b/src/mbgl/gl/types.hpp
@@ -46,6 +46,10 @@ enum class RenderbufferType : uint32_t {
enum class TextureMipMap : bool { No = false, Yes = true };
enum class TextureFilter : bool { Nearest = false, Linear = true };
+enum class TextureFormat : uint32_t {
+ RGBA = 0x1908,
+ Alpha = 0x1906,
+};
enum class PrimitiveType {
Points = 0x0000,