diff options
-rw-r--r-- | include/mbgl/util/image.hpp | 9 | ||||
-rw-r--r-- | src/mbgl/gl/context.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/gl/context.hpp | 16 | ||||
-rw-r--r-- | src/mbgl/gl/types.hpp | 4 |
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, |